Index: ext/standard/array.c =================================================================== RCS file: /repository/php-src/ext/standard/array.c,v retrieving revision 1.308.2.21.2.22 diff -u -u -r1.308.2.21.2.22 array.c --- ext/standard/array.c 1 Jan 2007 09:36:07 -0000 1.308.2.21.2.22 +++ ext/standard/array.c 5 Jan 2007 04:57:47 -0000 @@ -4528,6 +4528,115 @@ } /* }}} */ +/* {{{ php_array_key_index_common + keyOffset: 0: determine from parameters; 1 = first; -1 = last + */ +static void php_array_key_index_common(INTERNAL_FUNCTION_PARAMETERS, int keyOffset) +{ + zval *input, *value; + zval **arrValue; + HashPosition pos; + int key_type; + char *string_key; + uint string_key_len; + ulong num_key; + zend_bool direction; + + if(keyOffset == 0) { + //array_key_index(array input, int offset, [mixed value]) + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|z", &input, &keyOffset, &value) == FAILURE) { + RETURN_NULL(); + } + } else { + if(keyOffset == 1) { + keyOffset = 0; + } + + //array_(first|last)(array input, [mixed value]) + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &input, &value) == FAILURE) { + RETURN_NULL(); + } + } + + //true == forward; false == backwards + direction = (keyOffset >= 0); + if(!direction) { + keyOffset = abs(keyOffset) - 1; + } + + if(keyOffset >= zend_hash_num_elements(Z_ARRVAL_P(input))) { + RETURN_NULL(); + } + + if(direction) { + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); + } else { + zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(input), &pos); + } + + if(keyOffset >= 1) { + while(keyOffset--) { + if(direction) { + zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); + } else { + zend_hash_move_backwards_ex(Z_ARRVAL_P(input), &pos); + } + } + } + + key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, &pos); + + switch(key_type) { + case HASH_KEY_IS_LONG: + RETVAL_LONG(num_key); + break; + + case HASH_KEY_IS_STRING: + RETVAL_STRINGL(string_key, string_key_len - 1, 1); + break; + + case HASH_KEY_NON_EXISTANT: + default: + RETURN_NULL(); + break; + } + + if(ZEND_NUM_ARGS() >= 2) { + zval_dtor(value); + + zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void**)&arrValue, &pos); + + *value = **arrValue; + zval_copy_ctor(value); + ZVAL_ADDREF(value); + } +} +/* }}} */ + +/* {{{ proto mixed array_key_index(array input, int index [, mixed value]) + Return the array's index key (and optionally, value) */ +PHP_FUNCTION(array_key_index) +{ + php_array_key_index_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ proto mixed array_first(array input [, mixed value]) + Return the array's first key (and optionally, value) */ +PHP_FUNCTION(array_first) +{ + php_array_key_index_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto mixed array_last(array input [, mixed value]) + Return the array's last key (and optionally, value) */ +PHP_FUNCTION(array_last) +{ + php_array_key_index_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1); +} +/* }}} */ + /* * Local variables: * tab-width: 4 Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php-src/ext/standard/basic_functions.c,v retrieving revision 1.725.2.31.2.39 diff -u -u -r1.725.2.31.2.39 basic_functions.c --- ext/standard/basic_functions.c 1 Jan 2007 09:36:08 -0000 1.725.2.31.2.39 +++ ext/standard/basic_functions.c 5 Jan 2007 04:57:48 -0000 @@ -682,6 +682,19 @@ ZEND_ARG_INFO(0, keys) /* ARRAY_INFO(0, keys, 0) */ ZEND_ARG_INFO(0, values) /* ARRAY_INFO(0, values, 0) */ ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_array_key_index, 0) + ZEND_ARG_INFO(0, input) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(1, value) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_array_first, 0) + ZEND_ARG_INFO(0, input) + ZEND_ARG_INFO(1, value) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ basic_functions.c */ static @@ -3743,6 +3756,9 @@ PHP_FE(array_chunk, arginfo_array_chunk) PHP_FE(array_combine, arginfo_array_combine) PHP_FE(array_key_exists, arginfo_array_key_exists) + PHP_FE(array_key_index, arginfo_array_key_index) + PHP_FE(array_first, arginfo_array_first) + PHP_FE(array_last, arginfo_array_first) /* aliases from array.c */ PHP_FALIAS(pos, current, arginfo_current) Index: ext/standard/php_array.h =================================================================== RCS file: /repository/php-src/ext/standard/php_array.h,v retrieving revision 1.50.2.2.2.3 diff -u -u -r1.50.2.2.2.3 php_array.h --- ext/standard/php_array.h 1 Jan 2007 09:36:08 -0000 1.50.2.2.2.3 +++ ext/standard/php_array.h 5 Jan 2007 04:57:48 -0000 @@ -99,6 +99,9 @@ PHP_FUNCTION(array_key_exists); PHP_FUNCTION(array_chunk); PHP_FUNCTION(array_combine); +PHP_FUNCTION(array_key_index); +PHP_FUNCTION(array_first); +PHP_FUNCTION(array_last); HashTable* php_splice(HashTable *, int, int, zval ***, int, HashTable **); PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC);