88 * from an ~user directory to be able to make changes to the globalle running
99 * apache process, and for example make changes to catch data from other websites
1010 * running on the same host.
11- *
12- * However, people who are in a position to write C++ and deploy code however,
11+ *
12+ * However, people who are in a position to write C++ and deploy code however,
1313 * already _ARE_ in a position to do dangerous things. For them we do not want
1414 * these safety checks. In fact, we want to offer raw access, so that they can
1515 * open modules - no matter what. So we had to make our own copy of the dl()
1616 * function, and because we're here in C++ context, we do it a little nicer
1717 * than the original C++ code. This module class is a utility class used by
1818 * our own dl() implementation.
19- *
19+ *
2020 * @author Emiel Bruijntjes <[email protected] > 2121 * @copyright 2015 Copernica BV
2222 */
2525 * Set up namespace
2626 */
2727namespace Php {
28-
28+
2929/* *
3030 * Class definition
3131 */
@@ -37,13 +37,13 @@ class Module
3737 * @var void*
3838 */
3939 void *_handle;
40-
40+
4141 /* *
4242 * The module entry
4343 * @var zend_module_entry
4444 */
4545 zend_module_entry *_entry = nullptr ;
46-
46+
4747
4848 /* *
4949 * Internal helper class with persistent modules
@@ -56,32 +56,32 @@ class Module
5656 * @var std::set
5757 */
5858 std::set<void *> _handles;
59-
59+
6060 public:
6161 /* *
6262 * Constructor
6363 */
6464 Persistent () {}
65-
65+
6666 /* *
6767 * Destructor
6868 */
69- virtual ~Persistent ()
69+ virtual ~Persistent ()
7070 {
7171 // remove all handles
7272 while (!_handles.empty ())
7373 {
7474 // get first handle
7575 auto iter = _handles.begin ();
76-
76+
7777 // remove the handle
7878 DL_UNLOAD (*iter);
79-
79+
8080 // remove from set
8181 _handles.erase (iter);
8282 }
8383 }
84-
84+
8585 /* *
8686 * Check whether a handle is already persistently opened
8787 * @param handle
@@ -91,7 +91,7 @@ class Module
9191 {
9292 return _handles.find (handle) != _handles.end ();
9393 }
94-
94+
9595 /* *
9696 * Add a library persistently
9797 * @param module
@@ -112,39 +112,39 @@ class Module
112112public:
113113 /* *
114114 * Constructor
115- *
115+ *
116116 * A module can be loaded persistently. This means that the variables in
117117 * the module will keep in scope for as long as Apache runs, even though
118118 * the extension is not active in other page views
119- *
119+ *
120120 * @param module Name of the module
121121 * @param persistent Should it be loaded persistently
122122 */
123123 Module (const char *module , bool persistent)
124124 {
125125 // the path we're going to load
126126 ExtensionPath path (module );
127-
127+
128128 // load the module
129129 _handle = DL_LOAD (path);
130-
130+
131131 // handle should be valid
132132 if (!_handle) return ;
133-
133+
134134 // if we have to open it persistently, we open it for a second time so that
135135 // the refcounter always stays 1 or higher
136136 if (persistent && !_persistent.contains (_handle)) _persistent.add (module );
137-
137+
138138 // we have to call the get_module() function
139139 Symbol<zend_module_entry*()> get_module (_handle, " get_module" );
140-
140+
141141 // was the get_module() function found
142142 if (!get_module) return ;
143143
144144 // retrieve the module entry
145145 _entry = get_module ();
146146 }
147-
147+
148148 /* *
149149 * Destructor
150150 */
@@ -153,7 +153,7 @@ class Module
153153 // if the handle is still valid, we have to unload it
154154 if (_handle) DL_UNLOAD ((DL_HANDLE)_handle);
155155 }
156-
156+
157157 /* *
158158 * Check if the module is valid
159159 * @return bool
@@ -162,14 +162,14 @@ class Module
162162 {
163163 // module-entry must exist
164164 if (!_handle || !_entry) return false ;
165-
165+
166166 // check api compatibility
167167 if (_entry->zend_api != ZEND_MODULE_API_NO) return false ;
168-
168+
169169 // and other stuff
170170 return strcmp (_entry->build_id , ZEND_MODULE_BUILD_ID) == 0 ;
171171 }
172-
172+
173173 /* *
174174 * Start the module
175175 * @return bool
@@ -178,22 +178,26 @@ class Module
178178 {
179179 // this is not possible if the module is invalid in the first place
180180 if (!valid ()) return false ;
181-
181+
182182 // the Zend engine sets a number of properties in the entry class, we do that here too
183183 // note that it would be better to call zend_next_free_module() to find the next module
184184 // number, but some users complain that this function is not always available
185185 _entry->type = MODULE_TEMPORARY;
186186 _entry->module_number = zend_hash_num_elements (&module_registry) + 1 ;
187187 _entry->handle = _handle;
188-
188+
189189 // @todo does loading an extension even work in a multi-threading setup?
190-
190+
191191 // register the module, this apparently returns a copied entry pointer
192+ #if PHP_VERSION_ID < 80400
192193 auto *entry = zend_register_module_ex (_entry);
194+ #else
195+ auto *entry = zend_register_module_ex (_entry, MODULE_PERSISTENT);
196+ #endif
193197
194198 // forget the entry, so that a new call to start() will fail too
195199 _entry = nullptr ;
196-
200+
197201 // leap out on failure
198202 if (entry == NULL ) return false ;
199203
@@ -206,18 +210,18 @@ class Module
206210 // call the startup function
207211 if (entry->request_startup_func (MODULE_TEMPORARY, entry->module_number ) == FAILURE) return false ;
208212 }
209-
213+
210214 // all is ok, we can forget about the handle now, so that is won't get destructed
211215 _handle = nullptr ;
212216
213217 // enable full-table-cleanup, because inside the Zend-engine this is done too
214218 EG (full_tables_cleanup) = 1 ;
215-
219+
216220 // we're ready
217221 return true ;
218222 }
219223};
220-
224+
221225/* *
222226 * End of namespace
223227 */
0 commit comments