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

Reply via email to