@@ -366,10 +366,10 @@ If you have read :doc:`the chapter about tests <../tests>`, you should now write
366
366
367
367
\. .. and launch ``make test ``
368
368
369
- Advanced example
370
- ****************
369
+ Playing with constants
370
+ **********************
371
371
372
- Let's go in some advance examples .
372
+ Let's go with an advanced example .
373
373
Let's add the opposite function: ``celsius_to_fahrenheit($celsius) ``::
374
374
375
375
ZEND_BEGIN_ARG_INFO_EX(arginfo_celsius_to_fahrenheit, 0, 0, 1)
@@ -378,25 +378,25 @@ Let's add the opposite function: ``celsius_to_fahrenheit($celsius)``::
378
378
379
379
static double php_celsius_to_fahrenheit(double c)
380
380
{
381
- return (((double)9/5) * c) + 32 ;
381
+ return (((double)9/5) * c) + 32 ;
382
382
}
383
383
384
384
PHP_FUNCTION(celsius_to_fahrenheit)
385
385
{
386
- double c;
386
+ double c;
387
387
388
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &c) == FAILURE) {
389
- return;
390
- }
388
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &c) == FAILURE) {
389
+ return;
390
+ }
391
391
392
- RETURN_DOUBLE(php_celsius_to_fahrenheit(c));
392
+ RETURN_DOUBLE(php_celsius_to_fahrenheit(c));
393
393
}
394
394
395
395
static const zend_function_entry pib_functions[] =
396
396
{
397
- PHP_FE(fahrenheit_to_celsius, arginfo_fahrenheit_to_celsius) /* Done above */
398
- PHP_FE(celsius_to_fahrenheit,arginfo_celsius_to_fahrenheit) /* just added */
399
- PHP_FE_END
397
+ PHP_FE(fahrenheit_to_celsius, arginfo_fahrenheit_to_celsius) /* Done above */
398
+ PHP_FE(celsius_to_fahrenheit,arginfo_celsius_to_fahrenheit) /* just added */
399
+ PHP_FE_END
400
400
};
401
401
402
402
Now a more complex use case, we show it in PHP before implementing it as a C extension:
@@ -431,10 +431,10 @@ constants against the engine.
431
431
Here is a constant, internally, a ``zend_constant `` structure::
432
432
433
433
typedef struct _zend_constant {
434
- zval value;
435
- zend_string *name;
436
- int flags;
437
- int module_number;
434
+ zval value;
435
+ zend_string *name;
436
+ int flags;
437
+ int module_number;
438
438
} zend_constant;
439
439
440
440
Really an easy structure (that could become a nightmare if you deeply look at how constants are managed into the
@@ -448,10 +448,10 @@ To register constants, here again there is no difficulty at all, a bunch of macr
448
448
449
449
PHP_MINIT_FUNCTION(pib)
450
450
{
451
- REGISTER_LONG_CONSTANT("TEMP_CONVERTER_TO_CELSIUS", TEMP_CONVERTER_TO_CELSIUS, CONST_CS|CONST_PERSISTENT);
452
- REGISTER_LONG_CONSTANT("TEMP_CONVERTER_TO_FAHRENHEIT", TEMP_CONVERTER_TO_FAHRENHEIT, CONST_CS|CONST_PERSISTENT);
451
+ REGISTER_LONG_CONSTANT("TEMP_CONVERTER_TO_CELSIUS", TEMP_CONVERTER_TO_CELSIUS, CONST_CS|CONST_PERSISTENT);
452
+ REGISTER_LONG_CONSTANT("TEMP_CONVERTER_TO_FAHRENHEIT", TEMP_CONVERTER_TO_FAHRENHEIT, CONST_CS|CONST_PERSISTENT);
453
453
454
- return SUCCESS;
454
+ return SUCCESS;
455
455
}
456
456
457
457
.. note :: It is a good practice to give PHP constants values of C macros. That ease things, and that's what we did.
@@ -478,34 +478,34 @@ Then we add our new function to the function registration vector::
478
478
479
479
static const zend_function_entry pib_functions[] =
480
480
{
481
- PHP_FE(fahrenheit_to_celsius,arginfo_fahrenheit_to_celsius) /* seen above */
482
- PHP_FE(celsius_to_fahrenheit,arginfo_celsius_to_fahrenheit) /* seen above */
483
- PHP_FE(temperature_converter, arginfo_temperature_converter) /* our new function */
481
+ PHP_FE(fahrenheit_to_celsius,arginfo_fahrenheit_to_celsius) /* seen above */
482
+ PHP_FE(celsius_to_fahrenheit,arginfo_celsius_to_fahrenheit) /* seen above */
483
+ PHP_FE(temperature_converter, arginfo_temperature_converter) /* our new function */
484
484
}
485
485
486
486
And, the function body::
487
487
488
488
PHP_FUNCTION(temperature_converter)
489
489
{
490
- double t;
491
- zend_long mode = TEMP_CONVERTER_TO_CELSIUS;
492
- zend_string *result;
490
+ double t;
491
+ zend_long mode = TEMP_CONVERTER_TO_CELSIUS;
492
+ zend_string *result;
493
493
494
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "d|l", &t, &mode) == FAILURE) {
495
- return;
496
- }
494
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "d|l", &t, &mode) == FAILURE) {
495
+ return;
496
+ }
497
497
498
- switch (mode)
499
- {
500
- case TEMP_CONVERTER_TO_CELSIUS:
501
- result = strpprintf(0, "%.2f degrees fahrenheit gives %.2f degrees celsius", t, php_fahrenheit_to_celsius(t));
502
- RETURN_STR(result);
503
- case TEMP_CONVERTER_TO_FAHRENHEIT:
504
- result = strpprintf(0, "%.2f degrees celsius gives %.2f degrees fahrenheit", t, php_celsius_to_fahrenheit(t));
505
- RETURN_STR(result);
506
- default:
507
- php_error(E_WARNING, "Invalid mode provided, accepted values are 1 or 2");
508
- }
498
+ switch (mode)
499
+ {
500
+ case TEMP_CONVERTER_TO_CELSIUS:
501
+ result = strpprintf(0, "%.2f degrees fahrenheit gives %.2f degrees celsius", t, php_fahrenheit_to_celsius(t));
502
+ RETURN_STR(result);
503
+ case TEMP_CONVERTER_TO_FAHRENHEIT:
504
+ result = strpprintf(0, "%.2f degrees celsius gives %.2f degrees fahrenheit", t, php_celsius_to_fahrenheit(t));
505
+ RETURN_STR(result);
506
+ default:
507
+ php_error(E_WARNING, "Invalid mode provided, accepted values are 1 or 2");
508
+ }
509
509
}
510
510
511
511
Remember to well look at `README.PARAMETER_PARSING_API <https://github.com/php/php-src/blob/
@@ -523,6 +523,9 @@ the ``return_value`` zval using ``RETURN_STR()``.
523
523
.. note :: ``strpprintf()`` and its sisters are explained in
524
524
:doc: `the chapter about printing functions <../internal_types/strings/printing_functions >`.
525
525
526
+ A go with Hashtables (PHP arrays)
527
+ *********************************
528
+
526
529
Let's go now for a play with *PHP arrays * and design:
527
530
528
531
.. code-block :: php
@@ -546,30 +549,30 @@ make the maths operations and add the result in ``return_value``, as an array::
546
549
static const zend_function_entry pib_functions[] =
547
550
{
548
551
/* ... */
549
- PHP_FE(multiple_fahrenheit_to_celsius, arginfo_multiple_fahrenheit_to_celsius)
550
- PHP_FE_END
552
+ PHP_FE(multiple_fahrenheit_to_celsius, arginfo_multiple_fahrenheit_to_celsius)
553
+ PHP_FE_END
551
554
};
552
555
553
556
PHP_FUNCTION(multiple_fahrenheit_to_celsius)
554
557
{
555
- HashTable *temperatures;
556
- zval *data;
558
+ HashTable *temperatures;
559
+ zval *data;
557
560
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
- }
561
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &temperatures) == FAILURE) {
562
+ return;
563
+ }
564
+ if (zend_hash_num_elements(temperatures) == 0) {
565
+ return;
566
+ }
564
567
565
- array_init_size(return_value, zend_hash_num_elements(temperatures));
568
+ array_init_size(return_value, zend_hash_num_elements(temperatures));
566
569
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();
570
+ ZEND_HASH_FOREACH_VAL(temperatures, data)
571
+ zval dup;
572
+ ZVAL_COPY_VALUE(&dup, data);
573
+ convert_to_double(&dup);
574
+ add_next_index_double(return_value, php_fahrenheit_to_celsius(Z_DVAL(dup)));
575
+ ZEND_HASH_FOREACH_END();
573
576
}
574
577
575
578
0 commit comments