21.1 Getting Arguments


You want to get arguments passed by the user to your custom function.

Technique

Declare zval variables that correspond to the passed arguments, and then put the value of the arguments into these variables by using the zend_get_parameters_ex() function. After this is done, you need only convert the variables to their various types and access the values:

 PHP_FUNCTION(sample_function) {     char *ret = NULL,          *fmtstr;     zval **arg1, **arg2, **arg3;     if (ZEND_NUM_ARGS() != 3          zend_get_parameters_ex (3, &arg1, &arg2, &arg3) == FAILURE) {         WRONG_PARAM_COUNT;     }     /* arg1 is an int */     convert_to_long_ex (arg1);     /* arg2 is a double */     convert_to_double_ex (arg2);     /* arg3 is a string */     convert_to_string_ex (arg3);     fmtstr = "arg1 is %d, arg2 is %f and arg3 is %s, arg3 has a length of %d";     /* Not the best allocation for the integer values      * but sufficient for the needs of this simple program.      */     ret = emalloc(strlen(fmtstr) + 10 + 20 + Z_STRLEN_PP(arg3));     sprintf(ret, fmtstr, Z_LVAL_PP(arg1), Z_DVAL_PP(arg2),             Z_STRVAL_PP(arg3), Z_STRLEN_PP(arg3));     RETURN_STRING(ret, 0); } 

Comments

The preceding is an example of a sample function that can be called from PHP with the following line. (There must first be a little more work done to register it as a function; see recipe 21.2 for more information on how to do that.)

 echo sample_function(23, 23.34003, "Hello World"); 

This would return:

 arg1 is 23, arg2 is 23.34003 and arg3 is Hello World, arg3 has a length of 11 

Here is a line-by-line explanation:

Line 1 ” Declare this as a PHP_FUNCTION() .

Line 4 ” Declare arg1 , arg2 , and arg3 as zval variables. A zval looks like this:

 typedef _zval_struct zval; /* Notice that this is a union, meaning only    one of the entries exists at a single time. */ typedef union _zvalue_value {     long lval; /* the long value */     double dval; /* The double value */     struct {         char *val; /* The value of the string */         int len; /* The length of the string */     } str;     char chval;     HashTable *ht; /* If it is an array */     struct {         zend_class_entry *ce;         HashTable *properties;     } obj; /* Object properties */ } zvalue_value; /* The actual zval struct itself, aliased by the typedef above */ struct _zval_struct {     zvalue_value value; /* Value of the argument */     zend_uchar type; /* Type of the argument */     zend_uchar is_ref; /* Whether or not the argument is a reference */     zend_ushort refcount; /* The reference count on the argument */ }; 

Line 5 ” Make sure that exactly three arguments are passed to our function. ZEND_NUM_ARGS() returns the number of arguments passed to the function.

Line 6 ” Use the zend_get_parameters_ex() function to fetch the value of the arguments into the variables set declared as zvals.

Line 7 ” If this fails, report to the user that there is an incorrect parameter count.

Line 11 ” Convert arg1 to a long.

Line 13 ” Convert arg2 to a double.

Line 15 ” Convert arg3 to a string.

Line 18 ” Build the format string.

Line 19 ” Allocate the return value.

Line 20 ” Build the return value

Line 21 ” Return the return value.

If you browse the source code of PHP, in many places you might see

 pval **argument; 

instead of

 zval **argument; 

This is because in PHP 3, all arguments were pval s instead of zval s. Therefore, to make it easier to port PHP 3 code (the C code, mind you) to PHP 4, zval s and pval s are made the same thing by a simple typedef .

On an unrelated note, if you want to fetch a variable number of arguments, you can do the following:

 PHP_FUNCTION(somefunc) {     zval **arg1, **arg2;     int argcount = ZEND_NUM_ARGS();     if (argcount > 2  argcount < 0          zend_get_parameters_ex(argcount, &arg1, &arg2) == FAILURE) {         WRONG_PARAM_COUNT;     }     if (argcount > 0) {         convert_to_long_ex(arg1);         /* php_printf prints out to STDOUT */         php_printf("%d\n", Z_LVAL_PP(arg1));     }     if (argcount > 1) {         convert_to_string_ex(arg2);         php_printf("%s\n", Z_STRVAL_PP(arg2));     }     php_printf("Above are %d printed out arguments", argcount); } 

Because zend_get_parameters_ex() fetches only the number of arguments specified by the first argument, it fetches only the variables you want. After you have fetched a variable, remember to check whether that variable as been passed to the function before performing operations on it (this was done by the if (argcount > x) code).



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