Skip to content

Commit bda2aff

Browse files
author
Julien Pauli
committed
end of php_functions chapter for now
1 parent 192ff17 commit bda2aff

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

Book/php7/extensions_design/php_functions.rst

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ declaration can solve, that will be done in a second.
476476

477477
Then we add our new function to the function registration vector::
478478

479-
static const zend_function_entry myext_functions[] =
479+
static const zend_function_entry pib_functions[] =
480480
{
481481
PHP_FE(fahrenheit_to_celsius,arginfo_fahrenheit_to_celsius) /* seen above */
482482
PHP_FE(celsius_to_fahrenheit,arginfo_celsius_to_fahrenheit) /* seen above */
@@ -522,3 +522,61 @@ the ``return_value`` zval using ``RETURN_STR()``.
522522

523523
.. note:: ``strpprintf()`` and its sisters are explained in
524524
:doc:`the chapter about printing functions <../internal_types/strings/printing_functions>`.
525+
526+
Let's go now for a play with *PHP arrays* and design:
527+
528+
.. code-block:: php
529+
530+
function multiple_fahrenheit_to_celsius(array $temperatures)
531+
{
532+
foreach ($temperatures as $temp) {
533+
$return[] = fahreinheit_to_celsius($temp);
534+
}
535+
536+
return $return;
537+
}
538+
539+
So thinking at the C implementation, we need to ``zend_parse_parameters()`` and ask for just one array, iterate over it,
540+
make the maths operations and add the result in ``return_value``, as an array::
541+
542+
ZEND_BEGIN_ARG_INFO_EX(arginfo_multiple_fahrenheit_to_celsius, 0, 0, 1)
543+
ZEND_ARG_ARRAY_INFO(0, temperatures, 0)
544+
ZEND_END_ARG_INFO();
545+
546+
static const zend_function_entry pib_functions[] =
547+
{
548+
/* ... */
549+
PHP_FE(multiple_fahrenheit_to_celsius, arginfo_multiple_fahrenheit_to_celsius)
550+
PHP_FE_END
551+
};
552+
553+
PHP_FUNCTION(multiple_fahrenheit_to_celsius)
554+
{
555+
HashTable *temperatures;
556+
zval *data;
557+
558+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &temperatures) == FAILURE) {
559+
return;
560+
}
561+
if (zend_hash_num_elements(temperatures) == 0) {
562+
return;
563+
}
564+
565+
array_init_size(return_value, zend_hash_num_elements(temperatures));
566+
567+
ZEND_HASH_FOREACH_VAL(temperatures, data)
568+
zval dup;
569+
ZVAL_COPY_VALUE(&dup, data);
570+
convert_to_double(&dup);
571+
add_next_index_double(return_value, php_fahrenheit_to_celsius(Z_DVAL(dup)));
572+
ZEND_HASH_FOREACH_END();
573+
}
574+
575+
576+
.. note:: You need to know :doc:`how Hashtables work<../internal_types/hashtables>`, and the must-read
577+
:doc:`zval chapter<../internal_types/zvals>`
578+
579+
Here, the C part will be faster, as you don't call a PHP function in the loop for the C code, but a static (and probably
580+
inlined by the compiler) C function, which is orders of magnitude faster and requires tons less of low-level CPU
581+
instructions to run. It's not about that little demo function needs so much love in code performance, it's just to
582+
remember one reason why we sometimes use the C language over PHP.

0 commit comments

Comments
 (0)