@@ -28,7 +28,7 @@ the default value the extension designer gives to the API.
28
28
is the one given by the extension developer, not the other way around.
29
29
30
30
The default value we are talking about here is called the **"master value" **. You may recall it from a ``phpinfo() ``
31
- output, right ?:
31
+ output, right ?
32
32
33
33
.. image :: ./images/php_extensions_ini.png
34
34
:align: center
@@ -68,23 +68,27 @@ Into the engine, an INI setting is represented by a ``zend_ini_entry`` structure
68
68
int module_number;
69
69
};
70
70
71
- Nothing really strong in such a structure. Setting's ``name `` and ``value `` are the most commonly used fields. Note
72
- however that the value is a string (as :doc: `zend_string <../internal_types/strings/zend_strings >`) and nothing else.
73
- Then, like we detailed in the introduction chapter above, we find the ``orig_value ``, ``orig_modified ``, ``modifiable ``
74
- and ``modified `` fields which are related to the modification of the setting's value. The setting must keep in memory
75
- its original value (as "master value"). ``modifiable `` tells if the setting is actually modifable, and must have one of
76
- the values you should be aware of from PHP userland : ``ZEND_INI_USER ``, ``ZEND_INI_PERDIR ``, ``ZEND_INI_SYSTEM `` or
77
- ``ZEND_INI_ALL ``. ``modified `` is set to one anytime the setting has been modified during a request so that the engine
78
- knows at request shutdown that it must restore that INI setting value to its master value for the next request to treat.
79
-
80
- Then come two handlers: ``on_modify() `` is called whenever the current setting's value is modified, like f.e using a call
81
- to ``ini_set() `` (but not only). We'll focus deeper on ``on_modify() `` later, but think of it as being a
82
- *validator function * (f.e if the setting is expected to represent an integer, you may validate the values you'll be
83
- given against integers). It also serve as a memory bridge to update global values, we'll get back on that later as well.
84
-
85
- ``diplayer() `` is less useful, and you usually don't pass any. ``displayer() `` is about how to display your setting.
86
- F.e, you may remember that PHP tends to display *On * for boolean values of *true */*yes */*on */*1 * etc. That's the
87
- ``displayer() `` job : turn the current value into a "displayed" value.
71
+ Nothing really strong in such a structure.
72
+
73
+ * Setting's ``name `` and ``value `` are the most commonly used fields. Note
74
+ however that the value is a string (as :doc: `zend_string *<../internal_types/strings/zend_strings> `) and nothing else.
75
+ * Then, like we detailed in the introduction chapter above, we find the ``orig_value ``, ``orig_modified ``, ``modifiable ``
76
+ and ``modified `` fields which are related to the modification of the setting's value. The setting must keep in memory
77
+ its original value (as "master value").
78
+ * ``modifiable `` tells if the setting is actually modifable, and must pick some
79
+ values from ``ZEND_INI_USER ``, ``ZEND_INI_PERDIR ``, ``ZEND_INI_SYSTEM `` or
80
+ ``ZEND_INI_ALL ``, those may be flagued together and are detailed `in the PHP manual
81
+ <http://php.net/configuration.changes.modes> `_.
82
+ * ``modified `` is set to one anytime the setting has been modified during a request so that the engine knows at request
83
+ shutdown that it must restore that INI setting value to its master value for the next request to treat.
84
+ * ``on_modify() `` is a handler called whenever the current setting's value is modified, like f.e using a call
85
+ to ``ini_set() `` (but not only). We'll focus deeper on ``on_modify() `` later, but think of it as being a
86
+ *validator function * (f.e if the setting is expected to represent an integer, you may validate the values you'll be
87
+ given against integers). It also serve as a memory bridge to update global values, we'll get back on that later as
88
+ well.
89
+ * ``diplayer() `` is less useful, and you usually don't pass any. ``displayer() `` is about how to display your setting.
90
+ F.e, you may remember that PHP tends to display *On * for boolean values of *true */*yes */*on */*1 * etc. That's the
91
+ ``displayer() `` job : turn the current value into a "displayed" value.
88
92
89
93
You will also need to deal with this structure ``zend_ini_entry_def ``::
90
94
@@ -109,7 +113,10 @@ an INI setting against the engine. The engine reads a ``zend_ini_entry_def``, an
109
113
Registering and using INI entries
110
114
---------------------------------
111
115
112
- INI settings are persistent through requests. They can change their value during a request (runtime), but they'll go back
116
+ Registration
117
+ ************
118
+
119
+ INI settings are persistent through requests. They may change their value at runtime during a request, but they'll go back
113
120
to original value at request shutdown. Thus, registering INI settings is done once for all, in ``MINIT() `` hook of your
114
121
extension.
115
122
@@ -132,6 +139,13 @@ for previous chapter about random number picking and guessing, once again only s
132
139
{
133
140
DISPLAY_INI_ENTRIES();
134
141
}
142
+
143
+ PHP_MSHUTDOWN_FUNCTION(pib)
144
+ {
145
+ UNREGISTER_INI_ENTRIES();
146
+
147
+ return SUCCESS;
148
+ }
135
149
136
150
That was the easiest INI declaration, we won't keep it as-is but the steps are trivial : you declare a
137
151
``zend_ini_entry_def[] `` vector using ``PHP_INI_BEGIN `` and ``PHP_INI_END `` macros. In the middle, you add your
@@ -140,17 +154,24 @@ takes only four parameters : the name of the entry to register, its default valu
140
154
file scanning (see above chapter for details), the modification level, ``PHP_INI_ALL `` says "everywhere". We did not
141
155
play with validator yet, and passed NULL.
142
156
143
- Now, the new * "pib.rnd_max" * INI setting is declared - as * PHP_INI_ALL * - that means that the user may play with its
144
- value using `` ini_set() `` and `` ini_get() `` mainly .
157
+ In `` MINIT `` hook , we use the `` REGISTER_INI_ENTRIES `` macro which does its describing job whereas its counter-part
158
+ `` UNREGISTER_INI_ENTRIES `` is used at module shutdown to free the allocated resources .
145
159
146
- We did not forget to display that INI setting as part of our extension informations, using ``DISPLAY_INI_ENTRIES() ``.
160
+ Now, the new *"pib.rnd_max" * INI setting is declared - as ``PHP_INI_ALL `` - that means that the user may modify its
161
+ value using ``ini_set() `` (and read it back with ``ini_get() ``).
162
+
163
+ We did not forget to display those INI settings as part of our extension informations, using ``DISPLAY_INI_ENTRIES() ``.
147
164
Forgetting this in the declaration of the ``MINFO() `` hook will lead to our INI settings being hidden from the user in
148
165
the information page (``phpinfo() ``). Have a look at the :doc: `extension informations chapter <extension_infos >` if
149
166
you need.
150
167
151
- On your part as extension developper, we may now need to read that value ourselves. The simplest way to do this is to
152
- use macros that will look for the value into the main array retaining all the INI settings, find it, and return it as
153
- the type we'll ask for. We are provided several macros depending on what C type we want to be given back.
168
+ Usage
169
+ *****
170
+
171
+ On your part as extension developper, we may now need to read INI settings values by yourself. The simplest way to do
172
+ this into your extension is to use macros that will look for the value into the main array retaining all the INI
173
+ settings, find it, and return it as the type you'll ask for. We are provided several macros depending on what C type
174
+ we want to be given back.
154
175
155
176
``INI_INT(val) ``, ``INI_FLT(val) ``, ``INI_STR(val) ``, ``INI_BOOL(val) `` all four macros will look for the provided
156
177
value from the INI settings array and return it (if found) with a cast to the type you ask.
@@ -180,15 +201,15 @@ previous above lines is far from being optimal.
180
201
There are two problems that will get solved at the same time by using the 'advanced' INI settings API :
181
202
182
203
* Everytime we want to read our value, a lookup into the main INI settings table is needed, as well as a cast to the
183
- right type, often.
204
+ right type ( often). Those operations cost some CPU cycles .
184
205
* We did not provide any validator, thus the user could alter our setting and put anything he wants to as a value.
185
206
186
- Welcome globals update memory bridge.
207
+ The solution is to use an `` on_modify() `` validator and a memory bridge to update a global variable .
187
208
188
209
By using the advanced INI settings management API, we can tell the engine to register our settings just normally, but
189
210
we can also instruct it to update a global of our taste everytime the INI setting value is changed. Hence, whenever we
190
211
will want to read back our value, we'll just need to read our global. This will provide a boost in performance in the
191
- case we need to read the INI setting value often, as a hashtable lookup won't be needed anymore.
212
+ case we need to read the INI setting value often, as a hashtable lookup and a cast operation won't be needed anymore.
192
213
193
214
.. note :: You will need to feel comfortable with globals to continue reading the chapter. Global space management is
194
215
treated :doc: `into its own chapter <globals_management >`.
@@ -227,25 +248,25 @@ declares a ``pib_globals`` symbol of such a type.
227
248
``max_rnd `` member into the ``zend_pib_globals `` structure, to be able to update that part of memory whenever the
228
249
*'pib.rnd_max' * will get changed.
229
250
230
- The validator used here, ``onUpdateLongGEZero() ``, is a default validator that exists in PHP and validates the value
231
- against a long greater than or equal to zero. The validator is needed for the global to be updated, as such a job is
232
- done into the validator.
251
+ The `` on_modify() `` validator used here, ``onUpdateLongGEZero() ``, is a default validator that exists in PHP and
252
+ validates the value against a long greater than or equal to zero. The validator is needed for the global to be updated,
253
+ as such a job is done into the validator.
233
254
234
255
Now, to read back our INI setting value, we just need to read the value of our ``max_rnd `` global::
235
256
236
257
php_printf("The value is : %lu", PIB_G(max_rnd));
237
258
238
259
And we are done.
239
260
240
- Let's go to see the validator now. The validator has two goals :
261
+ Let's go to see the validator now (`` on_modify() `` handler) . The validator has two goals :
241
262
242
263
* Validate the passed value
243
264
* Update the global if the validation succeeds
244
265
245
- The validator is only called when the INI setting is set or modified, whenever this step happens.
266
+ The validator is only called when the INI setting is set or modified (written to) , whenever this step happens.
246
267
247
- .. warning :: If you want the global to be updated with the INI setting value, you'll need a validator. Such a mechanism
248
- is not magicaly performed by the engine, but must be done explicitly into the validator
268
+ .. warning :: If you want the global variable to be updated with the INI setting value, you'll need a validator. Such a
269
+ mechanism is not magicaly performed by the engine, but must be done explicitly into the validator.
249
270
250
271
Let's see the ``onUpdateLongGEZero() `` source code::
251
272
@@ -276,8 +297,8 @@ Let's see the ``onUpdateLongGEZero()`` source code::
276
297
277
298
Like you can see, there is nothing complex. Your validator is given the ``new_value `` and must validate against it.
278
299
Remember that ``new_value `` is of type :doc: `zend_string * <../internal_types/strings/zend_strings >`. The
279
- ``onUpdateLongGEZero() `` takes the value as a long and checks it is >=0 . One must return SUCCESS from the validator if
280
- OK and FAILURE if not.
300
+ ``onUpdateLongGEZero() `` takes the value as a long and checks if it is a positive integer . One must return `` SUCCESS ``
301
+ from the validator if everything went right and `` FAILURE `` if not.
281
302
282
303
Then comes the part to update the global. ``mh_arg `` variables are used to carry any type of information to your
283
304
validator.
@@ -290,7 +311,7 @@ is accessed differently if you are using ZTS mode or not. More informations abou
290
311
:doc: `can be found here <globals_management >`.
291
312
292
313
``mh_arg1 `` is passed the computed offset of your global member (``max_rnd `` for us), and you must slice the memory
293
- yourself to get a pointer to it. Taht 's why we stored ``mh_arg2 `` as a generic ``char * `` pointer and casted
314
+ yourself to get a pointer to it. That 's why we stored ``mh_arg2 `` as a generic ``char * `` pointer and casted
294
315
``mh_arg1 `` to ``size_t ``.
295
316
296
317
Then, you simply update the content with the validated value by writing into the pointer. ``mh_arg3 `` is unused actually.
@@ -332,19 +353,19 @@ for example::
332
353
STD_PHP_INI_ENTRY("pib.rnd_max", "100", PHP_INI_ALL, onUpdateMaxRnd, max_rnd, zend_pib_globals, pib_globals)
333
354
PHP_INI_END()
334
355
335
- .. note :: It is safe to write to an unsigned long from a long, as soon as the ranges are checked, which the validator
356
+ .. note :: It is safe to write to an * unsigned long* from a * long* , as soon as the ranges are checked, which the validator
336
357
does.
337
358
338
359
Now, if the user wants to modify the setting and pass a wrong value that does not validate, ``ini_set() `` simply will
339
- return FALSE to the userland, and will not modify the value:
360
+ return false to the userland, and will not modify the value:
340
361
341
362
.. code-block :: php
342
363
343
- ini_set('pib.rnd_max', 2048);
364
+ ini_set('pib.rnd_max', 2048); /* returns false as 2048 is > 1000 */
344
365
345
- In the opposite case, ``ini_set() `` returns the old value and modifies the value. The new provided value becomes the
346
- current "local" value whereas the default preceding value stays as the "master value". ``phpinfo() `` or `` ini_get_all() ``
347
- detail such values. Example:
366
+ In the opposite case, ``ini_set() `` returns the old value and modifies current the value. The new provided value becomes
367
+ the current "local" value whereas the default preceding value stays as the "master value". ``phpinfo() `` or
368
+ `` ini_get_all() `` detail such values. Example:
348
369
349
370
.. code-block :: php
350
371
@@ -376,17 +397,18 @@ For example, for our tiny example, the validator we designed is called three tim
376
397
377
398
Keep also in mind that the value accessor is checked against by ``ini_set() ``. If we would have designed a
378
399
``PHP_INI_SYSTEM `` setting, then the user would not have been able to modify it using ``ini_set() ``, as ``ini_set() ``
379
- uses ``PHP_INI_USER `` as accessor. The mismatch would then have benn detected soon and the validator would not have
380
- been called.
400
+ uses ``PHP_INI_USER `` as accessor. The mismatch would then have been detected and the validator would not have
401
+ been called by the engine in such a case .
381
402
382
403
If you need to change the INI setting value into your extension at runtime, the internal call is
383
404
``zend_alter_ini_entry() ``, this is what userland ``ini_set() `` uses.
384
405
385
406
Using a displayer
386
407
-----------------
387
408
388
- The last thing you need to know about INI settings is the ``displayer() `` callback. That one is triggered any time the
389
- userland asks to "see" your INI setting value, that is through the usage of ``phpinfo() `` or ``php --ri ``.
409
+ The last thing you need to know about INI settings is the ``displayer() `` callback. It is less used in practice, it is
410
+ triggered any time the userland asks to "print" your INI setting value, that is through the usage of
411
+ ``phpinfo() `` or ``php --ri ``.
390
412
391
413
If you provide no displayer, a default one will be used. See it::
392
414
@@ -395,7 +417,7 @@ If you provide no displayer, a default one will be used. See it::
395
417
Directive => Local Value => Master Value
396
418
pib.rnd_max => 120 => 120
397
419
398
- The default displayer takes the INI setting value (which, as a reminder, is of type ``zend_string \ * ``), and simply
420
+ The default displayer takes the INI setting value (which, as a reminder, is of type ``zend_string * ``), and simply
399
421
displays it. If no value were found or the value were the empty string, then it displays the string "no value".
400
422
401
423
To take hand on such a process, we must declare a ``displayer() `` callback that will be called. Let's try to represent
0 commit comments