Hi,
this patch adds new functionality to array_search(). It is mostly useful in 
cases where the indices in the array are not numeric but strings.
When a programmer wants to find the key for a value in the array he/she is 
give the opportunity to move the internal pointer of the array to the 
position where the value is found(of course array_search() stops at the first 
occurence if there is more than one pairs key=>value). After repositioning it 
is easy to use the functions that manipulate the internal pointer. Thus 
allowing the programmer to move back and forth in the array.
There is supplemental php script that shows the functionality.
The main function for repositioning is added to zend_hash.c . Zeev said that 
I have to move the what was former a macro to a function and I decided to 
make it zend_hash_move_internal_pointer_ex. However after following the 
discussion for debug_backtrace() for ZE1 I am not sure that it's place is 
there. You have to decide.

Regards,
Andrey
P.S.
Diffs are against:
1) array.c : /* $Id: array.c,v 1.184 2002/08/24 01:19:27 helly Exp $ */
2)zend_hash.c and zend_hash.h  : no version in the files. It is from : 
php4-200208260600
<?php
$a = array('one'=>'ala','two'=>'bala','three'=>'porto','four'=>'kala');
var_dump($a);
echo "Nexting...\n";
next($a);
echo "Showing current...\n";
var_dump(current($a));
echo "Searching in the array wo moving(2 params)...\n";
var_dump(array_search('porto',$a));
echo "Showing current...\n";
var_dump(current($a));
echo "Searching in the array wo moving(3 params)...\n";
var_dump(array_search('porto',$a,TRUE));
echo "Showing current...\n";
var_dump(current($a));
echo "Searching in the array wo moving(4 params)...\n";
var_dump(array_search('porto',$a, FALSE, FALSE));
echo "Showing current...\n";
var_dump(current($a));
echo "Searching in the array w/ moving...\n";
var_dump(array_search('porto',$a,FALSE,TRUE));
echo "Showing current...\n";
var_dump(current($a));
?>
1042a1043,1070
> ZEND_API void zend_hash_move_pointer_ex(HashTable *ht, HashPosition *pos, int how, 
>int start_pos)
> {
>       int counter;
>       HashPosition *current = pos ? pos : &ht->pInternalPointer;
> 
>       IS_CONSISTENT(ht);
>       counter = how;
>       switch (start_pos){
>               case 0:
>                       zend_hash_internal_pointer_reset_ex(ht, current);
>                       while (counter-- > 0 && zend_hash_move_forward_ex(ht, 
>current)==SUCCESS);
>                       break;
>               case 2:
>                       zend_hash_internal_pointer_end_ex(ht, current);
>                       while (counter-- > 0 && zend_hash_move_backwards_ex(ht, 
>current)==SUCCESS);
>                       break;
>               case 1:
>                       if (how > 0){
>                               while (counter-- > 0 && zend_hash_move_forward_ex(ht, 
>current)==SUCCESS);
>                       }else if(how < 0){
>                               while (counter++ < 0 && 
>zend_hash_move_backwards_ex(ht, current)==SUCCESS);
>                       }
>                       break;
>               default:
>                       break;
>       }
> }
> 
1326a1355
> 
162a163
> ZEND_API void zend_hash_move_pointer_ex(HashTable *ht, HashPosition *pos, int how, 
>int start_pos);
177a179,180
> #define zend_hash_move_pointer(ht, how, direction) \
>       zend_hash_move_pointer_ex(ht, NULL, how, direction)
220a224
> 
1027c1027
< static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
---
> static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior TSRMLS_DC)
1032a1033
> 		 **move_pointer,		/* whether to move internal pointer or not */
1040,1042c1041,1045
< 	  	
< 	if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
< 		zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) {
---
> 	int iterations = 0;
> 	int mv_pointer = 0;
> 		  	
> 	if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 ||
> 		zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict, &move_pointer) == FAILURE) {
1046,1049c1049,1066
< 	if (Z_TYPE_PP(value) == IS_OBJECT) {
< 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong datatype for first argument");
< 		RETURN_FALSE;
< 	}
---
> 	switch (ZEND_NUM_ARGS()){
> 		case 4:
> 			convert_to_boolean_ex(move_pointer);
> 			if (Z_LVAL_PP(move_pointer)){
> 				mv_pointer = 1;
> 			}
> 			/* intentional fall-through*/
> 		case 3:
> 			convert_to_boolean_ex(strict);
> 			if (Z_LVAL_PP(strict)) {
> 				is_equal_func = is_identical_function;
> 			}		
> 			/* intentional fall-through*/
> 		case 2:
> 			if (Z_TYPE_PP(value) == IS_OBJECT) {
> 				php_error(E_WARNING, "%s(): Wrong datatype for first argument", get_active_function_name(TSRMLS_C));
> 				RETURN_FALSE;
> 			}
1051,1060c1068,1074
< 	if (Z_TYPE_PP(array) != IS_ARRAY) {
< 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong datatype for second argument");
< 		RETURN_FALSE;
< 	}
< 
< 	if (ZEND_NUM_ARGS() == 3) {
< 		convert_to_boolean_ex(strict);
< 		if (Z_LVAL_PP(strict)) {
< 			is_equal_func = is_identical_function;
< 		}
---
> 			if (Z_TYPE_PP(array) != IS_ARRAY) {
> 				php_error(E_WARNING, "%s(): Wrong datatype for second argument", get_active_function_name(TSRMLS_C));
> 				RETURN_FALSE;
> 			}		
> 			break;
> 		default:
> 			break;
1062c1076
< 
---
> 	
1065c1079
< 	while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) {
---
> 	while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) {	
1068a1083,1085
> 				if (mv_pointer){
> 					zend_hash_move_pointer(target_hash, iterations,0);
> 				}
1073a1091,1093
> 						if (mv_pointer){
> 							zend_hash_move_pointer(target_hash, iterations,0);
> 						}
1076a1097,1099
> 						if (mv_pointer){
> 							zend_hash_move_pointer(target_hash, iterations,0);
> 						}
1081,1082c1104,1105
< 		}
< 		
---
> 			
> 		}	
1083a1107
> 		iterations++;		
1098c1122
< /* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict])
---
> /* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool move_pointer]])
3422a3447
> 
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to