summaryrefslogtreecommitdiff
path: root/ext/standard/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r--ext/standard/array.c88
1 files changed, 33 insertions, 55 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 09756b74e5..3e54946cd0 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -4083,47 +4083,24 @@ PHP_FUNCTION(array_count_values)
}
/* }}} */
-/* {{{ array_column_param_helper
- * Specialized conversion rules for array_column() function
- */
-static inline
-zend_bool array_column_param_helper(zval *param, int parameter_number) {
- switch (Z_TYPE_P(param)) {
- case IS_DOUBLE:
- convert_to_long_ex(param);
- /* fallthrough */
- case IS_LONG:
- return 1;
-
- case IS_OBJECT:
- if (!try_convert_to_string(param)) {
- return 0;
- }
- /* fallthrough */
- case IS_STRING:
- return 1;
-
- default:
- zend_argument_type_error(parameter_number, "must be of type string|int, %s given", zend_zval_type_name(param));
- return 0;
- }
-}
-/* }}} */
-
-static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /* {{{ */
+static inline zval *array_column_fetch_prop(zval *data, zend_string *name_str, zend_long name_long, zval *rv) /* {{{ */
{
zval *prop = NULL;
if (Z_TYPE_P(data) == IS_OBJECT) {
+ zend_string *tmp_str;
+ /* If name is an integer convert integer to string */
+ if (name_str == NULL) {
+ tmp_str = zend_long_to_str(name_long);
+ } else {
+ tmp_str = zend_string_copy(name_str);
+ }
/* The has_property check is first performed in "exists" mode (which returns true for
* properties that are null but exist) and then in "has" mode to handle objects that
* implement __isset (which is not called in "exists" mode). */
- zend_string *str, *tmp_str;
-
- str = zval_get_tmp_string(name, &tmp_str);
- if (Z_OBJ_HANDLER_P(data, has_property)(Z_OBJ_P(data), str, ZEND_PROPERTY_EXISTS, NULL)
- || Z_OBJ_HANDLER_P(data, has_property)(Z_OBJ_P(data), str, ZEND_PROPERTY_ISSET, NULL)) {
- prop = Z_OBJ_HANDLER_P(data, read_property)(Z_OBJ_P(data), str, BP_VAR_R, NULL, rv);
+ if (Z_OBJ_HANDLER_P(data, has_property)(Z_OBJ_P(data), tmp_str, ZEND_PROPERTY_EXISTS, NULL)
+ || Z_OBJ_HANDLER_P(data, has_property)(Z_OBJ_P(data), tmp_str, ZEND_PROPERTY_ISSET, NULL)) {
+ prop = Z_OBJ_HANDLER_P(data, read_property)(Z_OBJ_P(data), tmp_str, BP_VAR_R, NULL, rv);
if (prop) {
ZVAL_DEREF(prop);
if (prop != rv) {
@@ -4131,12 +4108,13 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
}
}
}
- zend_tmp_string_release(tmp_str);
+ zend_string_release(tmp_str);
} else if (Z_TYPE_P(data) == IS_ARRAY) {
- if (Z_TYPE_P(name) == IS_STRING) {
- prop = zend_symtable_find(Z_ARRVAL_P(data), Z_STR_P(name));
- } else if (Z_TYPE_P(name) == IS_LONG) {
- prop = zend_hash_index_find(Z_ARRVAL_P(data), Z_LVAL_P(name));
+ /* Name is a string */
+ if (name_str != NULL) {
+ prop = zend_symtable_find(Z_ARRVAL_P(data), name_str);
+ } else {
+ prop = zend_hash_index_find(Z_ARRVAL_P(data), name_long);
}
if (prop) {
ZVAL_DEREF(prop);
@@ -4144,42 +4122,42 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
}
}
-
return prop;
}
/* }}} */
-/* {{{ proto array array_column(array input, mixed column_key[, mixed index_key])
+/* {{{ proto array array_column(array input, string|int|null column_key[, string|int|null 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)
{
HashTable *input;
zval *colval, *data, rv;
- zval *column = NULL, *index = NULL;
+ zend_string *column_str = NULL;
+ zend_long column_long;
+ zend_bool column_is_null = 0;
+ zend_string *index_str = NULL;
+ zend_long index_long;
+ zend_bool index_is_null = 1;
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_ARRAY_HT(input)
- Z_PARAM_ZVAL_EX(column, 1, 0)
+ Z_PARAM_STR_OR_LONG_OR_NULL(column_str, column_long, column_is_null)
Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL_EX(index, 1, 0)
+ Z_PARAM_STR_OR_LONG_OR_NULL(index_str, index_long, index_is_null)
ZEND_PARSE_PARAMETERS_END();
- if ((column && !array_column_param_helper(column, 2)) ||
- (index && !array_column_param_helper(index, 3))) {
- RETURN_THROWS();
- }
-
array_init_size(return_value, zend_hash_num_elements(input));
- if (!index) {
+ /* Index param is not passed */
+ if (index_is_null) {
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
ZEND_HASH_FOREACH_VAL(input, data) {
ZVAL_DEREF(data);
- if (!column) {
+ if (column_is_null) {
Z_TRY_ADDREF_P(data);
colval = data;
- } else if ((colval = array_column_fetch_prop(data, column, &rv)) == NULL) {
+ } else if ((colval = array_column_fetch_prop(data, column_str, column_long, &rv)) == NULL) {
continue;
}
ZEND_HASH_FILL_ADD(colval);
@@ -4189,10 +4167,10 @@ PHP_FUNCTION(array_column)
ZEND_HASH_FOREACH_VAL(input, data) {
ZVAL_DEREF(data);
- if (!column) {
+ if (column_is_null) {
Z_TRY_ADDREF_P(data);
colval = data;
- } else if ((colval = array_column_fetch_prop(data, column, &rv)) == NULL) {
+ } else if ((colval = array_column_fetch_prop(data, column_str, column_long, &rv)) == NULL) {
continue;
}
@@ -4200,7 +4178,7 @@ PHP_FUNCTION(array_column)
* which is to append the value as next_index
*/
zval rv;
- zval *keyval = array_column_fetch_prop(data, index, &rv);
+ zval *keyval = array_column_fetch_prop(data, index_str, index_long, &rv);
if (keyval) {
switch (Z_TYPE_P(keyval)) {