How to traverse arrays in PHP 7 extensions recently I am looking at PHP 7 source code and learning how to develop PHP extensions based on this version. (there were not many development experiences in extensions in earlier versions, the new engine can improve the starting line). The following are just some notes.
Write the iterative callback function in two callback formats:
// Input int callback (zval * val) {zvaltmp; // add a temporary zval to avoid convert_to_string contamination of the original element ZVAL_COPY (& tmp, val); // Copy the val value, in PHP5, you need to use zval_copy_ctor and reset the reference count. now it seems that convert_to_string (& tmp) is not needed; // string type conversion // The purpose is very simple, just print out php_printf ("The value is: ["); PHPWRITE (Z_STRVAL (tmp), Z_STRLEN (tmp); php_printf ("]"); zval_dtor (& tmp ); // actively release the temporary zval; otherwise, the memory will leak. return ZEND_HASH_APPLY_KEEP;} // pass the key and value int callback_args (zval * val, int num_args, va_listargs, zend_hash_key * hash_key) {zvaltmp = * val; ZVAL_COPY (& tmp, val); convert_to_string (& tmp); // Print The key-value pair result php_printf ("The key is :["); if (hash_key-> key) {PHPWRITE (ZSTR_VAL (hash_key-> key), ZSTR_LEN (hash_key-> key);} else {php_printf ("% ld ", hash_key-> h);} php_printf ("], the value is: ["); PHPWRITE (Z_STRVAL (tmp), Z_STRLEN (tmp); php_printf ("]"); zval_dtor (& tmp); return ZEND_HASH_APPLY_KEEP ;}
Zval * val is the element value zval in the array, and hash_key is the element key. they are all pointers. The Structure of zend_hash_key is defined in zend_hash.h.
Typedef struct _ zend_hash_key {zend_ulong h; // number key zend_string * key; // string key} zend_hash_key;
The callback function returns three constant values:
Constant |
Description |
ZEND_HASH_APPLY_KEEP |
Returning this value will complete the current loop and continue iteration of the next value in HashTable, which is equivalent to executing continue in the foreach () control block; |
ZEND_HASH_APPLY_STOP |
Returning this value will interrupt iteration, equivalent to executing break in the foreach () control block; |
ZEND_HASH_APPLY_REMOVE |
Similar to ZEND_HASH_APPLY_KEEP, this return value will jump to the next iteration, but this return value will also cause the current element to be deleted from the original HashTable |
Suppose we have defined a PHP function foo:
PHP_FUNCTION (foo) {// Obtain arr zval * arr from the parameter; if (zend_parse_parameters (ZEND_NUM_ARGS (), "a", & arr) = FAILURE) {RETURN_NULL () ;}// the traversal value zend_hash_apply (ZARRVAL_P (arr), callback); // The traversal key and value pair (Z_ARRVAL_P (arr), callback_args, 0 );}
The Z_ARRVAL_P user returns the value. arr pointer in the zval structure.