Permalink
Browse files

Merge branch 'PHP-5.5'

* PHP-5.5:
  NEWS for array_column
  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()
  • Loading branch information...
2 parents fa161e9 + 66b4e5c commit ec26c93eff1959aecce5dcb98221ee85e7d79a28 @dsp dsp committed Mar 20, 2013
View
@@ -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)
@@ -436,6 +436,12 @@ 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, column_key)
+ ZEND_ARG_INFO(0, index_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)
@@ -3323,6 +3329,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)
View
@@ -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);
Oops, something went wrong.

0 comments on commit ec26c93

Please sign in to comment.