diff --git a/config.m4 b/config.m4 index 0c999eab..99989062 100644 --- a/config.m4 +++ b/config.m4 @@ -17,6 +17,9 @@ PHP_ARG_ENABLE(memcached-igbinary, whether to enable memcached igbinary serializ PHP_ARG_ENABLE(memcached-json, whether to enable memcached json serializer support, [ --enable-memcached-json Enable memcached json serializer support], no, no) +PHP_ARG_ENABLE(memcached-sasl, whether to disable memcached sasl support, +[ --disable-memcached-sasl Disable memcached sasl support], no, no) + if test -z "$PHP_ZLIB_DIR"; then PHP_ARG_WITH(zlib-dir, for ZLIB, [ --with-zlib-dir[=DIR] Set the path to ZLIB install prefix.], no) @@ -226,10 +229,12 @@ if test "$PHP_MEMCACHED" != "no"; then fi done fi - - AC_CHECK_HEADERS([sasl/sasl.h], [memcached_enable_sasl="yes"], [memcached_enable_sasl="no"]) - AC_MSG_CHECKING([whether to enable sasl support]) - AC_MSG_RESULT([$memcached_enable_sasl]) + + if test "$PHP_MEMCACHED_SASL" != "no"; then + AC_CHECK_HEADERS([sasl/sasl.h], [memcached_enable_sasl="yes"], [memcached_enable_sasl="no"]) + AC_MSG_CHECKING([whether to enable sasl support]) + AC_MSG_RESULT([$memcached_enable_sasl]) + fi AC_MSG_CHECKING([for libmemcached location]) if test "$PHP_LIBMEMCACHED_DIR" = "no"; then diff --git a/memcached-api.php b/memcached-api.php index 73347d72..75522950 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -201,6 +201,10 @@ public function fetchAll( ) {} public function set( $key, $value, $expiration = 0 ) {} + public function touch( $key, $expiration = 0 ) {} + + public function touchbyKey( $key, $expiration = 0 ) {} + public function setByKey( $server_key, $key, $value, $expiration = 0 ) {} public function setMulti( array $items, $expiration = 0 ) {} diff --git a/php_memcached.c b/php_memcached.c index b559cf86..a07e31fd 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -198,6 +198,7 @@ typedef struct { enum { MEMC_OP_SET, + MEMC_OP_TOUCH, MEMC_OP_ADD, MEMC_OP_REPLACE, MEMC_OP_APPEND, @@ -1090,6 +1091,24 @@ PHP_METHOD(Memcached, setByKey) } /* }}} */ +/* {{{ Memcached::touch(string key, [, int expiration ]) + Sets a new expiration for the given key */ +PHP_METHOD(Memcached, touch) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 0); +} +/* }}} */ + +/* {{{ Memcached::touchbyKey(string key, [, int expiration ]) + Sets a new expiration for the given key */ +PHP_METHOD(Memcached, touchByKey) +{ + php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 1); +} +/* }}} */ + + + /* {{{ Memcached::setMulti(array items [, int expiration ]) Sets the keys/values specified in the items array */ PHP_METHOD(Memcached, setMulti) @@ -1274,6 +1293,11 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool INIT_ZVAL(s_zvalue); value = &s_zvalue; ZVAL_STRINGL(value, s_value, s_value_len, 0); + } else if (op == MEMC_OP_TOUCH) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &server_key, + &server_key_len, &key, &key_len, &expiration) == FAILURE) { + return; + } } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz|l", &server_key, &server_key_len, &key, &key_len, &value, &expiration) == FAILURE) { @@ -1289,6 +1313,11 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool INIT_ZVAL(s_zvalue); value = &s_zvalue; ZVAL_STRINGL(value, s_value, s_value_len, 0); + } else if (op == MEMC_OP_TOUCH) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &key, + &key_len, &expiration) == FAILURE) { + return; + } } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &key, &key_len, &value, &expiration) == FAILURE) { @@ -1318,6 +1347,11 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool flags |= MEMC_VAL_COMPRESSED; } + if (op == MEMC_OP_TOUCH && !memcached_behavior_get(m_obj->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "touch is only supported with binary protocol"); + RETURN_FALSE; + } + 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; @@ -1334,6 +1368,16 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool } break; + case MEMC_OP_TOUCH: + if (!server_key) { + status = memcached_touch(m_obj->memc, key, key_len, expiration); + } else { + status = memcached_touch_by_key(m_obj->memc, server_key, server_key_len, key, + key_len, expiration); + } + break; + + case MEMC_OP_ADD: if (!server_key) { status = memcached_add(m_obj->memc, key, key_len, payload, payload_len, expiration, flags); @@ -3113,6 +3157,17 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setByKey, 0, 0, 3) ZEND_ARG_INFO(0, expiration) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_touch, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, expiration) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_touchByKey, 0, 0, 3) + ZEND_ARG_INFO(0, server_key) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, expiration) +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) @@ -3317,6 +3372,8 @@ static zend_function_entry memcached_class_methods[] = { MEMC_ME(set, arginfo_set) MEMC_ME(setByKey, arginfo_setByKey) + MEMC_ME(touch, arginfo_touch) + MEMC_ME(touchByKey, arginfo_touchByKey) MEMC_ME(setMulti, arginfo_setMulti) MEMC_ME(setMultiByKey, arginfo_setMultiByKey) diff --git a/tests/expire.phpt b/tests/expire.phpt index 6e406d42..959b7eff 100644 --- a/tests/expire.phpt +++ b/tests/expire.phpt @@ -1,10 +1,11 @@ --TEST-- -Memcached store & fetch expired key +Memcached store, fetch & touch expired key --SKIPIF-- --FILE-- setOption(Memcached::OPT_BINARY_PROTOCOL, true); $m->addServer('127.0.0.1', 11211, 1); $set = $m->set('will_expire', "foo", 2); @@ -12,6 +13,16 @@ $v = $m->get('will_expire'); if (!$set || $v != 'foo') { echo "Error setting will_expire to \"foo\" with 2s expiry.\n"; } +sleep(1); +$res = $m->touch('will_expire', 2); +$v = $m->get('will_expire'); +if(!$res || $v != 'foo') { + echo "Error touching will_expire for another 2s expiry.\n"; + var_dump($res); + var_dump($m->getResultMessage()); + var_dump($v); +} + sleep(3); $v = $m->get('will_expire'); @@ -22,7 +33,18 @@ if ($v !== Memcached::GET_ERROR_RETURN_VALUE) { var_dump($v); } +// test with plaintext proto should throw error +$m = new Memcached(); +$m->addServer('127.0.0.1', 11211, 1); + +$set = $m->set('will_expire', "foo", 2); +$v = $m->touch('will_expire'); +if($v !== false) { + echo "Touch with text protocol should return false.\n"; +} + echo "OK\n"; ?> ---EXPECT-- +--EXPECTF-- +Warning: Memcached::touch(): touch is only supported with binary protocol in %s on line %d OK \ No newline at end of file