21.2 Modifying Function Arguments


You want to modify arguments that your user passes to you.

Technique

A function that does this is fsockopen() . Declare the function in the function entry table so as to force its arguments to be passed by reference.

The function table entry:

 unsigned char first_arg_force_ref[] = {BYREF_FORCE, BYREF_NONE}; PHP_FE(ref_args, first_arg_force_ref) 

The function itself:

 PHP_FUNCTION(ref_args) {     /* arg1 is a number and arg2 is a string */     zval **arg1, **arg2;     if (ZEND_NUM_ARGS() != 2          zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {         WRONG_PARAM_COUNT;     }     zval_copy_ctor(*arg1); /* For strings only */     ZVAL_STRING(*arg1, empty_string, 0);     RETURN_TRUE; } 

Comments

In this code, we fetch the parameters as we would any normal set of parameters. The parameters will automatically be passed by reference because of the function table entry specifying that. If you refer back to recipe 21.1, you will see that the zval struct has an entry for is_ref , which is whether the argument is passed by reference. You can check whether a certain zval is a reference like this:

 if (!(*arg1)->is_ref) {     /* ... */ } 

We then use the zval_copy_ctor() function, which creates a new variable with the same value of the old one. We then empty the value of arg2 , and by doing so, affect the value passed to the function from the PHP script.

If you want to add values to an array passed to you, you should do something like the following (of course, the same concept applies in reference to the function table entry):

The function table entry:

 PHP_FE(fill_array, first_arg_force_ref) 

The function itself:

 PHP_FUNCTION(fill_array) {     zval **ar, *tmp;     int i;     if (ZEND_NUM_ARGS() != 1          zend_get_parameters_ex(1, &ar) == FAILURE) {         WRONG_PARAM_COUNT;     }     convert_to_array_ex(ar);     for (i=0; i < 200; i++) {         MAKE_STD_ZVAL(tmp);         ZVAL_LONG(tmp, i);         zend_hash_index_update(Z_ARRVAL_PP(ar), i, &tmp, sizeof(zval *), NULL);     } } 

MAKE_STD_ZVAL() allocates a new zval, initializes it to have a reference count of 1 , and sets is_ref to .



PHP Developer's Cookbook
PHP Developers Cookbook (2nd Edition)
ISBN: 0672323257
EAN: 2147483647
Year: 2000
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net