Skip to content

Commit c29a2e3

Browse files
TysonAndrejpauli
authored andcommitted
Consistently use fahrenheit to celsius (#25)
* Consistently use fahrenheit to celsius It was inconsistently described as celsius_to_fahrenheit some of the time. * Fix typos, remove trailing whitespace from lines
1 parent ee9ca08 commit c29a2e3

File tree

1 file changed

+49
-49
lines changed

1 file changed

+49
-49
lines changed

Book/php7/extensions_design/php_functions.rst

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
Registering and using PHP functions
22
===================================
33

4-
The main goal of a PHP extension is to register new PHP functions for userland. PHP functions are complex to fully
5-
understand their mechanics that hook very deep into the Zend Engine, but fortunately we don't need this knowledge
4+
The main goal of a PHP extension is to register new PHP functions for userland. PHP functions are complex to fully
5+
understand their mechanics that hook very deep into the Zend Engine, but fortunately we don't need this knowledge
66
for our chapter, as the PHP extension mechanism provides many ways to abstract a lot such a complexity.
77

8-
Registering and using new PHP functions in an extension is an easy step. Deeply understanding the big picture is
9-
however pretty more complex. A first step :doc:`to the zend_function chapter<../internal_types/functions>` could help
8+
Registering and using new PHP functions in an extension is an easy step. Deeply understanding the big picture is
9+
however pretty more complex. A first step :doc:`to the zend_function chapter<../internal_types/functions>` could help
1010
then.
1111

12-
Obviously, you'll need to master :doc:`types<../internal_types>`, especially :doc:`zvals<../internal_types/zvals>` and
12+
Obviously, you'll need to master :doc:`types<../internal_types>`, especially :doc:`zvals<../internal_types/zvals>` and
1313
:doc:`memory management<../memory_management>` here. Also, know your :doc:`hooks<../extensions_design/php_lifecycle>`.
1414

1515
zend_function_entry structure
1616
*****************************
1717

18-
Not to be confused with :doc:`the zend_function structure<../internal_types/functions>`, ``zend_function_entry`` is
18+
Not to be confused with :doc:`the zend_function structure<../internal_types/functions>`, ``zend_function_entry`` is
1919
used to register functions against the engine while in an extension.
2020
Here it is::
2121

@@ -44,7 +44,7 @@ return value is passed to our handler as a parameter.
4444
Arguments. The ``arg_info`` variable is about declaring the API arguments our function will accept. Here again,
4545
that part can be tricky to deeply understand, but we don't need to get too deep and we'll once more use macros to
4646
abstract and ease arguments declaration. What you should know is that you are not required to declare any arguments
47-
here for the function to work, but it is highly recommanded. We'll get back to that. Arguments are an array of
47+
here for the function to work, but it is highly recommanded. We'll get back to that. Arguments are an array of
4848
``arg_info``, and thus its size is passed as ``num_args``.
4949

5050
Then come ``flags``. We won't detail flags in this chapter. Those are used internally, you'll find some details in the
@@ -53,9 +53,9 @@ dedicated :doc:`zend_function<../internal_types/functions>` chapter.
5353
Registering PHP functions
5454
*************************
5555

56-
PHP functions are registered into the engine when the extension gets loaded. An extension may declare a function vector
57-
into the extension structure. Functions declared by extensions are called "internal" functions, and at the opposite of
58-
"user" functions (functions declared and used using PHP userland) they don't get unregistered at the end of the
56+
PHP functions are registered into the engine when the extension gets loaded. An extension may declare a function vector
57+
into the extension structure. Functions declared by extensions are called "internal" functions, and at the opposite of
58+
"user" functions (functions declared and used using PHP userland) they don't get unregistered at the end of the
5959
current request: they are permanent.
6060

6161
As a reminder, here is the PHP extension structure shorten for readability::
@@ -129,16 +129,16 @@ Here is the same code, but with the macros expanded, so that you can have a look
129129
(uint32_t) (sizeof(((void *)0))/sizeof(struct _zend_internal_arg_info)-1), 0 },
130130
}
131131

132-
Notice how ``PHP_FUNCTION()`` expanded to a C symbol beginning by ``zif_``. *'zif'* stands for
133-
*Zend Internal Function*, it is added to the name of your function to prevent symbol name collisions in the compilation
134-
of PHP and its modules. Thus, our ``fahrenheit_to_celsius()`` PHP function uses a C handler named
135-
``zif_fahrenheit_to_celsius()``. It is the same for nearly every PHP function. If you look for "zif_var_dump", you'll
132+
Notice how ``PHP_FUNCTION()`` expanded to a C symbol beginning by ``zif_``. *'zif'* stands for
133+
*Zend Internal Function*, it is added to the name of your function to prevent symbol name collisions in the compilation
134+
of PHP and its modules. Thus, our ``fahrenheit_to_celsius()`` PHP function uses a C handler named
135+
``zif_fahrenheit_to_celsius()``. It is the same for nearly every PHP function. If you look for "zif_var_dump", you'll
136136
read the PHP ``var_dump()`` source code function, etc...
137137

138138
Declaring function arguments
139139
****************************
140140

141-
So far so good, if :doc:`you compile<../build_system/building_extensions>` the extension and load it into PHP, you can
141+
So far so good, if :doc:`you compile<../build_system/building_extensions>` the extension and load it into PHP, you can
142142
see with reflection that the function is present::
143143

144144
> ~/php/bin/php -dextension=pib.so --re pib
@@ -149,10 +149,10 @@ see with reflection that the function is present::
149149
}
150150
}
151151

152-
But its arguments are missing. If we want to publish a ``fahrenheit_to_celsius($fahrenheit)`` function signature, we
152+
But its arguments are missing. If we want to publish a ``fahrenheit_to_celsius($fahrenheit)`` function signature, we
153153
need one mandatory argument.
154154

155-
What you must know is that argument declaration has nothing to do with the function internal work. That means that this
155+
What you must know is that argument declaration has nothing to do with the function internal work. That means that this
156156
function could have worked if we would have written its body now. Even with no declared arguments.
157157

158158
.. note:: Declaring arguments is not mandatory but highly recommanded. Arguments are used by the reflection API to get
@@ -207,7 +207,7 @@ This bunch of macros allow you to deal with every use-case.
207207
*'arginfo_[function name]'* pattern.
208208

209209
So back to our ``fahrenheit_to_celsius()`` function, we declare a simple return by value function (very classical
210-
use-case), with one argument called ``fahrenheit``, not passed by reference (here again, very traditionnal).
210+
use-case), with one argument called ``fahrenheit``, not passed by reference (here again, very traditional).
211211

212212
That created the ``arginfo_fahrenheit_to_celsius`` symbol of type ``zend_internal_arg_info[]`` (a vector, or an array,
213213
that is the same), and we must now use that back into our function declaration to attach it some args::
@@ -231,15 +231,15 @@ Ok. Here is a PHP function like you use it and declare it with the PHP language
231231
232232
function fahrenheit_to_celsius($fahrenheit)
233233
{
234-
return 9/5 * $fahrenheit + 32;
234+
return 5/9 * ($fahrenheit - 32);
235235
}
236236
237237
This is an easy function so that you understand things.
238238
Here is what it looks like when programmed in C::
239239

240-
PHP_FUNCTION(celsius_to_fahrenheit)
240+
PHP_FUNCTION(fahrenheit_to_celsius)
241241
{
242-
/* code to go here */
242+
/* code to go here */
243243
}
244244

245245
Macro expanded, that gives::
@@ -249,7 +249,7 @@ Macro expanded, that gives::
249249
/* code to go here */
250250
}
251251

252-
Take a break and think about the majors differences.
252+
Take a break and think about the major differences.
253253

254254
First strange thing, in C, the function is not expected to return anything. That's a ``void`` declared function, you
255255
can't here in C return something. But we notice we receive an argument called ``return_value`` of type ``zval *``,
@@ -289,18 +289,18 @@ float as an integer, and give it to you.
289289

290290
Let's see that function::
291291

292-
PHP_FUNCTION(celsius_to_fahrenheit)
292+
PHP_FUNCTION(fahrenheit_to_celsius)
293293
{
294-
double c;
294+
double f;
295295

296-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &c) == FAILURE) {
297-
return;
298-
}
296+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &f) == FAILURE) {
297+
return;
298+
}
299299

300-
/* continue */
300+
/* continue */
301301
}
302302

303-
We want to be given a double on the c variable. We then call ``zend_parse_parameters()``.
303+
We want to be given a double on the f variable. We then call ``zend_parse_parameters()``.
304304

305305
The first argument is the number of arguments the runtime have been given. ``ZEND_NUM_ARGS()`` is a macro that tells
306306
us, we then use it to tell zpp() how many arguments to read.
@@ -330,18 +330,18 @@ So far so good, we received a double. Let's now perform the math operations and
330330

331331
static double php_fahrenheit_to_celsius(double f)
332332
{
333-
return ((double)5/9) * (double)(f - 32);
333+
return ((double)5/9) * (double)(f - 32);
334334
}
335335

336336
PHP_FUNCTION(fahrenheit_to_celsius)
337337
{
338-
double f;
338+
double f;
339339

340-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &f) == FAILURE) {
341-
return;
342-
}
340+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &f) == FAILURE) {
341+
return;
342+
}
343343

344-
RETURN_DOUBLE(php_fahrenheit_to_celsius(f));
344+
RETURN_DOUBLE(php_fahrenheit_to_celsius(f));
345345
}
346346

347347
Returning values should be easy to you, as you know :doc:`how zvals work <../internal_types/zvals>`. You must fill-in
@@ -386,10 +386,10 @@ Let's add the opposite function: ``celsius_to_fahrenheit($celsius)``::
386386

387387
PHP_FUNCTION(celsius_to_fahrenheit)
388388
{
389-
double c;
389+
double c;
390390

391391
if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &c) == FAILURE) {
392-
return;
392+
return;
393393
}
394394

395395
RETURN_DOUBLE(php_celsius_to_fahrenheit(c));
@@ -427,7 +427,7 @@ Now a more complex use case, we show it in PHP before implementing it as a C ext
427427
That example helps us introduce **constants**.
428428

429429
Constants are easy to manage in extensions, like they are in their userland counter-part. Constants are persistent,
430-
most often, that means that they should persist their value accross requests. If you are aware of
430+
most often, that means that they should persist their value across requests. If you are aware of
431431
:doc:`the PHP lifecycle<./php_lifecycle>`, you should have guessed that ``MINIT()`` is the right stage to register
432432
constants against the engine.
433433

@@ -465,7 +465,7 @@ API and macros are located into
465465
zend_constants.h>`_.
466466

467467
The flags are mixed *OR* operation between ``CONST_CS`` (case-sensitive constant, what we want), and
468-
``CONST_PERSISTENT`` (a persistent constant, accross requests, what we want as well).
468+
``CONST_PERSISTENT`` (a persistent constant, across requests, what we want as well).
469469

470470
Now our ``temperature_converter($temp, $type = TEMP_CONVERTER_TO_CELSIUS)`` function in C::
471471

@@ -515,9 +515,9 @@ Remember to well look at `README.PARAMETER_PARSING_API <https://github.com/php/p
515515
ef4b2fc283ddaf9bd692015f1db6dad52171c3ce/README.PARAMETER_PARSING_API>`_. It's not a hard API, you must familiarize
516516
with it.
517517

518-
We use *"d|l"* as arguments to ``zend_parse_parameters()``. One double and optionnaly (the pipe *"|"*) one long. Take
519-
care, if the optionnal argument is not provided at runtime (what ``ZEND_NUM_ARGS()`` tells us about, as a reminder),
520-
then the ``&mode`` variable won't be touched by zpp(). That's why we provide a default value of
518+
We use *"d|l"* as arguments to ``zend_parse_parameters()``. One double and optionaly (the pipe *"|"*) one long. Take
519+
care, if the optional argument is not provided at runtime (what ``ZEND_NUM_ARGS()`` tells us about, as a reminder),
520+
then the ``&mode`` variable won't be touched by zpp(). That's why we provide a default value of
521521
``TEMP_CONVERTER_TO_CELSIUS`` to that variable.
522522

523523
Then we use ``strpprintf()`` to build a :doc:`zend_string <../internal_types/strings/zend_strings>`, and return it into
@@ -590,14 +590,14 @@ remember one reason why we sometimes use the C language over PHP.
590590
Managing references
591591
*******************
592592

593-
Now let's go to play with PHP references. You've learnt from :doc:`the zval chapter <../internal_types/zvals>` that
594-
references are a special trick used into the engine. As a reminder, a reference (by that we mean a ``&$php_reference``)
593+
Now let's go to play with PHP references. You've learnt from :doc:`the zval chapter <../internal_types/zvals>` that
594+
references are a special trick used into the engine. As a reminder, a reference (by that we mean a ``&$php_reference``)
595595
is a heap allocated ``zval`` stored into a ``zval`` container. Haha.
596596

597-
So, it is not very hard to deal with those into PHP functions, as soon as you remember what references are, and what
597+
So, it is not very hard to deal with those into PHP functions, as soon as you remember what references are, and what
598598
they're designed to.
599599

600-
If your function accept a parameter as a reference, you must declare that in arguments signature and be passed a
600+
If your function accept a parameter as a reference, you must declare that in arguments signature and be passed a
601601
reference from your ``zend_parse_parameter()`` call. Let's see that like always, with a PHP example first:
602602

603603
.. code-block::php
@@ -616,9 +616,9 @@ So now in C, first we must change our ``arg_info``::
616616
*1*, passed in the ``ZEND_ARG_INFO()`` macro tells the engine that argument must be passed by reference.
617617

618618
Then, when we receive the argument, we use the *"z"* argument type, to tell that we want to be given it as a ``zval *``.
619-
As we did hint the engine about the fact that it should pass us a reference, we'll be given a reference into that zval,
620-
aka it will be of type ``IS_REFERENCE``. We just need to dereference it (that is to fetch the zval stored into the
621-
zval), and modify it as-is, as the expected behavior of references is that you must modify the value carried by the
619+
As we did hint the engine about the fact that it should pass us a reference, we'll be given a reference into that zval,
620+
aka it will be of type ``IS_REFERENCE``. We just need to dereference it (that is to fetch the zval stored into the
621+
zval), and modify it as-is, as the expected behavior of references is that you must modify the value carried by the
622622
reference::
623623

624624
PHP_FUNCTION(fahrenheit_to_celsius)

0 commit comments

Comments
 (0)