I am working on a php extension to upgrade it to PHP7, my question is about INTERNAL_FUNCTION_PARAMETERS
. In the previous version it is defined as:
INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
and in the new zend engine it is defined as:
INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value
I have php function which returns an array and it looks like this: `
PHP_FUNCTION( myFunc ){ zval* myArray;
array_init(myArray);
/////
zval_ptr_dtor( &return_value );
*return_value_ptr = myArray;
}
How should I get similar functionalities without hanvig the return_value_ptr
?
Should I use #define RETURN_ARR(r)
?, If so how does this affect the performance?
In PHP 7, most pointers to zvals (zval*
) in PHP 5 have become plain zval structs (zval
) - instead of passing around pointers to heap-allocated (emalloc
) zvals, zvals themselves are copied. Because of this, in a sense, return_value
is the new return_value_ptr
, because there's one less level of indirection everywhere.
So, to go through line-by-line:
Line 1:
zval* myArray;
In PHP 7, you don't hold a pointer to a zval, you put it directly on the stack. No external allocation. So the first line of your function should be instead:
zval myArray;
Line 2:
array_init(myArray);
array_init
needs a pointer to a zval (zval*
), so this should be:
array_init(&myArray);
Line 4:
zval_ptr_dtor( &return_value );
Again, PHP 7 removes a level of indirection here. It would just be this now:
zval_dtor(return_value);
However, you don't need this line in PHP 7. The zval doesn't need deallocating (in fact you can't deallocate it), you can simply overwrite it. You would need to use zval_dtor();
if the zval contained a pointer to a string, array, or some other heap-allocated object, though. But in this case it's just a null, so you don't need to run it. Carrying on:
Line 5:
*return_value_ptr = myArray;
This should now be:
*return_value = myArray;
However, while you can directly overwrite return_value
here, it is recommended to use the ZVAL_COPY_VALUE
macro for this:
ZVAL_COPY_VALUE(return_value, &myArray);
Even better, you could use RETVAL_ZVAL
which is a shortcut for setting the return value:
RETVAL_ZVAL(&myArray);
I should point out that you probably don't need the myArray
zval in this case, as you can store the array in the return_value
directly and save you having to copy it later. Another thing to bear in mind is that you should probably handle parameters. If you don't take any, zend_parse_parameters_none();
is sufficient.
I suggest reading the phpng upgrading guide and the internals upgrading guide.