I've added an extra option extract() to have potential variable names passed
to a user defined callback function. If this function then returns true,
it's extracted, if not it's not.

Anyone care to apply/check it?

Eg.:

<?php
function extract_callback($varname){
        return preg_match('/^var/', $varname);
}

$var['var_1'] = 1;
$var['var_2'] = 1;
$var['blaat'] = 1;

extract($var, EXTR_USER_CALLBACK, 'extract_callback');

printf('var_1: %s <br>', $var_1);
printf('var_2: %s <br>', $var_2);
printf('blaat: %s <br>', $blaat);
?>
Index: array.c
===================================================================
RCS file: /repository/php4/ext/standard/array.c,v
retrieving revision 1.156
diff -u -u -r1.156 array.c
--- array.c     5 Feb 2002 20:43:48 -0000       1.156
+++ array.c     25 Feb 2002 16:07:10 -0000
@@ -59,7 +59,8 @@
 #define        EXTR_PREFIX_INVALID             4
 #define        EXTR_PREFIX_IF_EXISTS   5
 #define        EXTR_IF_EXISTS                  6
-
+#define        EXTR_USER_CALLBACK              7
+
 #define SORT_REGULAR           0
 #define SORT_NUMERIC           1
 #define        SORT_STRING                     2
@@ -86,7 +87,8 @@
        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_CALLBACK", EXTR_USER_CALLBACK, 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);
 
@@ -1137,7 +1139,7 @@
 PHP_FUNCTION(extract)
 {
        zval **var_array, **z_extract_type, **prefix;
-       zval **entry, *data;
+       zval **entry, *data, *user_callback_retval, **user_callback_args[1], 
+*user_callback_arg;
        char *var_name;
        smart_str final_name = {0};
        ulong num_key;
@@ -1163,6 +1165,11 @@
                                php_error(E_WARNING, "%s() expects a prefix to be 
specified",
                                                  get_active_function_name(TSRMLS_C));
                                return;
+
+                       }else if(extract_type == EXTR_USER_CALLBACK){
+                               php_error(E_WARNING, "%s() expects a user defined 
+function to be specified",
+                                                 get_active_function_name(TSRMLS_C));
+                               return;
                        }
                        break;
                        
@@ -1180,7 +1187,7 @@
                        break;
        }
        
-       if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) {
+       if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_USER_CALLBACK) {
                php_error(E_WARNING, "Unknown extract type in call to %s()",
                                  get_active_function_name(TSRMLS_C));
                return;
@@ -1248,8 +1255,30 @@
                                        } else
                                                smart_str_appendl(&final_name, 
var_name, var_name_len);
                                }
-                               break;
-
+                               break;
+
+                       case EXTR_USER_CALLBACK:
+                               user_callback_arg = emalloc(sizeof(zval));
+                               MAKE_STD_ZVAL(user_callback_arg);
+                               ZVAL_STRING(user_callback_arg, var_name, 0);
+
+                               *(user_callback_args[0]) = user_callback_arg;
+
+                               if(call_user_function_ex(EG(function_table), NULL, 
+*prefix, &user_callback_retval, 1, user_callback_args, 0, NULL TSRMLS_CC) != SUCCESS){
+                                       php_error(E_WARNING, "Failed to call user 
+function: %s()", Z_STRVAL_PP(prefix));
+                                       return;
+                               }
+                               efree(user_callback_arg);
+
+                               if(!Z_BVAL_P(user_callback_retval)){
+                                       
+zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos);
+                                       continue;
+                               }else{
+                                       smart_str_appendl(&final_name, var_name, 
+var_name_len);
+                               }
+
+                               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