Hi, the attached patch enables extract() to take user defined callback function to process the extracted variable names. It also fixes a minor WS problem I introduced before.
Example: <?php $array = array('a' => 'huhu', 'b' => 'haha'); function extract_func($s, $p, $b) { return (( $b ) ? $p:"my__").$s; } extract($array); extract($array,EXTR_USER_FUNC,'extract_func',array("pref",true)); var_dump($a); var_dump($b); var_dump($my__a); var_dump($my__b); var_dump($prefa); var_dump($prefb); ?> I like the patch to be reviewd before I commit it, thank you. Jan -- Q: Thank Jan? A: http://geschenke.an.dasmoped.net/
Index: ext/standard/array.c =================================================================== RCS file: /repository/php4/ext/standard/array.c,v retrieving revision 1.167 diff -u -r1.167 array.c --- ext/standard/array.c 18 Jun 2002 13:16:33 -0000 1.167 +++ ext/standard/array.c 30 Jun 2002 16:02:41 -0000 @@ -55,23 +55,24 @@ #define EXTR_OVERWRITE 0 #define EXTR_SKIP 1 #define EXTR_PREFIX_SAME 2 -#define EXTR_PREFIX_ALL 3 -#define EXTR_PREFIX_INVALID 4 -#define EXTR_PREFIX_IF_EXISTS 5 -#define EXTR_IF_EXISTS 6 - -#define SORT_REGULAR 0 -#define SORT_NUMERIC 1 -#define SORT_STRING 2 +#define EXTR_PREFIX_ALL 3 +#define EXTR_PREFIX_INVALID 4 +#define EXTR_PREFIX_IF_EXISTS 5 +#define EXTR_IF_EXISTS 6 +#define EXTR_USER_FUNC 7 + +#define SORT_REGULAR 0 +#define SORT_NUMERIC 1 +#define SORT_STRING 2 -#define SORT_DESC 3 -#define SORT_ASC 4 +#define SORT_DESC 3 +#define SORT_ASC 4 -#define CASE_LOWER 0 -#define CASE_UPPER 1 +#define CASE_LOWER 0 +#define CASE_UPPER 1 -#define COUNT_NORMAL 0 -#define COUNT_RECURSIVE 1 +#define COUNT_NORMAL 0 +#define COUNT_RECURSIVE 1 PHP_MINIT_FUNCTION(array) { @@ -86,6 +87,7 @@ REGISTER_LONG_CONSTANT("EXTR_PREFIX_INVALID", EXTR_PREFIX_INVALID, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("EXTR_PREFIX_IF_EXISTS", EXTR_PREFIX_IF_EXISTS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("EXTR_IF_EXISTS", EXTR_IF_EXISTS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("EXTR_USER_FUNC", EXTR_USER_FUNC, CONST_CS | +CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_ASC", SORT_ASC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SORT_DESC", SORT_DESC, CONST_CS | CONST_PERSISTENT); @@ -1130,17 +1132,18 @@ } -/* {{{ proto int extract(array var_array [, int extract_type [, string prefix]]) +/* {{{ proto int extract(array var_array [, int extract_type [, string prefix [, +array arguments]]]) Imports variables into symbol table from an array */ PHP_FUNCTION(extract) { zval **var_array, **z_extract_type, **prefix; zval **entry, *data; + zval **user_func_res, **user_func_params, **args[99], *user_func_name; char *var_name; smart_str final_name = {0}; ulong num_key; uint var_name_len; - int var_exists, extract_type, key_type, count = 0; + int var_exists, extract_type, key_type, count = 0, argc, i = 1, +user_func_params_flag = 0; HashPosition pos; switch (ZEND_NUM_ARGS()) { @@ -1170,7 +1173,29 @@ } convert_to_long_ex(z_extract_type); extract_type = Z_LVAL_PP(z_extract_type); - convert_to_string_ex(prefix); + if ((Z_TYPE_PP(prefix) == IS_ARRAY) && (extract_type == +EXTR_USER_FUNC)) { + convert_to_array_ex(prefix); + } else { + convert_to_string_ex(prefix); + } + + break; + + case 4: + if (zend_get_parameters_ex(4, &var_array, &z_extract_type, +&prefix, &user_func_params) == FAILURE) { + WRONG_PARAM_COUNT; + } + convert_to_long_ex(z_extract_type); + extract_type = Z_LVAL_PP(z_extract_type); + if (Z_TYPE_PP(prefix) == IS_ARRAY) { + convert_to_array_ex(prefix); + } else { + convert_to_string_ex(prefix); + } + SEPARATE_ZVAL(user_func_params); + convert_to_array_ex(user_func_params); + + user_func_params_flag = 1; break; default: @@ -1178,7 +1203,7 @@ break; } - if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { + if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_USER_FUNC) { php_error(E_WARNING, "Unknown extract type in call to %s()", get_active_function_name(TSRMLS_C)); return; @@ -1189,7 +1214,7 @@ get_active_function_name(TSRMLS_C)); return; } - + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); while(zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); @@ -1248,6 +1273,51 @@ } break; + case EXTR_USER_FUNC: + if (final_name.len == 0) { + if (!user_func_params_flag) { /* the user +specified no additional arguments */ + argc = 1; + args[0] = emalloc(sizeof(args[0])); + MAKE_STD_ZVAL(*args[0]); + ZVAL_STRINGL(*args[0], var_name, +var_name_len, 0); + } else { /* we have an array of additional +arguments */ + argc = 1 + +zend_hash_num_elements(Z_ARRVAL_PP(user_func_params)); + args[0] = emalloc(sizeof(zval *)); + MAKE_STD_ZVAL(*args[0]); + ZVAL_STRINGL(*args[0], var_name, +var_name_len, 0); + + /* copy arguments from user-array to +zval **args[] */ + for +(zend_hash_internal_pointer_reset(Z_ARRVAL_PP(user_func_params)); + +zend_hash_get_current_data(Z_ARRVAL_PP(user_func_params), (void **)&args[i++]) == +SUCCESS; + +zend_hash_move_forward(Z_ARRVAL_PP(user_func_params))) + { + args[i] = emalloc(sizeof(zval +*)); + MAKE_STD_ZVAL(*args[i]); + + } + } + + user_func_res = emalloc(sizeof(zval *)); + MAKE_STD_ZVAL(*user_func_res); + + /* Call the userland function */ + if (call_user_function_ex(EG(function_table), +NULL, *prefix, + user_func_res, argc, args, +0, NULL TSRMLS_CC) == SUCCESS) { + + smart_str_appendl(&final_name, +Z_STRVAL_PP(user_func_res), Z_STRLEN_PP(user_func_res)); + zval_ptr_dtor(user_func_res); + + + } else { + zval_ptr_dtor(user_func_res); + efree(args); + php_error(E_WARNING, "Unable to call +%s() - function does not exist", + Z_STRVAL_PP(prefix)); + } + efree(*args); + } + break; + default: if (!var_exists) smart_str_appendl(&final_name, var_name, var_name_len);
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php