Hi!

. end
. prev
. next
. reset
. current
. key
. array_key_exists
. array_unique
. array_flip
. array_walk_recursive
. array_walk
. uksort
. uasort
. usort
. natcasesort
. natsort

Attached is the patch that should restore BC for all those functions except sorts and array_unique/array_flip (these should be trivial too but I still thing their support for objects is just a bug). Please tell if you are using those (ones not BCed) in any meaningful scenario on objects.

This is done by having 'a' and 'h' specifiers have sister ones 'A' and 'H' that would accept objects if those have working HASH_OF. I have opted out for new letters and not sign since signs currently used for generic modifiers (like "separate it") and object-array relation is not generic.
Any comments?
And last but not least - anybody cares to write tests for those object/array cases?
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]
Index: ext/standard/array.c
===================================================================
RCS file: /repository/php-src/ext/standard/array.c,v
retrieving revision 1.308.2.21.2.37.2.45
diff -u -r1.308.2.21.2.37.2.45 array.c
--- ext/standard/array.c        21 Oct 2008 22:08:36 -0000      
1.308.2.21.2.37.2.45
+++ ext/standard/array.c        21 Nov 2008 19:49:53 -0000
@@ -751,16 +751,17 @@
    Advances array argument's internal pointer to the last element and return 
it */
 PHP_FUNCTION(end)
 {
-       zval *array, **entry;
+       HashTable *array;
+       zval **entry;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == 
FAILURE) {
                return;
        }
 
-       zend_hash_internal_pointer_end(Z_ARRVAL_P(array));
+       zend_hash_internal_pointer_end(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) 
&entry) == FAILURE) {
+               if (zend_hash_get_current_data(array, (void **) &entry) == 
FAILURE) {
                        RETURN_FALSE;
                }
 
@@ -773,16 +774,17 @@
    Move array argument's internal pointer to the previous element and return 
it */
 PHP_FUNCTION(prev)
 {
-       zval *array, **entry;
+       HashTable *array;
+       zval **entry;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == 
FAILURE) {
                return;
        }
 
-       zend_hash_move_backwards(Z_ARRVAL_P(array));
+       zend_hash_move_backwards(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) 
&entry) == FAILURE) {
+               if (zend_hash_get_current_data(array, (void **) &entry) == 
FAILURE) {
                        RETURN_FALSE;
                }
 
@@ -795,16 +797,17 @@
    Move array argument's internal pointer to the next element and return it */
 PHP_FUNCTION(next)
 {
-       zval *array, **entry;
+       HashTable *array;
+       zval **entry;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == 
FAILURE) {
                return;
        }
 
-       zend_hash_move_forward(Z_ARRVAL_P(array));
+       zend_hash_move_forward(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) 
&entry) == FAILURE) {
+               if (zend_hash_get_current_data(array, (void **) &entry) == 
FAILURE) {
                        RETURN_FALSE;
                }
 
@@ -817,16 +820,17 @@
    Set array argument's internal pointer to the first element and return it */
 PHP_FUNCTION(reset)
 {
-       zval *array, **entry;
+       HashTable *array;
+       zval **entry;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == 
FAILURE) {
                return;
        }
 
-       zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));
+       zend_hash_internal_pointer_reset(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) 
&entry) == FAILURE) {
+               if (zend_hash_get_current_data(array, (void **) &entry) == 
FAILURE) {
                        RETURN_FALSE;
                }
 
@@ -839,13 +843,14 @@
    Return the element currently pointed to by the internal array pointer */
 PHP_FUNCTION(current)
 {
-       zval *array, **entry;
+       HashTable *array;
+       zval **entry;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == 
FAILURE) {
                return;
        }
 
-       if (zend_hash_get_current_data(Z_ARRVAL_P(array), (void **) &entry) == 
FAILURE) {
+       if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
                RETURN_FALSE;
        }
        RETURN_ZVAL(*entry, 1, 0);
@@ -856,16 +861,16 @@
    Return the key of the element currently pointed to by the internal array 
pointer */
 PHP_FUNCTION(key)
 {
-       zval *array;
+       HashTable *array;
        char *string_key;
        uint string_length;
        ulong num_key;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == 
FAILURE) {
                return;
        }
 
-       switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, 
&string_length, &num_key, 0, NULL)) {
+       switch (zend_hash_get_current_key_ex(array, &string_key, 
&string_length, &num_key, 0, NULL)) {
                case HASH_KEY_IS_STRING:
                        RETVAL_STRINGL(string_key, string_length - 1, 1);
                        break;
@@ -1070,21 +1075,21 @@
    Apply a user function to every member of an array */
 PHP_FUNCTION(array_walk)
 {
-       zval *array,
-                *userdata = NULL;
+       HashTable *array;
+       zval *userdata = NULL;
        zend_fcall_info orig_array_walk_fci;
        zend_fcall_info_cache orig_array_walk_fci_cache;
 
        orig_array_walk_fci = BG(array_walk_fci);
        orig_array_walk_fci_cache = BG(array_walk_fci_cache);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af|z/", &array, 
&BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Hf|z/", &array, 
&BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) {
                BG(array_walk_fci) = orig_array_walk_fci;
                BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
                return;
        }
 
-       php_array_walk(Z_ARRVAL_P(array), userdata ? &userdata : NULL, 0 
TSRMLS_CC);
+       php_array_walk(array, userdata ? &userdata : NULL, 0 TSRMLS_CC);
        BG(array_walk_fci) = orig_array_walk_fci;
        BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
        RETURN_TRUE;
@@ -1095,21 +1100,21 @@
    Apply a user function recursively to every member of an array */
 PHP_FUNCTION(array_walk_recursive)
 {
-       zval *array,
-                *userdata = NULL;
+       HashTable *array;
+       zval *userdata = NULL;
        zend_fcall_info orig_array_walk_fci;
        zend_fcall_info_cache orig_array_walk_fci_cache;
 
        orig_array_walk_fci = BG(array_walk_fci);
        orig_array_walk_fci_cache = BG(array_walk_fci_cache);
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af|z/", &array, 
&BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Hf|z/", &array, 
&BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) {
                BG(array_walk_fci) = orig_array_walk_fci;
                BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
                return;
        }
 
-       php_array_walk(Z_ARRVAL_P(array), userdata ? &userdata : NULL, 1 
TSRMLS_CC);
+       php_array_walk(array, userdata ? &userdata : NULL, 1 TSRMLS_CC);
        BG(array_walk_fci) = orig_array_walk_fci;
        BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
        RETURN_TRUE;
@@ -4268,26 +4273,26 @@
    Checks if the given key or index exists in the array */
 PHP_FUNCTION(array_key_exists)
 {
-       zval *key,                                      /* key to check for */
-                *array;                                /* array to check in */
+       zval *key;                                      /* key to check for */
+       HashTable *array;                       /* array to check in */
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &key, 
&array) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zH", &key, 
&array) == FAILURE) {
                return;
        }
 
        switch (Z_TYPE_P(key)) {
                case IS_STRING:
-                       if (zend_symtable_exists(Z_ARRVAL_P(array), 
Z_STRVAL_P(key), Z_STRLEN_P(key) + 1)) {
+                       if (zend_symtable_exists(array, Z_STRVAL_P(key), 
Z_STRLEN_P(key) + 1)) {
                                RETURN_TRUE;
                        }
                        RETURN_FALSE;
                case IS_LONG:
-                       if (zend_hash_index_exists(Z_ARRVAL_P(array), 
Z_LVAL_P(key))) {
+                       if (zend_hash_index_exists(array, Z_LVAL_P(key))) {
                                RETURN_TRUE;
                        }
                        RETURN_FALSE;
                case IS_NULL:
-                       if (zend_hash_exists(Z_ARRVAL_P(array), "", 1)) {
+                       if (zend_hash_exists(array, "", 1)) {
                                RETURN_TRUE;
                        }
                        RETURN_FALSE;
Index: ext/standard/basic_functions.c
===================================================================
RCS file: /repository/php-src/ext/standard/basic_functions.c,v
retrieving revision 1.725.2.31.2.64.2.73
diff -u -r1.725.2.31.2.64.2.73 basic_functions.c
--- ext/standard/basic_functions.c      17 Nov 2008 11:27:59 -0000      
1.725.2.31.2.64.2.73
+++ ext/standard/basic_functions.c      21 Nov 2008 19:49:53 -0000
@@ -4770,7 +4770,7 @@
        HashTable *params_ar;
        int num_elems, element = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/za/", 
&callback, &object, &params) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/zA/", 
&callback, &object, &params) == FAILURE) {
                return;
        }
 
Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.34.2.55
diff -u -r1.296.2.27.2.34.2.55 zend_API.c
--- Zend/zend_API.c     4 Nov 2008 15:58:49 -0000       1.296.2.27.2.34.2.55
+++ Zend/zend_API.c     21 Nov 2008 19:49:53 -0000
@@ -295,7 +295,7 @@
 {
        char *spec_walk = *spec;
        char c = *spec_walk++;
-       int return_null = 0;
+       int return_null = 0, obj_array = 0;
 
        /* scan through modifiers */
        while (1) {
@@ -451,7 +451,8 @@
                                }
                        }
                        break;
-
+               case 'A':
+                               obj_array = 1;
                case 'a':
                        {
                                zval **p = va_arg(*va, zval **);
@@ -459,14 +460,15 @@
                                        *p = NULL;
                                        break;
                                }
-                               if (Z_TYPE_PP(arg) == IS_ARRAY) {
+                               if (Z_TYPE_PP(arg) == IS_ARRAY || 
(Z_TYPE_PP(arg) == IS_OBJECT && obj_array != 0)) {
                                        *p = *arg;
                                } else {
                                        return "array";
                                }
                        }
                        break;
-
+               case 'H':
+                               obj_array = 1;
                case 'h':
                        {
                                HashTable **p = va_arg(*va, HashTable **);
@@ -476,6 +478,11 @@
                                }
                                if (Z_TYPE_PP(arg) == IS_ARRAY) {
                                        *p = Z_ARRVAL_PP(arg);
+                               } else if(obj_array && Z_TYPE_PP(arg) == 
IS_OBJECT) {
+                                       *p = HASH_OF(*arg);
+                                       if(*p == NULL) {
+                                               return "array";
+                                       }
                                } else {
                                        return "array";
                                }
@@ -670,7 +677,8 @@
                        case 'o': case 'O':
                        case 'z': case 'Z':
                        case 'C': case 'h':
-                       case 'f':
+                       case 'f': case 'A':
+                       case 'H':
                                max_num_args++;
                                break;
 
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to