diff options
| author | David Soria Parra <dsp@php.net> | 2013-03-20 13:02:33 +0100 |
|---|---|---|
| committer | David Soria Parra <dsp@php.net> | 2013-03-20 13:02:33 +0100 |
| commit | 0173c4bab0357e58e74e2a84b18fa31034699582 (patch) | |
| tree | d25b1fa1c8311b9642bb3d8cae911151a538c53f /ext/standard/array.c | |
| parent | bf8026aacf6ebeafca9c78928e3e660d7698ff6a (diff) | |
| parent | f5bf1ba88fbacfebbb59b1e7bf43dd73649fa686 (diff) | |
| download | php-git-0173c4bab0357e58e74e2a84b18fa31034699582.tar.gz | |
Merge branch 'pull-request/257' into PHP-5.5
* pull-request/257:
array_column: Fix compile-time warnings
array_column: Removed array_pluck() alias
array_column: Set array_pluck as an alias for array_column
array_column: Implement ability to specify an index column
Cleaning up a memory leak.
array_column: Adding test for IS_OBJECT and converting object to string
array_column: Using add_next_index_zval() at nikic's recommendation.
array_column: Improved tests
array_column: Cleaning up, as recommended in pull request #56 comments
Fixing typo in test for array_column()
Simplify the code and use zend_hash_next_index_insert()
Adding test for columns not present in all rows for array_column().
Adding tests for the negative results of array_column()
Implement new array function array_column()
Diffstat (limited to 'ext/standard/array.c')
| -rw-r--r-- | ext/standard/array.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index 54077cd734..226bfefc5b 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2524,6 +2524,121 @@ PHP_FUNCTION(array_count_values) } /* }}} */ +/* {{{ proto array array_column(array input, mixed column_key[, mixed index_key]) + Return the values from a single column in the input array, identified by the + value_key and optionally indexed by the index_key */ +PHP_FUNCTION(array_column) +{ + zval *zarray, *zcolumn, *zkey = NULL, **data, **zcolval, **zkeyval; + HashTable *arr_hash; + HashPosition pointer; + ulong column_idx = 0, key_idx = 0; + char *column = NULL, *key = NULL, *keyval = NULL; + int column_len = 0, key_len = 0, keyval_idx = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|z", &zarray, &zcolumn, &zkey) == FAILURE) { + return; + } + + switch (Z_TYPE_P(zcolumn)) { + case IS_NULL: + column_idx = 0; + break; + case IS_LONG: + column_idx = Z_LVAL_P(zcolumn); + break; + case IS_STRING: + column = Z_STRVAL_P(zcolumn); + column_len = Z_STRLEN_P(zcolumn); + break; + case IS_OBJECT: + convert_to_string(zcolumn); + column = Z_STRVAL_P(zcolumn); + column_len = Z_STRLEN_P(zcolumn); + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The column key should be either a string or an integer"); + RETURN_FALSE; + } + + if (zkey) { + switch (Z_TYPE_P(zkey)) { + case IS_NULL: + key_idx = 0; + break; + case IS_LONG: + key_idx = Z_LVAL_P(zkey); + break; + case IS_STRING: + key = Z_STRVAL_P(zkey); + key_len = Z_STRLEN_P(zkey); + break; + case IS_OBJECT: + convert_to_string(zkey); + key = Z_STRVAL_P(zkey); + key_len = Z_STRLEN_P(zkey); + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The index key should be either a string or an integer"); + RETURN_FALSE; + } + } + + arr_hash = Z_ARRVAL_P(zarray); + array_init(return_value); + + 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 (column && zend_hash_find(Z_ARRVAL_PP(data), column, column_len + 1, (void**)&zcolval) == FAILURE) { + continue; + } else if (!column && zend_hash_index_find(Z_ARRVAL_PP(data), column_idx, (void**)&zcolval) == FAILURE) { + continue; + } + + Z_ADDREF_PP(zcolval); + + keyval = NULL; + keyval_idx = -1; + + if (zkey) { + if (key && zend_hash_find(Z_ARRVAL_PP(data), key, key_len + 1, (void**)&zkeyval) == FAILURE) { + keyval_idx = -1; + } else if (!key && zend_hash_index_find(Z_ARRVAL_PP(data), key_idx, (void**)&zkeyval) == FAILURE) { + keyval_idx = -1; + } else { + switch (Z_TYPE_PP(zkeyval)) { + case IS_LONG: + keyval_idx = Z_LVAL_PP(zkeyval); + break; + case IS_STRING: + keyval = Z_STRVAL_PP(zkeyval); + break; + case IS_OBJECT: + convert_to_string(*zkeyval); + keyval = Z_STRVAL_PP(zkeyval); + break; + default: + keyval_idx = -1; + } + } + } + + if (keyval) { + add_assoc_zval(return_value, keyval, *zcolval); + } else if (keyval_idx != -1) { + add_index_zval(return_value, keyval_idx, *zcolval); + } else { + add_next_index_zval(return_value, *zcolval); + } + } + + } +} +/* }}} */ + /* {{{ 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) |
