Commit: 9035a1ed246d4d2d867edc01616ca96b40a7cd11 Author: Ben Ramsey <ram...@php.net> Fri, 13 Apr 2012 23:17:56 -0500 Parents: e1410b5a70543856de3978603b41fbf2ca5d330c Branches: PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=9035a1ed246d4d2d867edc01616ca96b40a7cd11 Log: Implement new array function array_column() array_column() returns the values of the specified column from a multi-dimensional array. Changed paths: M ext/standard/array.c M ext/standard/basic_functions.c M ext/standard/php_array.h A ext/standard/tests/array/array_column.phpt Diff: diff --git a/ext/standard/array.c b/ext/standard/array.c index d1397a5..b707301 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2563,6 +2563,87 @@ PHP_FUNCTION(array_count_values) } /* }}} */ +/* {{{ proto array array_column(array input, mixed key) + Return the values from a single column in the input array, identified by the key */ +PHP_FUNCTION(array_column) +{ + zval *zarray, *zoffset, **data, **zvalue; + HashTable *arr_hash; + HashPosition pointer; + long index = 0; + char *key = NULL; + int key_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az", &zarray, &zoffset) == FAILURE) { + return; + } + + arr_hash = Z_ARRVAL_P(zarray); + array_init(return_value); + + switch (Z_TYPE_P(zoffset)) { + case IS_NULL: + index = 0; + break; + case IS_DOUBLE: + index = (long)Z_DVAL_P(zoffset); + break; + case IS_BOOL: + case IS_LONG: + case IS_RESOURCE: + index = Z_LVAL_P(zoffset); + break; + case IS_STRING: + key = Z_STRVAL_P(zoffset); + key_len = Z_STRLEN_P(zoffset); + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The key should be either a string or an integer"); + return; + } + + for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); + zend_hash_get_current_data_ex(arr_hash, (void**)&data, &pointer) == SUCCESS; + zend_hash_move_forward_ex(arr_hash, &pointer)) { + + if (Z_TYPE_PP(data) == IS_ARRAY) { + if (key && zend_hash_find(Z_ARRVAL_PP(data), key, key_len + 1, (void**)&zvalue) == FAILURE) { + continue; + } else if (!key && zend_hash_index_find(Z_ARRVAL_PP(data), index, (void**)&zvalue) == FAILURE) { + continue; + } + + switch (Z_TYPE_PP(zvalue)) { + case IS_NULL: + add_next_index_null(return_value); + break; + case IS_LONG: + add_next_index_long(return_value, Z_LVAL_PP(zvalue)); + break; + case IS_DOUBLE: + add_next_index_double(return_value, Z_DVAL_PP(zvalue)); + break; + case IS_BOOL: + add_next_index_bool(return_value, Z_BVAL_PP(zvalue)); + break; + case IS_OBJECT: + zval_add_ref(zvalue); + add_next_index_zval(return_value, *zvalue); + break; + case IS_STRING: + add_next_index_stringl(return_value, Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue), 1); + break; + case IS_RESOURCE: + zval_add_ref(zvalue); + add_next_index_resource(return_value, Z_RESVAL_PP(zvalue)); + break; + } + } + + } +} +/* }}} */ + /* {{{ proto array array_reverse(array input [, bool preserve keys]) Return input as a new array with the order of the entries reversed */ PHP_FUNCTION(array_reverse) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 61e2f39..2e44150 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -433,6 +433,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_array_count_values, 0) ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_column, 0, 0, 2) + ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_array_reverse, 0, 0, 1) ZEND_ARG_INFO(0, input) /* ARRAY_INFO(0, arg, 0) */ ZEND_ARG_INFO(0, preserve_keys) @@ -3299,6 +3304,7 @@ const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(array_keys, arginfo_array_keys) PHP_FE(array_values, arginfo_array_values) PHP_FE(array_count_values, arginfo_array_count_values) + PHP_FE(array_column, arginfo_array_column) PHP_FE(array_reverse, arginfo_array_reverse) PHP_FE(array_reduce, arginfo_array_reduce) PHP_FE(array_pad, arginfo_array_pad) diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h index 9099017..2126c09 100644 --- a/ext/standard/php_array.h +++ b/ext/standard/php_array.h @@ -71,6 +71,7 @@ PHP_FUNCTION(array_replace_recursive); PHP_FUNCTION(array_keys); PHP_FUNCTION(array_values); PHP_FUNCTION(array_count_values); +PHP_FUNCTION(array_column); PHP_FUNCTION(array_reverse); PHP_FUNCTION(array_reduce); PHP_FUNCTION(array_pad); diff --git a/ext/standard/tests/array/array_column.phpt b/ext/standard/tests/array/array_column.phpt new file mode 100644 index 0000000..08df3b8 --- /dev/null +++ b/ext/standard/tests/array/array_column.phpt @@ -0,0 +1,138 @@ +--TEST-- +Test array_column_values() function +--FILE-- +<?php +/* Prototype: + * array array_column(array $input, mixed $key); + * Description: + * Returns an array containing all the values from + * the specified "column" in a two-dimensional array. + */ + +echo "*** Testing basic functionalities ***\n"; +/* Array representing a possible record set returned from a database */ +$records = array( + array( + 'id' => 1, + 'first_name' => 'John', + 'last_name' => 'Doe' + ), + array( + 'id' => 2, + 'first_name' => 'Sally', + 'last_name' => 'Smith' + ), + array( + 'id' => 3, + 'first_name' => 'Jane', + 'last_name' => 'Jones' + ) +); + +echo "-- first_name column from recordset --\n"; +var_dump(array_column($records, 'first_name')); + +echo "-- id column from recordset --\n"; +var_dump(array_column($records, 'id')); + +echo "\n*** Testing multiple data types ***\n"; +$file = basename(__FILE__); +$fh = fopen($file, 'r', true); +$values = array( + array( + 'id' => 1, + 'value' => new stdClass + ), + array( + 'id' => 2, + 'value' => 34.2345 + ), + array( + 'id' => 3, + 'value' => true + ), + array( + 'id' => 4, + 'value' => false + ), + array( + 'id' => 5, + 'value' => null + ), + array( + 'id' => 6, + 'value' => 1234 + ), + array( + 'id' => 7, + 'value' => 'Foo' + ), + array( + 'id' => 8, + 'value' => $fh + ) +); +var_dump(array_column($values, 'value')); + +echo "\n*** Testing numeric column keys ***\n"; +$numericCols = array( + array('aaa', '111'), + array('bbb', '222'), + array('ccc', '333') +); +var_dump(array_column($numericCols, 1)); + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing basic functionalities *** +-- first_name column from recordset -- +array(3) { + [0]=> + string(4) "John" + [1]=> + string(5) "Sally" + [2]=> + string(4) "Jane" +} +-- id column from recordset -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +*** Testing multiple data types *** +array(8) { + [0]=> + object(stdClass)#1 (0) { + } + [1]=> + float(34.2345) + [2]=> + bool(true) + [3]=> + bool(false) + [4]=> + NULL + [5]=> + int(1234) + [6]=> + string(3) "Foo" + [7]=> + resource(5) of type (stream) +} + +*** Testing numeric column keys *** +array(3) { + [0]=> + string(3) "111" + [1]=> + string(3) "222" + [2]=> + string(3) "333" +} +Done -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php