@@ -5915,65 +5915,70 @@ PHP_FUNCTION(array_rand)
59155915}
59165916/* }}} */
59175917
5918- /* {{{ Returns the sum of the array entries */
5919- PHP_FUNCTION ( array_sum )
5918+ /* Wrapper for array_sum and array_product */
5919+ static void php_array_binop ( INTERNAL_FUNCTION_PARAMETERS , const char * op_name , binary_op_type op , zend_long initial )
59205920{
5921- zval * input ,
5922- * entry ,
5923- entry_n ;
5921+ HashTable * input ;
5922+ zval * entry ;
59245923
59255924 ZEND_PARSE_PARAMETERS_START (1 , 1 )
5926- Z_PARAM_ARRAY (input )
5925+ Z_PARAM_ARRAY_HT (input )
59275926 ZEND_PARSE_PARAMETERS_END ();
59285927
5929- ZVAL_LONG (return_value , 0 );
5928+ if (zend_hash_num_elements (input ) == 0 ) {
5929+ RETURN_LONG (initial );
5930+ }
5931+
5932+ ZVAL_LONG (return_value , initial );
5933+ ZEND_HASH_FOREACH_VAL (input , entry ) {
5934+ /* For objects we try to cast them to a numeric type */
5935+ if (Z_TYPE_P (entry ) == IS_OBJECT ) {
5936+ zval dst ;
5937+ zend_result status = Z_OBJ_HT_P (entry )-> cast_object (Z_OBJ_P (entry ), & dst , _IS_NUMBER );
59305938
5931- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (input ), entry ) {
5932- if (Z_TYPE_P (entry ) == IS_ARRAY || Z_TYPE_P (entry ) == IS_OBJECT ) {
5939+ /* Do not type error for BC */
5940+ if (status == FAILURE || (Z_TYPE (dst ) != IS_LONG && Z_TYPE (dst ) != IS_DOUBLE )) {
5941+ php_error_docref (NULL , E_WARNING , "%s is not supported on type %s" ,
5942+ op_name , zend_zval_type_name (entry ));
5943+ continue ;
5944+ }
5945+ op (return_value , return_value , & dst );
59335946 continue ;
59345947 }
5935- ZVAL_COPY (& entry_n , entry );
5936- convert_scalar_to_number (& entry_n );
5937- fast_add_function (return_value , return_value , & entry_n );
5948+
5949+ zend_result status = op (return_value , return_value , entry );
5950+ if (status == FAILURE ) {
5951+ ZEND_ASSERT (EG (exception ));
5952+ zend_clear_exception ();
5953+ /* BC resources: previously resources were cast to int */
5954+ if (Z_TYPE_P (entry ) == IS_RESOURCE ) {
5955+ zval tmp ;
5956+ ZVAL_LONG (& tmp , Z_RES_HANDLE_P (entry ));
5957+ op (return_value , return_value , & tmp );
5958+ }
5959+ /* BC non numeric strings: previously were cast to 0 */
5960+ else if (Z_TYPE_P (entry ) == IS_STRING ) {
5961+ zval tmp ;
5962+ ZVAL_LONG (& tmp , 0 );
5963+ op (return_value , return_value , & tmp );
5964+ }
5965+ php_error_docref (NULL , E_WARNING , "%s is not supported on type %s" ,
5966+ op_name , zend_zval_type_name (entry ));
5967+ }
59385968 } ZEND_HASH_FOREACH_END ();
59395969}
5970+
5971+ /* {{{ Returns the sum of the array entries */
5972+ PHP_FUNCTION (array_sum )
5973+ {
5974+ php_array_binop (INTERNAL_FUNCTION_PARAM_PASSTHRU , "Addition" , add_function , 0 );
5975+ }
59405976/* }}} */
59415977
59425978/* {{{ Returns the product of the array entries */
59435979PHP_FUNCTION (array_product )
59445980{
5945- zval * input ,
5946- * entry ,
5947- entry_n ;
5948- double dval ;
5949-
5950- ZEND_PARSE_PARAMETERS_START (1 , 1 )
5951- Z_PARAM_ARRAY (input )
5952- ZEND_PARSE_PARAMETERS_END ();
5953-
5954- ZVAL_LONG (return_value , 1 );
5955- if (!zend_hash_num_elements (Z_ARRVAL_P (input ))) {
5956- return ;
5957- }
5958-
5959- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (input ), entry ) {
5960- if (Z_TYPE_P (entry ) == IS_ARRAY || Z_TYPE_P (entry ) == IS_OBJECT ) {
5961- continue ;
5962- }
5963- ZVAL_COPY (& entry_n , entry );
5964- convert_scalar_to_number (& entry_n );
5965-
5966- if (Z_TYPE (entry_n ) == IS_LONG && Z_TYPE_P (return_value ) == IS_LONG ) {
5967- dval = (double )Z_LVAL_P (return_value ) * (double )Z_LVAL (entry_n );
5968- if ( (double )ZEND_LONG_MIN <= dval && dval <= (double )ZEND_LONG_MAX ) {
5969- Z_LVAL_P (return_value ) *= Z_LVAL (entry_n );
5970- continue ;
5971- }
5972- }
5973- convert_to_double (return_value );
5974- convert_to_double (& entry_n );
5975- Z_DVAL_P (return_value ) *= Z_DVAL (entry_n );
5976- } ZEND_HASH_FOREACH_END ();
5981+ php_array_binop (INTERNAL_FUNCTION_PARAM_PASSTHRU , "Multiplication" , mul_function , 1 );
59775982}
59785983/* }}} */
59795984
0 commit comments