Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 872ae10

Browse files
Implement Redis 7.0.0 [P]EXPIRE[AT] options
See #2068
1 parent d05d301 commit 872ae10

12 files changed

Lines changed: 167 additions & 38 deletions

README.markdown

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,17 +1098,18 @@ $redis->get('x'); // → `FALSE`
10981098
-----
10991099
_**Description**_: Same as rename, but will not replace a key if the destination already exists. This is the same behaviour as setNx.
11001100

1101-
### expire, setTimeout, pexpire
1101+
### expire, pexpire
11021102
-----
1103-
_**Description**_: Sets an expiration date (a timeout) on an item. pexpire requires a TTL in milliseconds.
1103+
_**Description**_: Sets an expiration on a key in either seconds or milliseconds.
11041104

1105-
##### *Parameters*
1106-
*Key*: key. The key that will disappear.
1107-
1108-
*Integer*: ttl. The key's remaining Time To Live, in seconds.
1105+
##### *Prototype*
1106+
~~~php
1107+
public function expire(string $key, int $seconds, ?string $mode = NULL): Redis|bool;
1108+
public function pexpire(string $key, int $milliseconds, ?string $mode = NULL): Redis|bool;
1109+
~~~
11091110

11101111
##### *Return value*
1111-
*BOOL*: `TRUE` in case of success, `FALSE` in case of failure.
1112+
*BOOL*: `TRUE` if an expiration was set, and `FALSE` on failure or if one was not set. You can distinguish between an error and an expiration not being set by checking `getLastError()`.
11121113
##### *Example*
11131114
~~~php
11141115
$redis->set('x', '42');
@@ -1121,22 +1122,23 @@ $redis->get('x'); // will return `FALSE`, as 'x' has expired.
11211122

11221123
### expireAt, pexpireAt
11231124
-----
1124-
_**Description**_: Sets an expiration date (a timestamp) on an item. pexpireAt requires a timestamp in milliseconds.
1125-
1126-
##### *Parameters*
1127-
*Key*: key. The key that will disappear.
1125+
_**Description**_: Seta specific timestamp for a key to expire in seconds or milliseconds.
11281126

1129-
*Integer*: Unix timestamp. The key's date of death, in seconds from Epoch time.
1127+
##### *Prototype*
1128+
~~~php
1129+
public function expireat(string $key, int $unix_timestamp, ?string $mode = NULL): Redis|bool;
1130+
public function pexpireat(string $key, int $unix_timestamp_millis, ?string $mode = NULL): Redis|bool;
1131+
~~~
11301132

11311133
##### *Return value*
1132-
*BOOL*: `TRUE` in case of success, `FALSE` in case of failure.
1134+
*BOOL*: `TRUE` if an expiration was set and `FALSE` if one was not set or in the event on an error. You can detect an actual error by checking `getLastError()`.
1135+
11331136
##### *Example*
11341137
~~~php
11351138
$redis->set('x', '42');
1136-
$now = time(NULL); // current timestamp
1137-
$redis->expireAt('x', $now + 3); // x will disappear in 3 seconds.
1139+
$redis->expireAt('x', time(NULL) + 3); // x will disappear in 3 seconds.
11381140
sleep(5); // wait 5 seconds
1139-
$redis->get('x'); // will return `FALSE`, as 'x' has expired.
1141+
$redis->get('x'); // will return `FALSE`, as 'x' has expired.
11401142
~~~
11411143

11421144
### keys, getKeys

redis.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,25 +1635,25 @@ PHP_METHOD(Redis, sortDescAlpha)
16351635

16361636
/* {{{ proto array Redis::expire(string key, int timeout) */
16371637
PHP_METHOD(Redis, expire) {
1638-
REDIS_PROCESS_KW_CMD("EXPIRE", redis_key_long_cmd, redis_1_response);
1638+
REDIS_PROCESS_KW_CMD("EXPIRE", redis_expire_cmd, redis_1_response);
16391639
}
16401640
/* }}} */
16411641

16421642
/* {{{ proto bool Redis::pexpire(string key, long ms) */
16431643
PHP_METHOD(Redis, pexpire) {
1644-
REDIS_PROCESS_KW_CMD("PEXPIRE", redis_key_long_cmd, redis_1_response);
1644+
REDIS_PROCESS_KW_CMD("PEXPIRE", redis_expire_cmd, redis_1_response);
16451645
}
16461646
/* }}} */
16471647

16481648
/* {{{ proto array Redis::expireAt(string key, int timestamp) */
16491649
PHP_METHOD(Redis, expireAt) {
1650-
REDIS_PROCESS_KW_CMD("EXPIREAT", redis_key_long_cmd, redis_1_response);
1650+
REDIS_PROCESS_KW_CMD("EXPIREAT", redis_expire_cmd, redis_1_response);
16511651
}
16521652
/* }}} */
16531653

16541654
/* {{{ proto array Redis::pexpireAt(string key, int timestamp) */
16551655
PHP_METHOD(Redis, pexpireAt) {
1656-
REDIS_PROCESS_KW_CMD("PEXPIREAT", redis_key_long_cmd, redis_1_response);
1656+
REDIS_PROCESS_KW_CMD("PEXPIREAT", redis_expire_cmd, redis_1_response);
16571657
}
16581658
/* }}} */
16591659

redis.stub.php

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,32 @@ public function exec(): Redis|array|false;
105105

106106
public function exists(mixed $key, mixed ...$other_keys): Redis|int|bool;
107107

108-
public function expire(string $key, int $timeout): Redis|bool;
108+
/**
109+
Sets an expiration in seconds on the key in question. If connected to
110+
redis-server >= 7.0.0 you may send an additional "mode" argument which
111+
modifies how the command will execute.
112+
113+
@param string $key The key to set an expiration on.
114+
@param ?string $mode A two character modifier that changes how the
115+
command works.
116+
NX - Set expiry only if key has no expiry
117+
XX - Set expiry only if key has an expiry
118+
LT - Set expiry only when new expiry is < current expiry
119+
GT - Set expiry only when new expiry is > current expiry
120+
*/
121+
public function expire(string $key, int $timeout, ?string $mode = NULL): Redis|bool;
122+
123+
/**
124+
Set a key's expiration to a specific unix timestamp in seconds. If
125+
connected to Redis >= 7.0.0 you can pass an optional 'mode' argument.
109126
110-
public function expireAt(string $key, int $timestamp): Redis|bool;
127+
@see Redis::expire() For a description of the mode argument.
128+
129+
@param string $key The key to set an expiration on.
130+
@param ?string $mode A two character modifier that changes how the
131+
command works.
132+
*/
133+
public function expireAt(string $key, int $timestamp, ?string $mode = NULL): Redis|bool;
111134

112135
public function failover(?array $to = null, bool $abort = false, int $timeout = 0): Redis|bool;
113136

@@ -313,11 +336,32 @@ public function open(string $host, int $port = 6379, float $timeout = 0, string
313336

314337
public function pconnect(string $host, int $port = 6379, float $timeout = 0, string $persistent_id = NULL, int $retry_interval = 0, float $read_timeout = 0, array $context = NULL): bool;
315338

316-
public function persist(string $key): bool;
339+
public function persist(string $key): bool;
340+
341+
/**
342+
Sets an expiration in milliseconds on a given key. If connected to
343+
Redis >= 7.0.0 you can pass an optional mode argument that modifies
344+
how the command will execute.
345+
346+
@see Redis::expire() for a description of the mode argument.
317347
318-
public function pexpire(string $key, int $timeout): bool;
348+
@param string $key The key to set an expiration on.
349+
@param ?string $mode A two character modifier that changes how the
350+
command works.
351+
*/
352+
public function pexpire(string $key, int $timeout, ?string $mode = NULL): bool;
319353

320-
public function pexpireAt(string $key, int $timestamp): bool;
354+
/**
355+
Set a key's expiration to a specific unix timestamp in milliseconds. If
356+
connected to Redis >= 7.0.0 you can pass an optional 'mode' argument.
357+
358+
@see Redis::expire() For a description of the mode argument.
359+
360+
@param string $key The key to set an expiration on.
361+
@param ?string $mode A two character modifier that changes how the
362+
command works.
363+
*/
364+
public function pexpireAt(string $key, int $timestamp, ?string $mode = NULL): bool;
321365

322366
public function pfadd(string $key, array $elements): int;
323367

redis_arginfo.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 1810caef11b38440e073059e2d9c65f92fa8a9a5 */
2+
* Stub hash: b53146f6b329f404b4bfa9e5df9dde9c36b50440 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null")
@@ -201,11 +201,13 @@ ZEND_END_ARG_INFO()
201201
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_expire, 0, 2, Redis, MAY_BE_BOOL)
202202
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
203203
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
204+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL")
204205
ZEND_END_ARG_INFO()
205206

206207
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_expireAt, 0, 2, Redis, MAY_BE_BOOL)
207208
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
208209
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
210+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL")
209211
ZEND_END_ARG_INFO()
210212

211213
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_failover, 0, 0, Redis, MAY_BE_BOOL)
@@ -287,7 +289,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_geosearchstore,
287289
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]")
288290
ZEND_END_ARG_INFO()
289291

290-
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_Redis_get, 0, 1, Redis, MAY_BE_ANY|MAY_BE_FALSE)
292+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_get, 0, 1, IS_MIXED, 0)
291293
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
292294
ZEND_END_ARG_INFO()
293295

@@ -576,11 +578,13 @@ ZEND_END_ARG_INFO()
576578
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_pexpire, 0, 2, _IS_BOOL, 0)
577579
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
578580
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
581+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL")
579582
ZEND_END_ARG_INFO()
580583

581584
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_pexpireAt, 0, 2, _IS_BOOL, 0)
582585
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
583586
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
587+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL")
584588
ZEND_END_ARG_INFO()
585589

586590
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_pfadd, 0, 2, IS_LONG, 0)

redis_cluster.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,24 +1252,24 @@ PHP_METHOD(RedisCluster, decrbyfloat) {
12521252

12531253
/* {{{ proto bool RedisCluster::expire(string key, long sec) */
12541254
PHP_METHOD(RedisCluster, expire) {
1255-
CLUSTER_PROCESS_KW_CMD("EXPIRE", redis_key_long_cmd, cluster_1_resp, 0);
1255+
CLUSTER_PROCESS_KW_CMD("EXPIRE", redis_expire_cmd, cluster_1_resp, 0);
12561256
}
12571257
/* }}} */
12581258

12591259
/* {{{ proto bool RedisCluster::expireat(string key, long ts) */
12601260
PHP_METHOD(RedisCluster, expireat) {
1261-
CLUSTER_PROCESS_KW_CMD("EXPIREAT", redis_key_long_cmd, cluster_1_resp, 0);
1261+
CLUSTER_PROCESS_KW_CMD("EXPIREAT", redis_expire_cmd, cluster_1_resp, 0);
12621262
}
12631263

12641264
/* {{{ proto bool RedisCluster::pexpire(string key, long ms) */
12651265
PHP_METHOD(RedisCluster, pexpire) {
1266-
CLUSTER_PROCESS_KW_CMD("PEXPIRE", redis_key_long_cmd, cluster_1_resp, 0);
1266+
CLUSTER_PROCESS_KW_CMD("PEXPIRE", redis_expire_cmd, cluster_1_resp, 0);
12671267
}
12681268
/* }}} */
12691269

12701270
/* {{{ proto bool RedisCluster::pexpireat(string key, long ts) */
12711271
PHP_METHOD(RedisCluster, pexpireat) {
1272-
CLUSTER_PROCESS_KW_CMD("PEXPIREAT", redis_key_long_cmd, cluster_1_resp, 0);
1272+
CLUSTER_PROCESS_KW_CMD("PEXPIREAT", redis_expire_cmd, cluster_1_resp, 0);
12731273
}
12741274
/* }}} */
12751275

redis_cluster.stub.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ public function exec(): array|false;
9595

9696
public function exists(mixed $key, mixed ...$other_keys): RedisCluster|int|bool;
9797

98-
public function expire(string $key, int $timeout): RedisCluster|bool;
98+
public function expire(string $key, int $timeout, ?string $mode = NULL): RedisCluster|bool;
9999

100-
public function expireat(string $key, int $timestamp): RedisCluster|bool;
100+
public function expireat(string $key, int $timestamp, ?string $mode = NULL): RedisCluster|bool;
101101

102102
public function expiretime(string $key): RedisCluster|int|false;
103103

@@ -218,9 +218,9 @@ public function object(string $subcommand, string $key): RedisCluster|int|string
218218

219219
public function persist(string $key): RedisCluster|bool;
220220

221-
public function pexpire(string $key, int $timeout): RedisCluster|bool;
221+
public function pexpire(string $key, int $timeout, ?string $mode = NULL): RedisCluster|bool;
222222

223-
public function pexpireat(string $key, int $timestamp): RedisCluster|bool;
223+
public function pexpireat(string $key, int $timestamp, ?string $mode = NULL): RedisCluster|bool;
224224

225225
public function pfadd(string $key, array $elements): RedisCluster|bool;
226226

redis_cluster_arginfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: c6326ac0f4a1dc7b6fe920a7358010f1a570832a */
2+
* Stub hash: 6b41f3c801e587509bc5c7cab302dc6c1e0f7d56 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1)
@@ -203,11 +203,13 @@ ZEND_END_ARG_INFO()
203203
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_expire, 0, 2, RedisCluster, MAY_BE_BOOL)
204204
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
205205
ZEND_ARG_TYPE_INFO(0, timeout, IS_LONG, 0)
206+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL")
206207
ZEND_END_ARG_INFO()
207208

208209
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_expireat, 0, 2, RedisCluster, MAY_BE_BOOL)
209210
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
210211
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
212+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_STRING, 1, "NULL")
211213
ZEND_END_ARG_INFO()
212214

213215
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_RedisCluster_expiretime, 0, 1, RedisCluster, MAY_BE_LONG|MAY_BE_FALSE)

redis_cluster_legacy_arginfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: c6326ac0f4a1dc7b6fe920a7358010f1a570832a */
2+
* Stub hash: 6b41f3c801e587509bc5c7cab302dc6c1e0f7d56 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1)
55
ZEND_ARG_INFO(0, name)
@@ -177,11 +177,13 @@ ZEND_END_ARG_INFO()
177177
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_expire, 0, 0, 2)
178178
ZEND_ARG_INFO(0, key)
179179
ZEND_ARG_INFO(0, timeout)
180+
ZEND_ARG_INFO(0, mode)
180181
ZEND_END_ARG_INFO()
181182

182183
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster_expireat, 0, 0, 2)
183184
ZEND_ARG_INFO(0, key)
184185
ZEND_ARG_INFO(0, timestamp)
186+
ZEND_ARG_INFO(0, mode)
185187
ZEND_END_ARG_INFO()
186188

187189
#define arginfo_class_RedisCluster_expiretime arginfo_class_RedisCluster__prefix

redis_commands.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5724,6 +5724,42 @@ int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
57245724
return SUCCESS;
57255725
}
57265726

5727+
// [P]EXPIRE[AT] [NX | XX | GT | LT]
5728+
int redis_expire_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
5729+
char *kw, char **cmd, int *cmd_len, short *slot,
5730+
void **ctx)
5731+
{
5732+
zend_string *key = NULL, *mode = NULL;
5733+
smart_string cmdstr = {0};
5734+
zend_long timeout = 0;
5735+
5736+
ZEND_PARSE_PARAMETERS_START(2, 3)
5737+
Z_PARAM_STR(key)
5738+
Z_PARAM_LONG(timeout)
5739+
Z_PARAM_OPTIONAL
5740+
Z_PARAM_STR(mode)
5741+
ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
5742+
5743+
if (mode != NULL && !(zend_string_equals_literal_ci(mode, "NX") ||
5744+
zend_string_equals_literal_ci(mode, "XX") ||
5745+
zend_string_equals_literal_ci(mode, "LT") ||
5746+
zend_string_equals_literal_ci(mode, "GT")))
5747+
{
5748+
php_error_docref(NULL, E_WARNING, "Unknown expiration modifier '%s'", ZSTR_VAL(mode));
5749+
return FAILURE;
5750+
}
5751+
5752+
redis_cmd_init_sstr(&cmdstr, 2 + (mode != NULL), kw, strlen(kw));
5753+
redis_cmd_append_sstr_key_zstr(&cmdstr, key, redis_sock, slot);
5754+
redis_cmd_append_sstr_long(&cmdstr, timeout);
5755+
if (mode != NULL) redis_cmd_append_sstr_zstr(&cmdstr, mode);
5756+
5757+
*cmd = cmdstr.c;
5758+
*cmd_len = cmdstr.len;
5759+
5760+
return SUCCESS;
5761+
}
5762+
57275763
int
57285764
redis_sentinel_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
57295765
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx)

redis_commands.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ int redis_xreadgroup_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
354354
int redis_xtrim_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
355355
char **cmd, int *cmd_len, short *slot, void **ctx);
356356

357+
int redis_expire_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
358+
char *kw, char **cmd, int *cmd_len, short *slot,
359+
void **ctx);
360+
357361
int redis_sentinel_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
358362
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
359363

0 commit comments

Comments
 (0)