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