Hi, pasted in and attached to this mail is patch which gives the opportunity for programmer to move the internal pointer of the array when searching with array_search(). Fourth parameter (move_pointer) of type bool is added. Why I did that? Few days ago I was asked by a man on #php how when he finds what he wants using array_search to traverse the array forwards and backwards starting from the key returned by array_search. The only way for him to do that was to use integers as keys and additional variable. Using this new feature the user will not be limited to integer indeces.
Andrey The diff follows (it is against /* $Id: array.c,v 1.181 2002/08/03 00:40:46 rodif_bl Exp $ */): --- array.c Sat Aug 3 03:48:15 2002 +++ ../array.c Sun Aug 4 16:12:17 2002 @@ -1030,10 +1030,19 @@ */ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) { +#define SEARCH_MOVE_POINTER(___move_pointer,___hash,___how) \ +if (___move_pointer){\ + zend_hash_internal_pointer_reset(___hash);\ + while ((--___how) >0){\ + zend_hash_move_forward(___hash);\ + }\ +} + zval **value, /* value to check for */ **array, /* array to check in */ **strict, /* strict comparison or not */ **entry, /* pointer to array entry */ + **move_pointer, /* whether to move internal pointer or +not */ res; /* comparison result */ HashTable *target_hash; /* array hashtable */ HashPosition pos; /* hash iterator */ @@ -1041,9 +1050,11 @@ uint str_key_len; char *string_key; int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; + int iterations = 0; + int mv_pointer = 0; - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) { + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 || + zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict, +&move_pointer) == FAILURE) { WRONG_PARAM_COUNT; } @@ -1057,27 +1068,38 @@ RETURN_FALSE; } - if (ZEND_NUM_ARGS() == 3) { + if (ZEND_NUM_ARGS() >= 3) { convert_to_boolean_ex(strict); if (Z_LVAL_PP(strict)) { is_equal_func = is_identical_function; } } + + if (ZEND_NUM_ARGS() == 4) { + convert_to_boolean_ex(move_pointer); + if (Z_LVAL_PP(move_pointer)){ + mv_pointer = 1; + } + } target_hash = HASH_OF(*array); zend_hash_internal_pointer_reset_ex(target_hash, &pos); while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) { + iterations++; is_equal_func(&res, *value, *entry TSRMLS_CC); if (Z_LVAL(res)) { if (behavior==0) { + SEARCH_MOVE_POINTER(mv_pointer,target_hash, +iterations); RETURN_TRUE; } else { /* Return current key */ switch (zend_hash_get_current_key_ex(target_hash, &string_key, &str_key_len, &num_key, 0, &pos)) { case HASH_KEY_IS_STRING: + SEARCH_MOVE_POINTER(mv_pointer, +target_hash, iterations); RETURN_STRINGL(string_key, str_key_len-1, 1); break; case HASH_KEY_IS_LONG: + SEARCH_MOVE_POINTER(mv_pointer, +target_hash, iterations); RETURN_LONG(num_key); break; } @@ -1088,6 +1110,7 @@ } RETURN_FALSE; +#undef SEARCH_MOVE_POINTER } @@ -1099,7 +1122,7 @@ } /* }}} */ -/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict]) +/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool +move_pointer]]) Searches the array for a given value and returns the corresponding key if successful */ PHP_FUNCTION(array_search) {
--- array.c Sat Aug 3 03:48:15 2002 +++ ../array.c Sun Aug 4 16:12:17 2002 @@ -1030,10 +1030,19 @@ */ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) { +#define SEARCH_MOVE_POINTER(___move_pointer,___hash,___how) \ +if (___move_pointer){\ + zend_hash_internal_pointer_reset(___hash);\ + while ((--___how) >0){\ + zend_hash_move_forward(___hash);\ + }\ +} + zval **value, /* value to check for */ **array, /* array to check in */ **strict, /* strict comparison or not */ **entry, /* pointer to array entry */ + **move_pointer, /* whether to move internal pointer or not */ res; /* comparison result */ HashTable *target_hash; /* array hashtable */ HashPosition pos; /* hash iterator */ @@ -1041,9 +1050,11 @@ uint str_key_len; char *string_key; int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; + int iterations = 0; + int mv_pointer = 0; - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) { + if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 || + zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict, &move_pointer) == FAILURE) { WRONG_PARAM_COUNT; } @@ -1057,27 +1068,38 @@ RETURN_FALSE; } - if (ZEND_NUM_ARGS() == 3) { + if (ZEND_NUM_ARGS() >= 3) { convert_to_boolean_ex(strict); if (Z_LVAL_PP(strict)) { is_equal_func = is_identical_function; } } + + if (ZEND_NUM_ARGS() == 4) { + convert_to_boolean_ex(move_pointer); + if (Z_LVAL_PP(move_pointer)){ + mv_pointer = 1; + } + } target_hash = HASH_OF(*array); zend_hash_internal_pointer_reset_ex(target_hash, &pos); while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) { + iterations++; is_equal_func(&res, *value, *entry TSRMLS_CC); if (Z_LVAL(res)) { if (behavior==0) { + SEARCH_MOVE_POINTER(mv_pointer,target_hash, iterations); RETURN_TRUE; } else { /* Return current key */ switch (zend_hash_get_current_key_ex(target_hash, &string_key, &str_key_len, &num_key, 0, &pos)) { case HASH_KEY_IS_STRING: + SEARCH_MOVE_POINTER(mv_pointer, target_hash, iterations); RETURN_STRINGL(string_key, str_key_len-1, 1); break; case HASH_KEY_IS_LONG: + SEARCH_MOVE_POINTER(mv_pointer, target_hash, iterations); RETURN_LONG(num_key); break; } @@ -1088,6 +1110,7 @@ } RETURN_FALSE; +#undef SEARCH_MOVE_POINTER } @@ -1099,7 +1122,7 @@ } /* }}} */ -/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict]) +/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool move_pointer]]) Searches the array for a given value and returns the corresponding key if successful */ PHP_FUNCTION(array_search) {
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php