Skip to content

Commit 4fa2111

Browse files
committed
Value pass to callback behavior consistently with get
(GET_EXTENED return array)
1 parent 155a864 commit 4fa2111

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

php_memcached.c

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by
386386
static 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 */
392392
typedef 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

752752
static
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);

tests/experimental/getmulti_bykey.phpt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ $m->set('foo', 1, 10);
1111
$m->set('bar', 2, 10);
1212
$m->delete('baz');
1313

14-
$cas = array();
15-
var_dump($m->getMultiByKey('foo', array('foo', 'bar', 'baz'), $cas, Memcached::GET_PRESERVE_ORDER));
14+
var_dump($m->getMultiByKey('foo', array('foo', 'bar', 'baz'), Memcached::GET_PRESERVE_ORDER));
1615
echo $m->getResultMessage(), "\n";
1716

18-
$cas = array();
19-
var_dump($m->getMultiByKey('foo', array(), $cas, Memcached::GET_PRESERVE_ORDER));
17+
var_dump($m->getMultiByKey('foo', array(), Memcached::GET_PRESERVE_ORDER));
2018
echo $m->getResultMessage(), "\n";
2119

2220
--EXPECT--

0 commit comments

Comments
 (0)