@@ -4593,7 +4593,7 @@ PHP_FUNCTION(array_count_values)
45934593}
45944594/* }}} */
45954595
4596- static inline zval * array_column_fetch_prop (zval * data , zend_string * name_str , zend_long name_long , void * * cache_slot , zval * rv ) /* {{{ */
4596+ static inline zval * array_column_fetch_prop (zval * data , zend_string * name_str , zend_long name_long , bool is_string_key , void * * cache_slot , zval * rv ) /* {{{ */
45974597{
45984598 zval * prop = NULL ;
45994599
@@ -4620,9 +4620,8 @@ static inline zval *array_column_fetch_prop(zval *data, zend_string *name_str, z
46204620 }
46214621 zend_string_release (tmp_str );
46224622 } else if (Z_TYPE_P (data ) == IS_ARRAY ) {
4623- /* Name is a string */
4624- if (name_str != NULL ) {
4625- prop = zend_symtable_find (Z_ARRVAL_P (data ), name_str );
4623+ if (is_string_key ) {
4624+ prop = zend_hash_find (Z_ARRVAL_P (data ), name_str );
46264625 } else {
46274626 prop = zend_hash_index_find (Z_ARRVAL_P (data ), name_long );
46284627 }
@@ -4656,38 +4655,62 @@ PHP_FUNCTION(array_column)
46564655 Z_PARAM_STR_OR_LONG_OR_NULL (index_str , index_long , index_is_null )
46574656 ZEND_PARSE_PARAMETERS_END ();
46584657
4659- void * cache_slot_column [3 ] = { NULL , NULL , NULL };
4660- void * cache_slot_index [3 ] = { NULL , NULL , NULL };
4658+ uint32_t num_elements = zend_hash_num_elements (input );
4659+ if (num_elements == 0 ) {
4660+ RETURN_EMPTY_ARRAY ();
4661+ }
4662+
4663+ if (column_is_null && index_is_null ) {
4664+ array_init_size (return_value , num_elements );
4665+ zend_hash_real_init_packed (Z_ARRVAL_P (return_value ));
4666+ ZEND_HASH_FILL_PACKED (Z_ARRVAL_P (return_value )) {
4667+ ZEND_HASH_FOREACH_VAL (input , data ) {
4668+ ZVAL_DEREF (data );
4669+ Z_TRY_ADDREF_P (data );
4670+ ZEND_HASH_FILL_ADD (data );
4671+ } ZEND_HASH_FOREACH_END ();
4672+ } ZEND_HASH_FILL_END ();
4673+ return ;
4674+ }
4675+
4676+ /* Normalize array keys once, retaining the original names for object properties. */
4677+ zend_ulong column_index = (zend_ulong ) column_long ;
4678+ bool column_is_string_key = column_str && !ZEND_HANDLE_NUMERIC (column_str , column_index );
4679+ column_long = (zend_long ) column_index ;
4680+ void * cache_slot_column [3 ] = { NULL , NULL , NULL };
46614681
4662- array_init_size (return_value , zend_hash_num_elements (input )) ;
46634682 /* Index param is not passed */
46644683 if (index_is_null ) {
4684+ array_init_size (return_value , num_elements );
46654685 zend_hash_real_init_packed (Z_ARRVAL_P (return_value ));
46664686 ZEND_HASH_FILL_PACKED (Z_ARRVAL_P (return_value )) {
46674687 ZEND_HASH_FOREACH_VAL (input , data ) {
46684688 ZVAL_DEREF (data );
4669- if (column_is_null ) {
4670- Z_TRY_ADDREF_P (data );
4671- colval = data ;
4672- } else if ((colval = array_column_fetch_prop (data , column_str , column_long , cache_slot_column , & rv )) == NULL ) {
4689+ if ((colval = array_column_fetch_prop (data , column_str , column_long , column_is_string_key , cache_slot_column , & rv )) == NULL ) {
46734690 continue ;
46744691 }
46754692 ZEND_HASH_FILL_ADD (colval );
46764693 } ZEND_HASH_FOREACH_END ();
46774694 } ZEND_HASH_FILL_END ();
46784695 } else {
4696+ zend_ulong index = (zend_ulong ) index_long ;
4697+ bool index_is_string_key = index_str && !ZEND_HANDLE_NUMERIC (index_str , index );
4698+ index_long = (zend_long ) index ;
4699+ void * cache_slot_index [3 ] = { NULL , NULL , NULL };
4700+
4701+ array_init_size (return_value , num_elements );
46794702 ZEND_HASH_FOREACH_VAL (input , data ) {
46804703 ZVAL_DEREF (data );
46814704
46824705 if (column_is_null ) {
46834706 Z_TRY_ADDREF_P (data );
46844707 colval = data ;
4685- } else if ((colval = array_column_fetch_prop (data , column_str , column_long , cache_slot_column , & rv )) == NULL ) {
4708+ } else if ((colval = array_column_fetch_prop (data , column_str , column_long , column_is_string_key , cache_slot_column , & rv )) == NULL ) {
46864709 continue ;
46874710 }
46884711
46894712 zval rv ;
4690- zval * keyval = array_column_fetch_prop (data , index_str , index_long , cache_slot_index , & rv );
4713+ zval * keyval = array_column_fetch_prop (data , index_str , index_long , index_is_string_key , cache_slot_index , & rv );
46914714 if (keyval ) {
46924715 array_set_zval_key (Z_ARRVAL_P (return_value ), keyval , colval );
46934716 zval_ptr_dtor (colval );
0 commit comments