PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Redis/Connections/PhpRedisConnection.php

https://gitlab.com/madwanz64/laravel
PHP | 557 lines | 240 code | 59 blank | 258 comment | 9 complexity | e496376ee60b645682b04511acd7c995 MD5 | raw file
  1. <?php
  2. namespace Illuminate\Redis\Connections;
  3. use Closure;
  4. use Illuminate\Contracts\Redis\Connection as ConnectionContract;
  5. use Illuminate\Support\Str;
  6. use Redis;
  7. use RedisCluster;
  8. use RedisException;
  9. /**
  10. * @mixin \Redis
  11. */
  12. class PhpRedisConnection extends Connection implements ConnectionContract
  13. {
  14. /**
  15. * The connection creation callback.
  16. *
  17. * @var callable
  18. */
  19. protected $connector;
  20. /**
  21. * The connection configuration array.
  22. *
  23. * @var array
  24. */
  25. protected $config;
  26. /**
  27. * Create a new PhpRedis connection.
  28. *
  29. * @param \Redis $client
  30. * @param callable|null $connector
  31. * @param array $config
  32. * @return void
  33. */
  34. public function __construct($client, callable $connector = null, array $config = [])
  35. {
  36. $this->client = $client;
  37. $this->config = $config;
  38. $this->connector = $connector;
  39. }
  40. /**
  41. * Returns the value of the given key.
  42. *
  43. * @param string $key
  44. * @return string|null
  45. */
  46. public function get($key)
  47. {
  48. $result = $this->command('get', [$key]);
  49. return $result !== false ? $result : null;
  50. }
  51. /**
  52. * Get the values of all the given keys.
  53. *
  54. * @param array $keys
  55. * @return array
  56. */
  57. public function mget(array $keys)
  58. {
  59. return array_map(function ($value) {
  60. return $value !== false ? $value : null;
  61. }, $this->command('mget', [$keys]));
  62. }
  63. /**
  64. * Set the string value in argument as value of the key.
  65. *
  66. * @param string $key
  67. * @param mixed $value
  68. * @param string|null $expireResolution
  69. * @param int|null $expireTTL
  70. * @param string|null $flag
  71. * @return bool
  72. */
  73. public function set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null)
  74. {
  75. return $this->command('set', [
  76. $key,
  77. $value,
  78. $expireResolution ? [$flag, $expireResolution => $expireTTL] : null,
  79. ]);
  80. }
  81. /**
  82. * Set the given key if it doesn't exist.
  83. *
  84. * @param string $key
  85. * @param string $value
  86. * @return int
  87. */
  88. public function setnx($key, $value)
  89. {
  90. return (int) $this->command('setnx', [$key, $value]);
  91. }
  92. /**
  93. * Get the value of the given hash fields.
  94. *
  95. * @param string $key
  96. * @param mixed $dictionary
  97. * @return array
  98. */
  99. public function hmget($key, ...$dictionary)
  100. {
  101. if (count($dictionary) === 1) {
  102. $dictionary = $dictionary[0];
  103. }
  104. return array_values($this->command('hmget', [$key, $dictionary]));
  105. }
  106. /**
  107. * Set the given hash fields to their respective values.
  108. *
  109. * @param string $key
  110. * @param mixed $dictionary
  111. * @return int
  112. */
  113. public function hmset($key, ...$dictionary)
  114. {
  115. if (count($dictionary) === 1) {
  116. $dictionary = $dictionary[0];
  117. } else {
  118. $input = collect($dictionary);
  119. $dictionary = $input->nth(2)->combine($input->nth(2, 1))->toArray();
  120. }
  121. return $this->command('hmset', [$key, $dictionary]);
  122. }
  123. /**
  124. * Set the given hash field if it doesn't exist.
  125. *
  126. * @param string $hash
  127. * @param string $key
  128. * @param string $value
  129. * @return int
  130. */
  131. public function hsetnx($hash, $key, $value)
  132. {
  133. return (int) $this->command('hsetnx', [$hash, $key, $value]);
  134. }
  135. /**
  136. * Removes the first count occurrences of the value element from the list.
  137. *
  138. * @param string $key
  139. * @param int $count
  140. * @param mixed $value
  141. * @return int|false
  142. */
  143. public function lrem($key, $count, $value)
  144. {
  145. return $this->command('lrem', [$key, $value, $count]);
  146. }
  147. /**
  148. * Removes and returns the first element of the list stored at key.
  149. *
  150. * @param mixed $arguments
  151. * @return array|null
  152. */
  153. public function blpop(...$arguments)
  154. {
  155. $result = $this->command('blpop', $arguments);
  156. return empty($result) ? null : $result;
  157. }
  158. /**
  159. * Removes and returns the last element of the list stored at key.
  160. *
  161. * @param mixed $arguments
  162. * @return array|null
  163. */
  164. public function brpop(...$arguments)
  165. {
  166. $result = $this->command('brpop', $arguments);
  167. return empty($result) ? null : $result;
  168. }
  169. /**
  170. * Removes and returns a random element from the set value at key.
  171. *
  172. * @param string $key
  173. * @param int|null $count
  174. * @return mixed|false
  175. */
  176. public function spop($key, $count = 1)
  177. {
  178. return $this->command('spop', func_get_args());
  179. }
  180. /**
  181. * Add one or more members to a sorted set or update its score if it already exists.
  182. *
  183. * @param string $key
  184. * @param mixed $dictionary
  185. * @return int
  186. */
  187. public function zadd($key, ...$dictionary)
  188. {
  189. if (is_array(end($dictionary))) {
  190. foreach (array_pop($dictionary) as $member => $score) {
  191. $dictionary[] = $score;
  192. $dictionary[] = $member;
  193. }
  194. }
  195. $options = [];
  196. foreach (array_slice($dictionary, 0, 3) as $i => $value) {
  197. if (in_array($value, ['nx', 'xx', 'ch', 'incr', 'NX', 'XX', 'CH', 'INCR'], true)) {
  198. $options[] = $value;
  199. unset($dictionary[$i]);
  200. }
  201. }
  202. return $this->command('zadd', array_merge([$key], [$options], array_values($dictionary)));
  203. }
  204. /**
  205. * Return elements with score between $min and $max.
  206. *
  207. * @param string $key
  208. * @param mixed $min
  209. * @param mixed $max
  210. * @param array $options
  211. * @return array
  212. */
  213. public function zrangebyscore($key, $min, $max, $options = [])
  214. {
  215. if (isset($options['limit'])) {
  216. $options['limit'] = [
  217. $options['limit']['offset'],
  218. $options['limit']['count'],
  219. ];
  220. }
  221. return $this->command('zRangeByScore', [$key, $min, $max, $options]);
  222. }
  223. /**
  224. * Return elements with score between $min and $max.
  225. *
  226. * @param string $key
  227. * @param mixed $min
  228. * @param mixed $max
  229. * @param array $options
  230. * @return array
  231. */
  232. public function zrevrangebyscore($key, $min, $max, $options = [])
  233. {
  234. if (isset($options['limit'])) {
  235. $options['limit'] = [
  236. $options['limit']['offset'],
  237. $options['limit']['count'],
  238. ];
  239. }
  240. return $this->command('zRevRangeByScore', [$key, $min, $max, $options]);
  241. }
  242. /**
  243. * Find the intersection between sets and store in a new set.
  244. *
  245. * @param string $output
  246. * @param array $keys
  247. * @param array $options
  248. * @return int
  249. */
  250. public function zinterstore($output, $keys, $options = [])
  251. {
  252. return $this->command('zinterstore', [$output, $keys,
  253. $options['weights'] ?? null,
  254. $options['aggregate'] ?? 'sum',
  255. ]);
  256. }
  257. /**
  258. * Find the union between sets and store in a new set.
  259. *
  260. * @param string $output
  261. * @param array $keys
  262. * @param array $options
  263. * @return int
  264. */
  265. public function zunionstore($output, $keys, $options = [])
  266. {
  267. return $this->command('zunionstore', [$output, $keys,
  268. $options['weights'] ?? null,
  269. $options['aggregate'] ?? 'sum',
  270. ]);
  271. }
  272. /**
  273. * Scans the all keys based on options.
  274. *
  275. * @param mixed $cursor
  276. * @param array $options
  277. * @return mixed
  278. */
  279. public function scan($cursor, $options = [])
  280. {
  281. $result = $this->client->scan($cursor,
  282. $options['match'] ?? '*',
  283. $options['count'] ?? 10
  284. );
  285. return empty($result) ? $result : [$cursor, $result];
  286. }
  287. /**
  288. * Scans the given set for all values based on options.
  289. *
  290. * @param string $key
  291. * @param mixed $cursor
  292. * @param array $options
  293. * @return mixed
  294. */
  295. public function zscan($key, $cursor, $options = [])
  296. {
  297. $result = $this->client->zscan($key, $cursor,
  298. $options['match'] ?? '*',
  299. $options['count'] ?? 10
  300. );
  301. return $result === false ? [0, []] : [$cursor, $result];
  302. }
  303. /**
  304. * Scans the given set for all values based on options.
  305. *
  306. * @param string $key
  307. * @param mixed $cursor
  308. * @param array $options
  309. * @return mixed
  310. */
  311. public function hscan($key, $cursor, $options = [])
  312. {
  313. $result = $this->client->hscan($key, $cursor,
  314. $options['match'] ?? '*',
  315. $options['count'] ?? 10
  316. );
  317. return $result === false ? [0, []] : [$cursor, $result];
  318. }
  319. /**
  320. * Scans the given set for all values based on options.
  321. *
  322. * @param string $key
  323. * @param mixed $cursor
  324. * @param array $options
  325. * @return mixed
  326. */
  327. public function sscan($key, $cursor, $options = [])
  328. {
  329. $result = $this->client->sscan($key, $cursor,
  330. $options['match'] ?? '*',
  331. $options['count'] ?? 10
  332. );
  333. return $result === false ? [0, []] : [$cursor, $result];
  334. }
  335. /**
  336. * Execute commands in a pipeline.
  337. *
  338. * @param callable|null $callback
  339. * @return \Redis|array
  340. */
  341. public function pipeline(callable $callback = null)
  342. {
  343. $pipeline = $this->client()->pipeline();
  344. return is_null($callback)
  345. ? $pipeline
  346. : tap($pipeline, $callback)->exec();
  347. }
  348. /**
  349. * Execute commands in a transaction.
  350. *
  351. * @param callable|null $callback
  352. * @return \Redis|array
  353. */
  354. public function transaction(callable $callback = null)
  355. {
  356. $transaction = $this->client()->multi();
  357. return is_null($callback)
  358. ? $transaction
  359. : tap($transaction, $callback)->exec();
  360. }
  361. /**
  362. * Evaluate a LUA script serverside, from the SHA1 hash of the script instead of the script itself.
  363. *
  364. * @param string $script
  365. * @param int $numkeys
  366. * @param mixed $arguments
  367. * @return mixed
  368. */
  369. public function evalsha($script, $numkeys, ...$arguments)
  370. {
  371. return $this->command('evalsha', [
  372. $this->script('load', $script), $arguments, $numkeys,
  373. ]);
  374. }
  375. /**
  376. * Evaluate a script and return its result.
  377. *
  378. * @param string $script
  379. * @param int $numberOfKeys
  380. * @param dynamic $arguments
  381. * @return mixed
  382. */
  383. public function eval($script, $numberOfKeys, ...$arguments)
  384. {
  385. return $this->command('eval', [$script, $arguments, $numberOfKeys]);
  386. }
  387. /**
  388. * Subscribe to a set of given channels for messages.
  389. *
  390. * @param array|string $channels
  391. * @param \Closure $callback
  392. * @return void
  393. */
  394. public function subscribe($channels, Closure $callback)
  395. {
  396. $this->client->subscribe((array) $channels, function ($redis, $channel, $message) use ($callback) {
  397. $callback($message, $channel);
  398. });
  399. }
  400. /**
  401. * Subscribe to a set of given channels with wildcards.
  402. *
  403. * @param array|string $channels
  404. * @param \Closure $callback
  405. * @return void
  406. */
  407. public function psubscribe($channels, Closure $callback)
  408. {
  409. $this->client->psubscribe((array) $channels, function ($redis, $pattern, $channel, $message) use ($callback) {
  410. $callback($message, $channel);
  411. });
  412. }
  413. /**
  414. * Subscribe to a set of given channels for messages.
  415. *
  416. * @param array|string $channels
  417. * @param \Closure $callback
  418. * @param string $method
  419. * @return void
  420. */
  421. public function createSubscription($channels, Closure $callback, $method = 'subscribe')
  422. {
  423. //
  424. }
  425. /**
  426. * Flush the selected Redis database.
  427. *
  428. * @return void
  429. */
  430. public function flushdb()
  431. {
  432. if (! $this->client instanceof RedisCluster) {
  433. return $this->command('flushdb');
  434. }
  435. foreach ($this->client->_masters() as $master) {
  436. $this->client->flushDb($master);
  437. }
  438. }
  439. /**
  440. * Execute a raw command.
  441. *
  442. * @param array $parameters
  443. * @return mixed
  444. */
  445. public function executeRaw(array $parameters)
  446. {
  447. return $this->command('rawCommand', $parameters);
  448. }
  449. /**
  450. * Run a command against the Redis database.
  451. *
  452. * @param string $method
  453. * @param array $parameters
  454. * @return mixed
  455. */
  456. public function command($method, array $parameters = [])
  457. {
  458. try {
  459. return parent::command($method, $parameters);
  460. } catch (RedisException $e) {
  461. if (Str::contains($e->getMessage(), 'went away')) {
  462. $this->client = $this->connector ? call_user_func($this->connector) : $this->client;
  463. }
  464. throw $e;
  465. }
  466. }
  467. /**
  468. * Disconnects from the Redis instance.
  469. *
  470. * @return void
  471. */
  472. public function disconnect()
  473. {
  474. $this->client->close();
  475. }
  476. /**
  477. * Apply prefix to the given key if necessary.
  478. *
  479. * @param string $key
  480. * @return string
  481. */
  482. private function applyPrefix($key)
  483. {
  484. $prefix = (string) $this->client->getOption(Redis::OPT_PREFIX);
  485. return $prefix.$key;
  486. }
  487. /**
  488. * Pass other method calls down to the underlying client.
  489. *
  490. * @param string $method
  491. * @param array $parameters
  492. * @return mixed
  493. */
  494. public function __call($method, $parameters)
  495. {
  496. return parent::__call(strtolower($method), $parameters);
  497. }
  498. }