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

Reply via email to