diff --git a/memcached-api.php b/memcached-api.php index ecc4072c..45641415 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -185,13 +185,13 @@ class Memcached { public function __construct( $persistent_id = '', $on_new_object_cb = null ) {} - public function get( $key, $cache_cb = null, &$cas_token = null ) {} + public function get( $key, $cache_cb = null, &$cas_token = null, &$udf_flags = null ) {} - public function getByKey( $server_key, $key, $cache_cb = null, &$cas_token = null ) {} + public function getByKey( $server_key, $key, $cache_cb = null, &$cas_token = null, &$udf_flags = null ) {} - public function getMulti( array $keys, &$cas_tokens = null, $flags = 0 ) {} + public function getMulti( array $keys, &$cas_tokens = null, $flags = 0, &$udf_flags = null ) {} - public function getMultiByKey( $server_key, array $keys, &$cas_tokens = null, $flags = 0 ) {} + public function getMultiByKey( $server_key, array $keys, &$cas_tokens = null, $flags = 0, &$udf_flags = null ) {} public function getDelayed( array $keys, $with_cas = null, $value_cb = null ) {} @@ -201,25 +201,25 @@ public function fetch( ) {} public function fetchAll( ) {} - public function set( $key, $value, $expiration = 0 ) {} + public function set( $key, $value, $expiration = 0, $udf_flags = 0 ) {} public function touch( $key, $expiration = 0 ) {} public function touchbyKey( $key, $expiration = 0 ) {} - public function setByKey( $server_key, $key, $value, $expiration = 0 ) {} + public function setByKey( $server_key, $key, $value, $expiration = 0, $udf_flags = 0 ) {} - public function setMulti( array $items, $expiration = 0 ) {} + public function setMulti( array $items, $expiration = 0, $udf_flags = 0 ) {} - public function setMultiByKey( $server_key, array $items, $expiration = 0 ) {} + public function setMultiByKey( $server_key, array $items, $expiration = 0, $udf_flags = 0 ) {} - public function cas( $token, $key, $value, $expiration = 0 ) {} + public function cas( $token, $key, $value, $expiration = 0, $udf_flags = 0 ) {} - public function casByKey( $token, $server_key, $key, $value, $expiration = 0 ) {} + public function casByKey( $token, $server_key, $key, $value, $expiration = 0, $udf_flags = 0 ) {} - public function add( $key, $value, $expiration = 0 ) {} + public function add( $key, $value, $expiration = 0, $udf_flags = 0 ) {} - public function addByKey( $server_key, $key, $value, $expiration = 0 ) {} + public function addByKey( $server_key, $key, $value, $expiration = 0, $udf_flags = 0 ) {} public function append( $key, $value ) {} @@ -229,9 +229,9 @@ public function prepend( $key, $value ) {} public function prependByKey( $server_key, $key, $value ) {} - public function replace( $key, $value, $expiration = 0 ) {} + public function replace( $key, $value, $expiration = 0, $udf_flags = 0 ) {} - public function replaceByKey( $server_key, $key, $value, $expiration = 0 ) {} + public function replaceByKey( $server_key, $key, $value, $expiration = 0, $udf_flags = 0 ) {} public function delete( $key, $time = 0 ) {} diff --git a/php_memcached.c b/php_memcached.c index 4074e591..c3f1874b 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -136,6 +136,13 @@ typedef unsigned long int uint32_t; #define MEMC_VAL_COMPRESSION_ZLIB (1<<5) #define MEMC_VAL_COMPRESSION_FASTLZ (1<<6) +/**************************************** + User-defined flags +****************************************/ +#define MEMC_UDF_MASK 0xff00 +#define MEMC_UDF_GET(flags) ((long)(flags & MEMC_UDF_MASK)>>8) +#define MEMC_UDF_SET(flags, udf_flags) ((flags) |= ((udf_flags<<8) & MEMC_UDF_MASK)) + /**************************************** "get" operation flags ****************************************/ @@ -507,7 +514,7 @@ static PHP_METHOD(Memcached, __construct) } /* }}} */ -/* {{{ Memcached::get(string key [, mixed callback [, double &cas_token ] ]) +/* {{{ Memcached::get(string key [, mixed callback [, double &cas_token [, int &udf_flags ] ] ]) Returns a value for the given key or false */ PHP_METHOD(Memcached, get) { @@ -515,7 +522,7 @@ PHP_METHOD(Memcached, get) } /* }}} */ -/* {{{ Memcached::getByKey(string server_key, string key [, mixed callback [, double &cas_token ] ]) +/* {{{ Memcached::getByKey(string server_key, string key [, mixed callback [, double &cas_token [, int &udf_flags ] ] ]) Returns a value for key from the server identified by the server key or false */ PHP_METHOD(Memcached, getByKey) { @@ -537,6 +544,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) const char* keys[1] = { NULL }; size_t key_lens[1] = { 0 }; zval *cas_token = NULL; + zval *udf_flags = NULL; zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; memcached_result_st result; @@ -544,13 +552,13 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|f!z", &server_key, - &server_key_len, &key, &key_len, &fci, &fcc, &cas_token) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|f!zz", &server_key, + &server_key_len, &key, &key_len, &fci, &fcc, &cas_token, &udf_flags) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|f!z", &key, &key_len, - &fci, &fcc, &cas_token) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|f!zz", &key, &key_len, + &fci, &fcc, &cas_token, &udf_flags) == FAILURE) { return; } } @@ -572,13 +580,13 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) /* * Enable CAS support, but only if it is currently disabled. */ - if (cas_token && orig_cas_flag == 0) { + if (cas_token && PZVAL_IS_REF(cas_token) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); } status = memcached_mget_by_key(m_obj->memc, server_key, server_key_len, keys, key_lens, 1); - if (cas_token && orig_cas_flag == 0) { + if (cas_token && PZVAL_IS_REF(cas_token) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); } @@ -642,11 +650,16 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) ZVAL_DOUBLE(cas_token, (double)cas); } + if (udf_flags) { + zval_dtor(udf_flags); + ZVAL_LONG(udf_flags, MEMC_UDF_GET(flags)); + } + memcached_result_free(&result); } /* }}} */ -/* {{{ Memcached::getMulti(array keys [, array &cas_tokens ]) +/* {{{ Memcached::getMulti(array keys [, array &cas_tokens [, array &udf_flags ] ]) Returns values for the given keys or false */ PHP_METHOD(Memcached, getMulti) { @@ -654,7 +667,7 @@ PHP_METHOD(Memcached, getMulti) } /* }}} */ -/* {{{ Memcached::getMultiByKey(string server_key, array keys [, array &cas_tokens ]) +/* {{{ Memcached::getMultiByKey(string server_key, array keys [, array &cas_tokens [, array &udf_flags ] ]) Returns values for the given keys from the server identified by the server key or false */ PHP_METHOD(Memcached, getMultiByKey) { @@ -679,6 +692,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke uint32_t flags; uint64_t cas = 0; zval *cas_tokens = NULL; + zval *udf_flags = NULL; uint64_t orig_cas_flag; zval *value; long get_flags = 0; @@ -689,12 +703,12 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|zl", &server_key, - &server_key_len, &keys, &cas_tokens, &get_flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/|zlz", &server_key, + &server_key_len, &keys, &cas_tokens, &get_flags, &udf_flags) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|zl", &keys, &cas_tokens, &get_flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/|zlz", &keys, &cas_tokens, &get_flags, &udf_flags) == FAILURE) { return; } } @@ -741,7 +755,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke /* * Enable CAS support, but only if it is currently disabled. */ - if (cas_tokens) { + if (cas_tokens && PZVAL_IS_REF(cas_tokens)) { orig_cas_flag = memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS); if (orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1); @@ -755,7 +769,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke /* * Restore the CAS support flag, but only if we had to turn it on. */ - if (cas_tokens && orig_cas_flag == 0) { + if (cas_tokens && PZVAL_IS_REF(cas_tokens) && orig_cas_flag == 0) { memcached_behavior_set(m_obj->memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, orig_cas_flag); } @@ -767,8 +781,26 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke * returned as doubles, because we cannot store potential 64-bit values in longs. */ if (cas_tokens) { - zval_dtor(cas_tokens); - array_init(cas_tokens); + if (PZVAL_IS_REF(cas_tokens)) { + // cas_tokens was passed by reference, we'll create an array for it. + zval_dtor(cas_tokens); + array_init(cas_tokens); + } else { + // Not pased by reference, we allow this (eg.: if you specify null + // to not enable cas but you want to use the udf_flags parameter). + // We destruct it and set it to null for the peace of mind. + zval_dtor(cas_tokens); + cas_tokens = NULL; + } + } + + /* + * Iterate through the result set and create the result array. The flags are + * returned as longs. + */ + if (udf_flags) { + zval_dtor(udf_flags); + array_init(udf_flags); } memcached_result_create(m_obj->memc, &result); @@ -816,6 +848,9 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke cas = memcached_result_cas(&result); add_assoc_double_ex(cas_tokens, res_key, res_key_len+1, (double)cas); } + if (udf_flags) { + add_assoc_long_ex(udf_flags, res_key, res_key_len+1, MEMC_UDF_GET(flags)); + } } memcached_result_free(&result); @@ -826,6 +861,10 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke zval_dtor(cas_tokens); ZVAL_NULL(cas_tokens); } + if (udf_flags) { + zval_dtor(udf_flags); + ZVAL_NULL(udf_flags); + } zval_dtor(return_value); RETURN_FALSE; } @@ -1022,6 +1061,9 @@ PHP_METHOD(Memcached, fetch) /* XXX: also check against ULLONG_MAX or memc_behavior */ add_assoc_double_ex(return_value, ZEND_STRS("cas"), (double)cas); } + if ((flags & MEMC_UDF_MASK) != 0) { + add_assoc_long_ex(return_value, ZEND_STRS("flags"), MEMC_UDF_GET(flags)); + } memcached_result_free(&result); } @@ -1078,6 +1120,9 @@ PHP_METHOD(Memcached, fetchAll) /* XXX: also check against ULLONG_MAX or memc_behavior */ add_assoc_double_ex(entry, ZEND_STRS("cas"), (double)cas); } + if ((flags & MEMC_UDF_MASK) != 0) { + add_assoc_long_ex(entry, ZEND_STRS("flags"), MEMC_UDF_GET(flags)); + } add_next_index_zval(return_value, entry); } @@ -1090,7 +1135,7 @@ PHP_METHOD(Memcached, fetchAll) } /* }}} */ -/* {{{ Memcached::set(string key, mixed value [, int expiration ]) +/* {{{ Memcached::set(string key, mixed value [, int expiration [, int udf_flags ] ]) Sets the value for the given key */ PHP_METHOD(Memcached, set) { @@ -1098,7 +1143,7 @@ PHP_METHOD(Memcached, set) } /* }}} */ -/* {{{ Memcached::setByKey(string server_key, string key, mixed value [, int expiration ]) +/* {{{ Memcached::setByKey(string server_key, string key, mixed value [, int expiration [, int udf_flags ] ]) Sets the value for the given key on the server identified by the server key */ PHP_METHOD(Memcached, setByKey) { @@ -1125,7 +1170,7 @@ PHP_METHOD(Memcached, touchByKey) #endif -/* {{{ Memcached::setMulti(array items [, int expiration ]) +/* {{{ Memcached::setMulti(array items [, int expiration [, int udf_flags ] ]) Sets the keys/values specified in the items array */ PHP_METHOD(Memcached, setMulti) { @@ -1133,7 +1178,7 @@ PHP_METHOD(Memcached, setMulti) } /* }}} */ -/* {{{ Memcached::setMultiByKey(string server_key, array items [, int expiration ]) +/* {{{ Memcached::setMultiByKey(string server_key, array items [, int expiration [, int udf_flags ] ]) Sets the keys/values specified in the items array on the server identified by the given server key */ PHP_METHOD(Memcached, setMultiByKey) { @@ -1173,6 +1218,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke char *server_key = NULL; int server_key_len = 0; time_t expiration = 0; + uint32_t udf_flags = 0; zval **entry; char *str_key; uint str_key_len; @@ -1186,12 +1232,12 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|l", &server_key, - &server_key_len, &entries, &expiration) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|ll", &server_key, + &server_key_len, &entries, &expiration, &udf_flags) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &entries, &expiration) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|ll", &entries, &expiration, &udf_flags) == FAILURE) { return; } } @@ -1199,6 +1245,16 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke MEMC_METHOD_FETCH_OBJECT; i_obj->rescode = MEMCACHED_SUCCESS; + /* + * php_memcached uses 8 bits internally to store type, compression and serialization info. + * We use 8 upper bits to store user defined flags. + */ + if (udf_flags > 0) { + if (udf_flags > (MEMC_UDF_MASK>>8)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "udf_flags will be limited to %d", (MEMC_UDF_MASK>>8)); + } + } + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(entries)); zend_hash_get_current_data(Z_ARRVAL_P(entries), (void**)&entry) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(entries))) { @@ -1221,6 +1277,10 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke flags |= MEMC_VAL_COMPRESSED; } + if (udf_flags > 0) { + MEMC_UDF_SET(flags, udf_flags); + } + payload = php_memc_zval_to_payload(*entry, &payload_len, &flags, m_obj->serializer, m_obj->compression_type TSRMLS_CC); if (payload == NULL) { i_obj->rescode = MEMC_RES_PAYLOAD_FAILURE; @@ -1246,7 +1306,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke } /* }}} */ -/* {{{ Memcached::add(string key, mixed value [, int expiration ]) +/* {{{ Memcached::add(string key, mixed value [, int expiration [, int udf_flags ] ]) Sets the value for the given key, failing if the key already exists */ PHP_METHOD(Memcached, add) { @@ -1254,7 +1314,7 @@ PHP_METHOD(Memcached, add) } /* }}} */ -/* {{{ Memcached::addByKey(string server_key, string key, mixed value [, int expiration ]) +/* {{{ Memcached::addByKey(string server_key, string key, mixed value [, int expiration [, int udf_flags ] ]) Sets the value for the given key on the server identified by the sever key, failing if the key already exists */ PHP_METHOD(Memcached, addByKey) { @@ -1294,7 +1354,7 @@ PHP_METHOD(Memcached, prependByKey) } /* }}} */ -/* {{{ Memcached::replace(string key, mixed value [, int expiration ]) +/* {{{ Memcached::replace(string key, mixed value [, int expiration [, int udf_flags ] ]) Replaces the value for the given key, failing if the key doesn't exist */ PHP_METHOD(Memcached, replace) { @@ -1302,7 +1362,7 @@ PHP_METHOD(Memcached, replace) } /* }}} */ -/* {{{ Memcached::replaceByKey(string server_key, string key, mixed value [, int expiration ]) +/* {{{ Memcached::replaceByKey(string server_key, string key, mixed value [, int expiration [, int udf_flags ] ]) Replaces the value for the given key on the server identified by the server key, failing if the key doesn't exist */ PHP_METHOD(Memcached, replaceByKey) { @@ -1323,6 +1383,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool zval s_zvalue; zval *value; long expiration = 0; + uint32_t udf_flags = 0; char *payload; size_t payload_len; uint32_t flags = 0; @@ -1345,8 +1406,8 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz|l", &server_key, - &server_key_len, &key, &key_len, &value, &expiration) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz|ll", &server_key, + &server_key_len, &key, &key_len, &value, &expiration, &udf_flags) == FAILURE) { return; } } @@ -1365,8 +1426,8 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &key, &key_len, - &value, &expiration) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|ll", &key, &key_len, + &value, &expiration, &udf_flags) == FAILURE) { return; } } @@ -1393,6 +1454,18 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool flags |= MEMC_VAL_COMPRESSED; } + /* + * php_memcached uses 8 bits internally to store type, compression and serialization info. + * We use 8 upper bits to store user defined flags. + */ + if (udf_flags > 0) { + if (udf_flags > (MEMC_UDF_MASK>>8)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "udf_flags will be limited to %d", (MEMC_UDF_MASK>>8)); + } + + MEMC_UDF_SET(flags, udf_flags); + } + if (op == MEMC_OP_TOUCH) { #if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000016 if (memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { @@ -1492,6 +1565,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) int server_key_len = 0; zval *value; time_t expiration = 0; + uint32_t udf_flags = 0; char *payload; size_t payload_len; uint32_t flags = 0; @@ -1499,13 +1573,13 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dssz|l", &cas_d, &server_key, - &server_key_len, &key, &key_len, &value, &expiration) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dssz|ll", &cas_d, &server_key, + &server_key_len, &key, &key_len, &value, &expiration, &udf_flags) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dsz|l", &cas_d, &key, &key_len, - &value, &expiration) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dsz|ll", &cas_d, &key, &key_len, + &value, &expiration, &udf_flags) == FAILURE) { return; } } @@ -1524,6 +1598,18 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) flags |= MEMC_VAL_COMPRESSED; } + /* + * php_memcached uses 8 bits internally to store type, compression and serialization info. + * We use 8 upper bits to store user defined flags. + */ + if (udf_flags > 0) { + if (udf_flags > (MEMC_UDF_MASK>>8)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "udf_flags will be limited to %d", (MEMC_UDF_MASK>>8)); + } + + MEMC_UDF_SET(flags, udf_flags); + } + payload = php_memc_zval_to_payload(value, &payload_len, &flags, m_obj->serializer, m_obj->compression_type TSRMLS_CC); if (payload == NULL) { i_obj->rescode = MEMC_RES_PAYLOAD_FAILURE; @@ -1544,7 +1630,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) } /* }}} */ -/* {{{ Memcached::cas(double cas_token, string key, mixed value [, int expiration ]) +/* {{{ Memcached::cas(double cas_token, string key, mixed value [, int expiration [, int udf_flags ] ]) Sets the value for the given key, failing if the cas_token doesn't match the one in memcache */ PHP_METHOD(Memcached, cas) { @@ -1552,7 +1638,7 @@ PHP_METHOD(Memcached, cas) } /* }}} */ -/* {{{ Memcached::casByKey(double cas_token, string server_key, string key, mixed value [, int expiration ]) +/* {{{ Memcached::casByKey(double cas_token, string server_key, string key, mixed value [, int expiration [, int udf_flags ] ]) Sets the value for the given key on the server identified by the server_key, failing if the cas_token doesn't match the one in memcache */ PHP_METHOD(Memcached, casByKey) { @@ -3360,6 +3446,9 @@ static int php_memc_do_result_callback(zval *zmemc_obj, zend_fcall_info *fci, if (cas != 0) { add_assoc_double_ex(z_result, ZEND_STRS("cas"), (double)cas); } + if ((flags & MEMC_UDF_MASK) != 0) { + add_assoc_long_ex(z_result, ZEND_STRS("flags"), MEMC_UDF_GET(flags)); + } if (zend_call_function(fci, fcc TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not invoke result callback"); @@ -3391,27 +3480,31 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_get, 0, 0, 1) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, cache_cb) - ZEND_ARG_INFO(1, cas_token) + ZEND_ARG_INFO(2, cas_token) + ZEND_ARG_INFO(1, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_getByKey, 0, 0, 2) ZEND_ARG_INFO(0, server_key) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, cache_cb) - ZEND_ARG_INFO(1, cas_token) + ZEND_ARG_INFO(2, cas_token) + ZEND_ARG_INFO(1, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_getMulti, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(1, cas_tokens) + ZEND_ARG_INFO(2, cas_tokens) ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(1, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_getMultiByKey, 0, 0, 2) ZEND_ARG_INFO(0, server_key) ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(1, cas_tokens) + ZEND_ARG_INFO(2, cas_tokens) ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(1, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayed, 0, 0, 1) @@ -3437,6 +3530,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_set, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_setByKey, 0, 0, 3) @@ -3444,6 +3538,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setByKey, 0, 0, 3) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_touch, 0, 0, 2) @@ -3460,18 +3555,21 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_setMulti, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, items, 0) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_setMultiByKey, 0, 0, 2) ZEND_ARG_INFO(0, server_key) ZEND_ARG_ARRAY_INFO(0, items, 0) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_add, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_addByKey, 0, 0, 3) @@ -3479,12 +3577,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_addByKey, 0, 0, 3) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_replace, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_replaceByKey, 0, 0, 3) @@ -3492,6 +3592,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_replaceByKey, 0, 0, 3) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 2) @@ -3525,6 +3626,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_cas, 0, 0, 3) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_casByKey, 0, 0, 4) @@ -3533,6 +3635,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_casByKey, 0, 0, 4) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) ZEND_ARG_INFO(0, expiration) + ZEND_ARG_INFO(0, udf_flags) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_delete, 0, 0, 1) diff --git a/tests/cas.phpt b/tests/cas.phpt index fc14842b..09b436e0 100644 --- a/tests/cas.phpt +++ b/tests/cas.phpt @@ -30,6 +30,25 @@ if ($v !== 11) { echo "Wanted cas_test to be 11, value is: "; var_dump($v); } + +$v = $m->get('cas_test', null, 2); +if ($v != 11) { + echo "Failed to get the value with \$cas_token passed by value (2)\n"; + return; +} + +$v = $m->get('cas_test', null, null); +if ($v != 11) { + echo "Failed to get the value with \$cas_token passed by value (null)\n"; + return; +} + +$v = $m->get('cas_test', null, $data = array(2, 4)); +if ($v != 11 || $data !== array(2, 4)) { + echo "Failed to get the value with \$cas_token passed by value (\$data = array(2, 4))\n"; + return; +} + echo "OK\n"; ?> --EXPECT-- diff --git a/tests/cas_multi.phpt b/tests/cas_multi.phpt index d180d779..e4c9e0f3 100644 --- a/tests/cas_multi.phpt +++ b/tests/cas_multi.phpt @@ -45,6 +45,33 @@ foreach ($data as $key => $v) { } } +if (array_keys($actual) !== array_keys($data)) { + echo "missing value(s)\n"; + echo "data :"; + var_dump($data); + echo "actual data: "; + var_dump($actual); + return; +} + +$actual = $m->getMulti(array_keys($data), 2); +if (array_keys($actual) !== array_keys($data)) { + echo "Failed to getMulti \$cas_token passed by value (2)\n"; + return; +} + +$actual = $m->getMulti(array_keys($data), null); +if (array_keys($actual) !== array_keys($data)) { + echo "Failed to getMulti \$cas_token passed by value (null)\n"; + return; +} + +$actual = $m->getMulti(array_keys($data), $cas_tokens = array(2, 4)); +if (array_keys($actual) !== array_keys($data) || $cas_tokens !== array(2, 4)) { + echo "Failed to getMulti \$cas_token passed by value (\$cas_tokens = array(2, 4))\n"; + return; +} + echo "OK\n"; ?>