@artilingo/artiframe-cli 1.4.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core-stubs/bin/SystemMethod.php +600 -521
- package/core-stubs/bin/ViewMethod.php +591 -393
- package/core-stubs/docs/de.html +4347 -4390
- package/core-stubs/docs/en.html +4347 -4389
- package/core-stubs/docs/es.html +4347 -4390
- package/core-stubs/docs/fr.html +4347 -4389
- package/core-stubs/docs/tr.html +138 -109
- package/package.json +1 -1
- package/src/App.php +8 -0
- package/src/Commands/AddCommand.php +1 -1
- package/src/Commands/ListCommand.php +2 -1
- package/src/Commands/MakeApiCommand.php +1 -1
- package/src/Commands/MakeClassCommand.php +1 -1
- package/src/Commands/MakeViewCommand.php +1 -1
- package/src/Commands/NewProjectCommand.php +37 -25
- package/src/Commands/RemoveCommand.php +21 -10
- package/src/Commands/ServeCommand.php +29 -9
- package/src/Commands/TableCommand.php +2 -1
- package/src/Commands/UpgradeCommand.php +209 -0
- package/src/Commands/VersionCommand.php +2 -1
- package/src/Lang/de.php +7 -1
- package/src/Lang/en.php +6 -0
- package/src/Lang/es.php +7 -1
- package/src/Lang/fr.php +6 -0
- package/src/Lang/tr.php +7 -1
- package/src/Services/Safeguard.php +25 -0
- package/stubs/service/image.stub +334 -334
- package/stubs/service/iyzico.stub +637 -637
- package/stubs/service/jwt.stub +312 -312
- package/stubs/service/phpmailer.stub +143 -143
- package/stubs/service/pusher.stub +232 -232
- package/stubs/service/qrcode.stub +169 -169
- package/stubs/service/redis.stub +361 -361
- package/stubs/service/s3.stub +377 -377
- package/stubs/service/sentry.stub +76 -106
- package/stubs/service/stripe.stub +526 -526
- package/stubs/service/twilio.stub +361 -361
- package/core-stubs/app/R2Manager.php +0 -130
package/stubs/service/redis.stub
CHANGED
|
@@ -1,361 +1,361 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
|
|
3
|
-
namespace Service;
|
|
4
|
-
|
|
5
|
-
use Predis\Client;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Redis Cache Service
|
|
9
|
-
*
|
|
10
|
-
* Provides a clean, simple interface for Redis caching operations
|
|
11
|
-
* using the predis/predis SDK. All configuration is read from $_ENV.
|
|
12
|
-
*
|
|
13
|
-
* Required environment variables:
|
|
14
|
-
* REDIS_HOST — Redis server hostname (default: 127.0.0.1)
|
|
15
|
-
* REDIS_PORT — Redis server port (default: 6379)
|
|
16
|
-
* REDIS_PASSWORD — Redis authentication password (default: null)
|
|
17
|
-
* REDIS_DATABASE — Redis database index (default: 0)
|
|
18
|
-
*
|
|
19
|
-
* @package Service
|
|
20
|
-
*/
|
|
21
|
-
class RedisCache
|
|
22
|
-
{
|
|
23
|
-
/**
|
|
24
|
-
* The Predis client instance.
|
|
25
|
-
*
|
|
26
|
-
* @var \Predis\Client
|
|
27
|
-
*/
|
|
28
|
-
private Client $client;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create a new RedisCache instance.
|
|
32
|
-
*
|
|
33
|
-
* Initializes the Predis client using connection parameters
|
|
34
|
-
* from environment variables. Falls back to sensible defaults
|
|
35
|
-
* if variables are not set.
|
|
36
|
-
*
|
|
37
|
-
* @throws \Predis\Connection\ConnectionException If unable to connect to Redis
|
|
38
|
-
*/
|
|
39
|
-
public function __construct()
|
|
40
|
-
{
|
|
41
|
-
$this->client = new Client([
|
|
42
|
-
'scheme' => 'tcp',
|
|
43
|
-
'host' => $_ENV['REDIS_HOST'] ?? '127.0.0.1',
|
|
44
|
-
'port' => (int) ($_ENV['REDIS_PORT'] ?? 6379),
|
|
45
|
-
'password' => $_ENV['REDIS_PASSWORD'] ?? null,
|
|
46
|
-
'database' => (int) ($_ENV['REDIS_DATABASE'] ?? 0),
|
|
47
|
-
]);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Get a value from the cache.
|
|
52
|
-
*
|
|
53
|
-
* Automatically attempts to JSON-decode the stored value.
|
|
54
|
-
* If decoding fails, the raw string value is returned.
|
|
55
|
-
*
|
|
56
|
-
* @param string $key The cache key
|
|
57
|
-
* @param mixed $default Default value if key does not exist
|
|
58
|
-
* @return mixed The cached value, decoded JSON, or default
|
|
59
|
-
*/
|
|
60
|
-
public function get(string $key, mixed $default = null): mixed
|
|
61
|
-
{
|
|
62
|
-
try {
|
|
63
|
-
$value = $this->client->get($key);
|
|
64
|
-
|
|
65
|
-
if ($value === null) {
|
|
66
|
-
return $default;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
$decoded = json_decode($value, true);
|
|
70
|
-
|
|
71
|
-
return (json_last_error() === JSON_ERROR_NONE) ? $decoded : $value;
|
|
72
|
-
} catch (\Exception $e) {
|
|
73
|
-
return $default;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Store a value in the cache.
|
|
79
|
-
*
|
|
80
|
-
* Arrays and objects are automatically JSON-encoded before storage.
|
|
81
|
-
* Scalar values are stored as-is.
|
|
82
|
-
*
|
|
83
|
-
* @param string $key The cache key
|
|
84
|
-
* @param mixed $value The value to store
|
|
85
|
-
* @param int $ttl Time-to-live in seconds (0 = no expiry)
|
|
86
|
-
* @return bool True on success, false on failure
|
|
87
|
-
*/
|
|
88
|
-
public function set(string $key, mixed $value, int $ttl = 0): bool
|
|
89
|
-
{
|
|
90
|
-
try {
|
|
91
|
-
$serialized = (is_array($value) || is_object($value))
|
|
92
|
-
? json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
93
|
-
: $value;
|
|
94
|
-
|
|
95
|
-
if ($ttl > 0) {
|
|
96
|
-
$result = $this->client->setex($key, $ttl, $serialized);
|
|
97
|
-
} else {
|
|
98
|
-
$result = $this->client->set($key, $serialized);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return (string) $result === 'OK';
|
|
102
|
-
} catch (\Exception $e) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Check if a key exists in the cache.
|
|
109
|
-
*
|
|
110
|
-
* @param string $key The cache key
|
|
111
|
-
* @return bool True if the key exists
|
|
112
|
-
*/
|
|
113
|
-
public function has(string $key): bool
|
|
114
|
-
{
|
|
115
|
-
try {
|
|
116
|
-
return (bool) $this->client->exists($key);
|
|
117
|
-
} catch (\Exception $e) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Delete a key from the cache.
|
|
124
|
-
*
|
|
125
|
-
* @param string $key The cache key to delete
|
|
126
|
-
* @return bool True if the key was deleted, false if it didn't exist or on error
|
|
127
|
-
*/
|
|
128
|
-
public function forget(string $key): bool
|
|
129
|
-
{
|
|
130
|
-
try {
|
|
131
|
-
return $this->client->del([$key]) > 0;
|
|
132
|
-
} catch (\Exception $e) {
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Get a value from cache, or execute a callback and store the result.
|
|
139
|
-
*
|
|
140
|
-
* This is the classic "cache-aside" pattern. If the key exists in cache,
|
|
141
|
-
* its value is returned. Otherwise, the callback is executed, its return
|
|
142
|
-
* value is stored in cache with the given TTL, and then returned.
|
|
143
|
-
*
|
|
144
|
-
* @param string $key The cache key
|
|
145
|
-
* @param int $ttl Time-to-live in seconds
|
|
146
|
-
* @param callable $callback Function to execute if key is not cached
|
|
147
|
-
* @return mixed The cached or freshly computed value
|
|
148
|
-
*/
|
|
149
|
-
public function remember(string $key, int $ttl, callable $callback): mixed
|
|
150
|
-
{
|
|
151
|
-
if ($this->has($key)) {
|
|
152
|
-
return $this->get($key);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
$value = $callback();
|
|
156
|
-
$this->set($key, $value, $ttl);
|
|
157
|
-
|
|
158
|
-
return $value;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Increment a numeric value stored at the given key.
|
|
163
|
-
*
|
|
164
|
-
* If the key does not exist, it is initialized to 0 before incrementing.
|
|
165
|
-
*
|
|
166
|
-
* @param string $key The cache key
|
|
167
|
-
* @param int $amount Amount to increment by (default: 1)
|
|
168
|
-
* @return int The new value after incrementing
|
|
169
|
-
*/
|
|
170
|
-
public function increment(string $key, int $amount = 1): int
|
|
171
|
-
{
|
|
172
|
-
try {
|
|
173
|
-
return $this->client->incrby($key, $amount);
|
|
174
|
-
} catch (\Exception $e) {
|
|
175
|
-
return 0;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Decrement a numeric value stored at the given key.
|
|
181
|
-
*
|
|
182
|
-
* If the key does not exist, it is initialized to 0 before decrementing.
|
|
183
|
-
*
|
|
184
|
-
* @param string $key The cache key
|
|
185
|
-
* @param int $amount Amount to decrement by (default: 1)
|
|
186
|
-
* @return int The new value after decrementing
|
|
187
|
-
*/
|
|
188
|
-
public function decrement(string $key, int $amount = 1): int
|
|
189
|
-
{
|
|
190
|
-
try {
|
|
191
|
-
return $this->client->decrby($key, $amount);
|
|
192
|
-
} catch (\Exception $e) {
|
|
193
|
-
return 0;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Clear all keys in the current Redis database.
|
|
199
|
-
*
|
|
200
|
-
* WARNING: This removes ALL data from the selected database.
|
|
201
|
-
* Use with caution in production environments.
|
|
202
|
-
*
|
|
203
|
-
* @return bool True on success, false on failure
|
|
204
|
-
*/
|
|
205
|
-
public function flush(): bool
|
|
206
|
-
{
|
|
207
|
-
try {
|
|
208
|
-
$result = $this->client->flushdb();
|
|
209
|
-
return (string) $result === 'OK';
|
|
210
|
-
} catch (\Exception $e) {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* List all keys matching the given pattern.
|
|
217
|
-
*
|
|
218
|
-
* Supports Redis glob-style patterns:
|
|
219
|
-
* * — matches any sequence of characters
|
|
220
|
-
* ? — matches any single character
|
|
221
|
-
* [abc] — matches a, b, or c
|
|
222
|
-
*
|
|
223
|
-
* WARNING: KEYS is O(N) and should not be used in production on large datasets.
|
|
224
|
-
* Consider SCAN-based alternatives for large keyspaces.
|
|
225
|
-
*
|
|
226
|
-
* @param string $pattern Glob-style pattern (default: '*' for all keys)
|
|
227
|
-
* @return array List of matching key names
|
|
228
|
-
*/
|
|
229
|
-
public function keys(string $pattern = '*'): array
|
|
230
|
-
{
|
|
231
|
-
try {
|
|
232
|
-
return $this->client->keys($pattern);
|
|
233
|
-
} catch (\Exception $e) {
|
|
234
|
-
return [];
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Get the remaining time-to-live for a key.
|
|
240
|
-
*
|
|
241
|
-
* @param string $key The cache key
|
|
242
|
-
* @return int TTL in seconds, -1 if no expiry is set, -2 if key does not exist
|
|
243
|
-
*/
|
|
244
|
-
public function ttl(string $key): int
|
|
245
|
-
{
|
|
246
|
-
try {
|
|
247
|
-
return $this->client->ttl($key);
|
|
248
|
-
} catch (\Exception $e) {
|
|
249
|
-
return -2;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Set an expiry (timeout) on an existing key.
|
|
255
|
-
*
|
|
256
|
-
* @param string $key The cache key
|
|
257
|
-
* @param int $seconds Number of seconds until the key expires
|
|
258
|
-
* @return bool True if the timeout was set, false if key does not exist or on error
|
|
259
|
-
*/
|
|
260
|
-
public function expire(string $key, int $seconds): bool
|
|
261
|
-
{
|
|
262
|
-
try {
|
|
263
|
-
return (bool) $this->client->expire($key, $seconds);
|
|
264
|
-
} catch (\Exception $e) {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Set a field value in a Redis hash.
|
|
271
|
-
*
|
|
272
|
-
* Arrays and objects are automatically JSON-encoded.
|
|
273
|
-
*
|
|
274
|
-
* @param string $hash The hash key name
|
|
275
|
-
* @param string $field The field name within the hash
|
|
276
|
-
* @param mixed $value The value to store
|
|
277
|
-
* @return bool True on success
|
|
278
|
-
*/
|
|
279
|
-
public function hSet(string $hash, string $field, mixed $value): bool
|
|
280
|
-
{
|
|
281
|
-
try {
|
|
282
|
-
$serialized = (is_array($value) || is_object($value))
|
|
283
|
-
? json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
284
|
-
: $value;
|
|
285
|
-
|
|
286
|
-
$this->client->hset($hash, $field, $serialized);
|
|
287
|
-
|
|
288
|
-
return true;
|
|
289
|
-
} catch (\Exception $e) {
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Get a field value from a Redis hash.
|
|
296
|
-
*
|
|
297
|
-
* Automatically attempts to JSON-decode the stored value.
|
|
298
|
-
*
|
|
299
|
-
* @param string $hash The hash key name
|
|
300
|
-
* @param string $field The field name within the hash
|
|
301
|
-
* @param mixed $default Default value if field does not exist
|
|
302
|
-
* @return mixed The field value, decoded JSON, or default
|
|
303
|
-
*/
|
|
304
|
-
public function hGet(string $hash, string $field, mixed $default = null): mixed
|
|
305
|
-
{
|
|
306
|
-
try {
|
|
307
|
-
$value = $this->client->hget($hash, $field);
|
|
308
|
-
|
|
309
|
-
if ($value === null) {
|
|
310
|
-
return $default;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
$decoded = json_decode($value, true);
|
|
314
|
-
|
|
315
|
-
return (json_last_error() === JSON_ERROR_NONE) ? $decoded : $value;
|
|
316
|
-
} catch (\Exception $e) {
|
|
317
|
-
return $default;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Get all fields and values from a Redis hash.
|
|
323
|
-
*
|
|
324
|
-
* Each value is automatically JSON-decoded if possible.
|
|
325
|
-
*
|
|
326
|
-
* @param string $hash The hash key name
|
|
327
|
-
* @return array Associative array of field => value pairs
|
|
328
|
-
*/
|
|
329
|
-
public function hGetAll(string $hash): array
|
|
330
|
-
{
|
|
331
|
-
try {
|
|
332
|
-
$data = $this->client->hgetall($hash);
|
|
333
|
-
$result = [];
|
|
334
|
-
|
|
335
|
-
foreach ($data as $field => $value) {
|
|
336
|
-
$decoded = json_decode($value, true);
|
|
337
|
-
$result[$field] = (json_last_error() === JSON_ERROR_NONE) ? $decoded : $value;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
return $result;
|
|
341
|
-
} catch (\Exception $e) {
|
|
342
|
-
return [];
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Delete a field from a Redis hash.
|
|
348
|
-
*
|
|
349
|
-
* @param string $hash The hash key name
|
|
350
|
-
* @param string $field The field name to delete
|
|
351
|
-
* @return bool True if the field was removed, false if it didn't exist or on error
|
|
352
|
-
*/
|
|
353
|
-
public function hDel(string $hash, string $field): bool
|
|
354
|
-
{
|
|
355
|
-
try {
|
|
356
|
-
return $this->client->hdel($hash, [$field]) > 0;
|
|
357
|
-
} catch (\Exception $e) {
|
|
358
|
-
return false;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Src\Service;
|
|
4
|
+
|
|
5
|
+
use Predis\Client;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Redis Cache Service
|
|
9
|
+
*
|
|
10
|
+
* Provides a clean, simple interface for Redis caching operations
|
|
11
|
+
* using the predis/predis SDK. All configuration is read from $_ENV.
|
|
12
|
+
*
|
|
13
|
+
* Required environment variables:
|
|
14
|
+
* REDIS_HOST — Redis server hostname (default: 127.0.0.1)
|
|
15
|
+
* REDIS_PORT — Redis server port (default: 6379)
|
|
16
|
+
* REDIS_PASSWORD — Redis authentication password (default: null)
|
|
17
|
+
* REDIS_DATABASE — Redis database index (default: 0)
|
|
18
|
+
*
|
|
19
|
+
* @package Service
|
|
20
|
+
*/
|
|
21
|
+
class RedisCache
|
|
22
|
+
{
|
|
23
|
+
/**
|
|
24
|
+
* The Predis client instance.
|
|
25
|
+
*
|
|
26
|
+
* @var \Predis\Client
|
|
27
|
+
*/
|
|
28
|
+
private Client $client;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a new RedisCache instance.
|
|
32
|
+
*
|
|
33
|
+
* Initializes the Predis client using connection parameters
|
|
34
|
+
* from environment variables. Falls back to sensible defaults
|
|
35
|
+
* if variables are not set.
|
|
36
|
+
*
|
|
37
|
+
* @throws \Predis\Connection\ConnectionException If unable to connect to Redis
|
|
38
|
+
*/
|
|
39
|
+
public function __construct()
|
|
40
|
+
{
|
|
41
|
+
$this->client = new Client([
|
|
42
|
+
'scheme' => 'tcp',
|
|
43
|
+
'host' => $_ENV['REDIS_HOST'] ?? '127.0.0.1',
|
|
44
|
+
'port' => (int) ($_ENV['REDIS_PORT'] ?? 6379),
|
|
45
|
+
'password' => $_ENV['REDIS_PASSWORD'] ?? null,
|
|
46
|
+
'database' => (int) ($_ENV['REDIS_DATABASE'] ?? 0),
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get a value from the cache.
|
|
52
|
+
*
|
|
53
|
+
* Automatically attempts to JSON-decode the stored value.
|
|
54
|
+
* If decoding fails, the raw string value is returned.
|
|
55
|
+
*
|
|
56
|
+
* @param string $key The cache key
|
|
57
|
+
* @param mixed $default Default value if key does not exist
|
|
58
|
+
* @return mixed The cached value, decoded JSON, or default
|
|
59
|
+
*/
|
|
60
|
+
public function get(string $key, mixed $default = null): mixed
|
|
61
|
+
{
|
|
62
|
+
try {
|
|
63
|
+
$value = $this->client->get($key);
|
|
64
|
+
|
|
65
|
+
if ($value === null) {
|
|
66
|
+
return $default;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
$decoded = json_decode($value, true);
|
|
70
|
+
|
|
71
|
+
return (json_last_error() === JSON_ERROR_NONE) ? $decoded : $value;
|
|
72
|
+
} catch (\Exception $e) {
|
|
73
|
+
return $default;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Store a value in the cache.
|
|
79
|
+
*
|
|
80
|
+
* Arrays and objects are automatically JSON-encoded before storage.
|
|
81
|
+
* Scalar values are stored as-is.
|
|
82
|
+
*
|
|
83
|
+
* @param string $key The cache key
|
|
84
|
+
* @param mixed $value The value to store
|
|
85
|
+
* @param int $ttl Time-to-live in seconds (0 = no expiry)
|
|
86
|
+
* @return bool True on success, false on failure
|
|
87
|
+
*/
|
|
88
|
+
public function set(string $key, mixed $value, int $ttl = 0): bool
|
|
89
|
+
{
|
|
90
|
+
try {
|
|
91
|
+
$serialized = (is_array($value) || is_object($value))
|
|
92
|
+
? json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
93
|
+
: $value;
|
|
94
|
+
|
|
95
|
+
if ($ttl > 0) {
|
|
96
|
+
$result = $this->client->setex($key, $ttl, $serialized);
|
|
97
|
+
} else {
|
|
98
|
+
$result = $this->client->set($key, $serialized);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return (string) $result === 'OK';
|
|
102
|
+
} catch (\Exception $e) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check if a key exists in the cache.
|
|
109
|
+
*
|
|
110
|
+
* @param string $key The cache key
|
|
111
|
+
* @return bool True if the key exists
|
|
112
|
+
*/
|
|
113
|
+
public function has(string $key): bool
|
|
114
|
+
{
|
|
115
|
+
try {
|
|
116
|
+
return (bool) $this->client->exists($key);
|
|
117
|
+
} catch (\Exception $e) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Delete a key from the cache.
|
|
124
|
+
*
|
|
125
|
+
* @param string $key The cache key to delete
|
|
126
|
+
* @return bool True if the key was deleted, false if it didn't exist or on error
|
|
127
|
+
*/
|
|
128
|
+
public function forget(string $key): bool
|
|
129
|
+
{
|
|
130
|
+
try {
|
|
131
|
+
return $this->client->del([$key]) > 0;
|
|
132
|
+
} catch (\Exception $e) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get a value from cache, or execute a callback and store the result.
|
|
139
|
+
*
|
|
140
|
+
* This is the classic "cache-aside" pattern. If the key exists in cache,
|
|
141
|
+
* its value is returned. Otherwise, the callback is executed, its return
|
|
142
|
+
* value is stored in cache with the given TTL, and then returned.
|
|
143
|
+
*
|
|
144
|
+
* @param string $key The cache key
|
|
145
|
+
* @param int $ttl Time-to-live in seconds
|
|
146
|
+
* @param callable $callback Function to execute if key is not cached
|
|
147
|
+
* @return mixed The cached or freshly computed value
|
|
148
|
+
*/
|
|
149
|
+
public function remember(string $key, int $ttl, callable $callback): mixed
|
|
150
|
+
{
|
|
151
|
+
if ($this->has($key)) {
|
|
152
|
+
return $this->get($key);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
$value = $callback();
|
|
156
|
+
$this->set($key, $value, $ttl);
|
|
157
|
+
|
|
158
|
+
return $value;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Increment a numeric value stored at the given key.
|
|
163
|
+
*
|
|
164
|
+
* If the key does not exist, it is initialized to 0 before incrementing.
|
|
165
|
+
*
|
|
166
|
+
* @param string $key The cache key
|
|
167
|
+
* @param int $amount Amount to increment by (default: 1)
|
|
168
|
+
* @return int The new value after incrementing
|
|
169
|
+
*/
|
|
170
|
+
public function increment(string $key, int $amount = 1): int
|
|
171
|
+
{
|
|
172
|
+
try {
|
|
173
|
+
return $this->client->incrby($key, $amount);
|
|
174
|
+
} catch (\Exception $e) {
|
|
175
|
+
return 0;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Decrement a numeric value stored at the given key.
|
|
181
|
+
*
|
|
182
|
+
* If the key does not exist, it is initialized to 0 before decrementing.
|
|
183
|
+
*
|
|
184
|
+
* @param string $key The cache key
|
|
185
|
+
* @param int $amount Amount to decrement by (default: 1)
|
|
186
|
+
* @return int The new value after decrementing
|
|
187
|
+
*/
|
|
188
|
+
public function decrement(string $key, int $amount = 1): int
|
|
189
|
+
{
|
|
190
|
+
try {
|
|
191
|
+
return $this->client->decrby($key, $amount);
|
|
192
|
+
} catch (\Exception $e) {
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Clear all keys in the current Redis database.
|
|
199
|
+
*
|
|
200
|
+
* WARNING: This removes ALL data from the selected database.
|
|
201
|
+
* Use with caution in production environments.
|
|
202
|
+
*
|
|
203
|
+
* @return bool True on success, false on failure
|
|
204
|
+
*/
|
|
205
|
+
public function flush(): bool
|
|
206
|
+
{
|
|
207
|
+
try {
|
|
208
|
+
$result = $this->client->flushdb();
|
|
209
|
+
return (string) $result === 'OK';
|
|
210
|
+
} catch (\Exception $e) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* List all keys matching the given pattern.
|
|
217
|
+
*
|
|
218
|
+
* Supports Redis glob-style patterns:
|
|
219
|
+
* * — matches any sequence of characters
|
|
220
|
+
* ? — matches any single character
|
|
221
|
+
* [abc] — matches a, b, or c
|
|
222
|
+
*
|
|
223
|
+
* WARNING: KEYS is O(N) and should not be used in production on large datasets.
|
|
224
|
+
* Consider SCAN-based alternatives for large keyspaces.
|
|
225
|
+
*
|
|
226
|
+
* @param string $pattern Glob-style pattern (default: '*' for all keys)
|
|
227
|
+
* @return array List of matching key names
|
|
228
|
+
*/
|
|
229
|
+
public function keys(string $pattern = '*'): array
|
|
230
|
+
{
|
|
231
|
+
try {
|
|
232
|
+
return $this->client->keys($pattern);
|
|
233
|
+
} catch (\Exception $e) {
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get the remaining time-to-live for a key.
|
|
240
|
+
*
|
|
241
|
+
* @param string $key The cache key
|
|
242
|
+
* @return int TTL in seconds, -1 if no expiry is set, -2 if key does not exist
|
|
243
|
+
*/
|
|
244
|
+
public function ttl(string $key): int
|
|
245
|
+
{
|
|
246
|
+
try {
|
|
247
|
+
return $this->client->ttl($key);
|
|
248
|
+
} catch (\Exception $e) {
|
|
249
|
+
return -2;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Set an expiry (timeout) on an existing key.
|
|
255
|
+
*
|
|
256
|
+
* @param string $key The cache key
|
|
257
|
+
* @param int $seconds Number of seconds until the key expires
|
|
258
|
+
* @return bool True if the timeout was set, false if key does not exist or on error
|
|
259
|
+
*/
|
|
260
|
+
public function expire(string $key, int $seconds): bool
|
|
261
|
+
{
|
|
262
|
+
try {
|
|
263
|
+
return (bool) $this->client->expire($key, $seconds);
|
|
264
|
+
} catch (\Exception $e) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Set a field value in a Redis hash.
|
|
271
|
+
*
|
|
272
|
+
* Arrays and objects are automatically JSON-encoded.
|
|
273
|
+
*
|
|
274
|
+
* @param string $hash The hash key name
|
|
275
|
+
* @param string $field The field name within the hash
|
|
276
|
+
* @param mixed $value The value to store
|
|
277
|
+
* @return bool True on success
|
|
278
|
+
*/
|
|
279
|
+
public function hSet(string $hash, string $field, mixed $value): bool
|
|
280
|
+
{
|
|
281
|
+
try {
|
|
282
|
+
$serialized = (is_array($value) || is_object($value))
|
|
283
|
+
? json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
284
|
+
: $value;
|
|
285
|
+
|
|
286
|
+
$this->client->hset($hash, $field, $serialized);
|
|
287
|
+
|
|
288
|
+
return true;
|
|
289
|
+
} catch (\Exception $e) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Get a field value from a Redis hash.
|
|
296
|
+
*
|
|
297
|
+
* Automatically attempts to JSON-decode the stored value.
|
|
298
|
+
*
|
|
299
|
+
* @param string $hash The hash key name
|
|
300
|
+
* @param string $field The field name within the hash
|
|
301
|
+
* @param mixed $default Default value if field does not exist
|
|
302
|
+
* @return mixed The field value, decoded JSON, or default
|
|
303
|
+
*/
|
|
304
|
+
public function hGet(string $hash, string $field, mixed $default = null): mixed
|
|
305
|
+
{
|
|
306
|
+
try {
|
|
307
|
+
$value = $this->client->hget($hash, $field);
|
|
308
|
+
|
|
309
|
+
if ($value === null) {
|
|
310
|
+
return $default;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
$decoded = json_decode($value, true);
|
|
314
|
+
|
|
315
|
+
return (json_last_error() === JSON_ERROR_NONE) ? $decoded : $value;
|
|
316
|
+
} catch (\Exception $e) {
|
|
317
|
+
return $default;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Get all fields and values from a Redis hash.
|
|
323
|
+
*
|
|
324
|
+
* Each value is automatically JSON-decoded if possible.
|
|
325
|
+
*
|
|
326
|
+
* @param string $hash The hash key name
|
|
327
|
+
* @return array Associative array of field => value pairs
|
|
328
|
+
*/
|
|
329
|
+
public function hGetAll(string $hash): array
|
|
330
|
+
{
|
|
331
|
+
try {
|
|
332
|
+
$data = $this->client->hgetall($hash);
|
|
333
|
+
$result = [];
|
|
334
|
+
|
|
335
|
+
foreach ($data as $field => $value) {
|
|
336
|
+
$decoded = json_decode($value, true);
|
|
337
|
+
$result[$field] = (json_last_error() === JSON_ERROR_NONE) ? $decoded : $value;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return $result;
|
|
341
|
+
} catch (\Exception $e) {
|
|
342
|
+
return [];
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Delete a field from a Redis hash.
|
|
348
|
+
*
|
|
349
|
+
* @param string $hash The hash key name
|
|
350
|
+
* @param string $field The field name to delete
|
|
351
|
+
* @return bool True if the field was removed, false if it didn't exist or on error
|
|
352
|
+
*/
|
|
353
|
+
public function hDel(string $hash, string $field): bool
|
|
354
|
+
{
|
|
355
|
+
try {
|
|
356
|
+
return $this->client->hdel($hash, [$field]) > 0;
|
|
357
|
+
} catch (\Exception $e) {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|