Press "Enter" to skip to content

Introducing the New Type Descriptors in the Zend Parameters Parser

Starting with PHP 5.3, the zend_parse_paramters_* functions added the following new type descriptors:

f  - function or array containing php method call info (returned as
      zend_fcall_info and zend_fcall_info_cache)
H  - array or HASH_OF(object) (returned as HashTable*)
L  - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (long)
Z  - the actual zval (zval**)
*  - variable arguments list (0 or more)
+  - variable arguments list (1 or more)

This also makes it much easier for us, when developing extensions, to handle input parameters and get the values we want.
For example, before there was 'f', if our extension provided a method that accepted a user-supplied callback function, we had to check the argument the user passed:

1. Is it a string or an array?
2. If it's a string, is it a callable callback function?
3. If it's an array, there are two cases: calling a class's static method, or calling an object's method.
   In both cases, verify that they are callable callback functions.

Pretty annoying, right? But with 'f', we can simply:

PHP_FUNCTION(dummy) {
    zval *retval_ptr = NULL;
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
            "f*", &fci, &fci_cache, &fci.params, &fci.param_count) == FAILURE) {
        return;
    }
    fci.retval_ptr_ptr = &retval_ptr;
    zend_call_function(&fci, &fci_cache TSRMLS_CC);
    .....
}

Isn't that a lot more convenient?
Also, the example above incidentally introduced "*", which is mainly used to make developing variadic functions easier. "+" is similar.
The last thing to talk about is "H".
First, we should mention some of PHP's historical reasons: PHP objects can actually also be used as arrays, and in that case their properties by default serve as the array's container.
This way, when a function in our extension declares that it wants to get an array, for the following object you can't call it directly:

$person = new StdClass();
$person->name = "Laruence";
$person->age   = 28;

But if, in the extension's function, we use "H" to declare that we want an array, then the object above can be used directly as a valid argument.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.