@@ -386,7 +386,7 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by
386386static void php_memc_getDelayed_impl (INTERNAL_FUNCTION_PARAMETERS , zend_bool by_key );
387387
388388/* Invoke PHP functions */
389- static zend_bool s_invoke_cache_callback (zval * zobject , zend_fcall_info * fci , zend_fcall_info_cache * fcc , zend_string * key , zval * value );
389+ static zend_bool s_invoke_cache_callback (zval * zobject , zend_fcall_info * fci , zend_fcall_info_cache * fcc , zend_bool with_cas , zend_string * key , zval * value );
390390
391391/* Iterate result sets */
392392typedef zend_bool (* php_memc_result_apply_fn )(php_memc_object_t * intern , zend_string * key , zval * value , zval * cas , uint32_t flags , void * context );
@@ -750,7 +750,7 @@ zend_bool s_invoke_new_instance_cb(zval *object, zend_fcall_info *fci, zend_fcal
750750}
751751
752752static
753- zend_bool s_invoke_cache_callback (zval * zobject , zend_fcall_info * fci , zend_fcall_info_cache * fcc , zend_string * key , zval * value )
753+ zend_bool s_invoke_cache_callback (zval * zobject , zend_fcall_info * fci , zend_fcall_info_cache * fcc , zend_bool with_cas , zend_string * key , zval * value )
754754{
755755 zend_bool status = 0 ;
756756 zval params [4 ];
@@ -759,21 +759,42 @@ zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcal
759759
760760 /* Prepare params */
761761 ZVAL_COPY (& params [0 ], zobject );
762- ZVAL_STR (& params [1 ], zend_string_copy (key )); /* key */
763- ZVAL_NEW_REF (& params [2 ], value ); /* value */
764- ZVAL_NEW_EMPTY_REF (& params [3 ]); /* expiration */
765- ZVAL_NULL (Z_REFVAL (params [3 ]));
762+ ZVAL_STR_COPY (& params [1 ], key ); /* key */
763+ ZVAL_NEW_REF (& params [2 ], value ); /* value */
764+
765+ if (with_cas ) {
766+ fci -> param_count = 3 ;
767+ } else {
768+ ZVAL_NEW_EMPTY_REF (& params [3 ]); /* expiration */
769+ ZVAL_NULL (Z_REFVAL (params [3 ]));
770+ fci -> param_count = 4 ;
771+ }
766772
767773 fci -> retval = & retval ;
768774 fci -> params = params ;
769- fci -> param_count = 4 ;
770775
771776 if (zend_call_function (fci , fcc ) == SUCCESS ) {
772777 if (zend_is_true (& retval )) {
773- time_t expiration = zval_get_long (Z_REFVAL (params [3 ]));
774- status = s_memc_write_zval (intern , MEMC_OP_SET , NULL , key , Z_REFVAL (params [2 ]), expiration );
775- /* memleak? zval_ptr_dtor(value); */
776- ZVAL_COPY (value , Z_REFVAL (params [2 ]));
778+ time_t expiration ;
779+ zval * val = Z_REFVAL (params [2 ]);
780+
781+ if (with_cas ) {
782+ if (Z_TYPE_P (val ) == IS_ARRAY ) {
783+ zval * rv = zend_hash_str_find (Z_ARRVAL_P (val ), "value" , sizeof ("value" ) - 1 );
784+ if (rv ) {
785+ zval * cas = zend_hash_str_find (Z_ARRVAL_P (val ), "cas" , sizeof ("cas" ) - 1 );
786+ expiration = cas ? Z_LVAL_P (cas ) : 0 ;
787+ status = s_memc_write_zval (intern , MEMC_OP_SET , NULL , key , rv , expiration );
788+ }
789+ /* memleak? zval_ptr_dtor(value); */
790+ ZVAL_COPY (value , val );
791+ }
792+ } else {
793+ expiration = zval_get_long (Z_REFVAL (params [3 ]));
794+ status = s_memc_write_zval (intern , MEMC_OP_SET , NULL , key , val , expiration );
795+ /* memleak? zval_ptr_dtor(value); */
796+ ZVAL_COPY (value , val );
797+ }
777798 }
778799 }
779800 else {
@@ -783,7 +804,9 @@ zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcal
783804 zval_ptr_dtor (& params [0 ]);
784805 zval_ptr_dtor (& params [1 ]);
785806 zval_ptr_dtor (& params [2 ]);
786- zval_ptr_dtor (& params [3 ]);
807+ if (!with_cas ) {
808+ zval_ptr_dtor (& params [3 ]);
809+ }
787810 zval_ptr_dtor (& retval );
788811
789812 return status ;
@@ -1408,7 +1431,7 @@ void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
14081431
14091432 if (!mget_status ) {
14101433 if (s_memc_status_has_result_code (intern , MEMCACHED_NOTFOUND ) && fci .size > 0 ) {
1411- status = s_invoke_cache_callback (object , & fci , & fcc , key , return_value );
1434+ status = s_invoke_cache_callback (object , & fci , & fcc , context . extended , key , return_value );
14121435
14131436 if (!status ) {
14141437 zval_ptr_dtor (return_value );
@@ -1488,9 +1511,15 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
14881511 }
14891512
14901513 MEMC_METHOD_FETCH_OBJECT ;
1491- s_memc_set_status (intern , MEMCACHED_SUCCESS , 0 );
14921514
14931515 array_init (return_value );
1516+ if (zend_hash_num_elements (Z_ARRVAL_P (keys )) == 0 ) {
1517+ /* BC compatible */
1518+ s_memc_set_status (intern , MEMCACHED_NOTFOUND , 0 );
1519+ return ;
1520+ }
1521+
1522+ s_memc_set_status (intern , MEMCACHED_SUCCESS , 0 );
14941523
14951524 preserve_order = (flags & MEMC_GET_PRESERVE_ORDER );
14961525 s_hash_to_keys (& keys_out , Z_ARRVAL_P (keys ), preserve_order , return_value );
0 commit comments