Hi all

Attached* is a patch introducing a new parameter to in_array() and
array_search() which will set the internal pointer to the first
location of $needle in the $haystack (granted that $needle exists
within the $haystack).

This will make it possible to search for a value in an array and then
run prev()/next() on the array to get the next/previous sibling.

I'd like to commit this after 5.2.4 has been released if there are no
objections?

-Hannes

* In case it doesn't come through: http://home.nith.no/~maghan/keeppos/
Index: ext/standard/basic_functions.c
===================================================================
RCS file: /repository/php-src/ext/standard/basic_functions.c,v
retrieving revision 1.725.2.31.2.59
diff -u -p -r1.725.2.31.2.59 basic_functions.c
--- ext/standard/basic_functions.c	19 Jul 2007 15:49:45 -0000	1.725.2.31.2.59
+++ ext/standard/basic_functions.c	15 Aug 2007 13:38:11 -0000
@@ -362,6 +362,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_in_array,
 	ZEND_ARG_INFO(0, needle)
 	ZEND_ARG_INFO(0, haystack) /* ARRAY_INFO(0, haystack, 0) */
 	ZEND_ARG_INFO(0, strict)
+	ZEND_ARG_INFO(0, keeppos)
 ZEND_END_ARG_INFO()
 
 static
@@ -369,6 +370,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_sea
 	ZEND_ARG_INFO(0, needle)
 	ZEND_ARG_INFO(0, haystack) /* ARRAY_INFO(0, haystack, 0) */
 	ZEND_ARG_INFO(0, strict)
+	ZEND_ARG_INFO(0, keeppos)
 ZEND_END_ARG_INFO()
 
 static
Index: ext/standard/array.c
===================================================================
RCS file: /repository/php-src/ext/standard/array.c,v
retrieving revision 1.308.2.21.2.32
diff -u -p -r1.308.2.21.2.32 array.c
--- ext/standard/array.c	10 Aug 2007 12:17:26 -0000	1.308.2.21.2.32
+++ ext/standard/array.c	15 Aug 2007 13:38:11 -0000
@@ -1210,17 +1210,19 @@ static void php_search_array(INTERNAL_FU
  	zval **value,				/* value to check for */
 		 **array,				/* array to check in */
 		 **strict,				/* strict comparison or not */
+		 **z_kpos,				/* position the internal pointer at the found location */
 		 **entry,				/* pointer to array entry */
 		  res;					/* comparison result */
 	HashTable *target_hash;		/* array hashtable */
 	HashPosition pos;			/* hash iterator */
+	zend_bool kpos = 0;
    	ulong num_key;
 	uint str_key_len;
    	char *string_key;
 	int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
 
-	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, &z_kpos) == FAILURE) {
 		WRONG_PARAM_COUNT;
 	}
 
@@ -1230,11 +1232,15 @@ static void php_search_array(INTERNAL_FU
 		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(z_kpos);
+			kpos = Z_BVAL_PP(z_kpos);
+		}
 	}
 
 	target_hash = HASH_OF(*array);
@@ -1242,6 +1248,9 @@ static void php_search_array(INTERNAL_FU
 	while (zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) {
 	 	is_equal_func(&res, *value, *entry TSRMLS_CC);
 		if (Z_LVAL(res)) {
+			if (kpos) {
+				Z_ARRVAL_PP(array)->pInternalPointer = pos;
+			}
 			if (behavior == 0) {		 
 				RETURN_TRUE;
 			} else {
@@ -1264,7 +1273,7 @@ static void php_search_array(INTERNAL_FU
 }
 /* }}} */
 
-/* {{{ proto bool in_array(mixed needle, array haystack [, bool strict])
+/* {{{ proto bool in_array(mixed needle, array haystack [, bool strict [, bool keep_pos=false]])
    Checks if the given value exists in the array */
 PHP_FUNCTION(in_array)
 {
@@ -1272,7 +1281,7 @@ PHP_FUNCTION(in_array)
 }
 /* }}} */
 
-/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict])
+/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool keep_pos=false]])
    Searches the array for a given value and returns the corresponding key if successful */
 PHP_FUNCTION(array_search)
 {
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to