Connection.php 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\redis;
  8. use yii\base\Component;
  9. use yii\db\Exception;
  10. use yii\helpers\ArrayHelper;
  11. use yii\helpers\Inflector;
  12. use yii\helpers\VarDumper;
  13. /**
  14. * The redis connection class is used to establish a connection to a [redis](https://redis.io/) server.
  15. *
  16. * By default it assumes there is a redis server running on localhost at port 6379 and uses the database number 0.
  17. *
  18. * It is possible to connect to a redis server using [[hostname]] and [[port]] or using a [[unixSocket]].
  19. *
  20. * It also supports [the AUTH command](https://redis.io/commands/auth) of redis.
  21. * When the server needs authentication, you can set the [[password]] property to
  22. * authenticate with the server after connect.
  23. *
  24. * The execution of [redis commands](https://redis.io/commands) is possible with via [[executeCommand()]].
  25. *
  26. * @method mixed append($key, $value) Append a value to a key. <https://redis.io/commands/append>
  27. * @method mixed auth($password) Authenticate to the server. <https://redis.io/commands/auth>
  28. * @method mixed bgrewriteaof() Asynchronously rewrite the append-only file. <https://redis.io/commands/bgrewriteaof>
  29. * @method mixed bgsave() Asynchronously save the dataset to disk. <https://redis.io/commands/bgsave>
  30. * @method mixed bitcount($key, $start = null, $end = null) Count set bits in a string. <https://redis.io/commands/bitcount>
  31. * @method mixed bitfield($key, ...$operations) Perform arbitrary bitfield integer operations on strings. <https://redis.io/commands/bitfield>
  32. * @method mixed bitop($operation, $destkey, ...$keys) Perform bitwise operations between strings. <https://redis.io/commands/bitop>
  33. * @method mixed bitpos($key, $bit, $start = null, $end = null) Find first bit set or clear in a string. <https://redis.io/commands/bitpos>
  34. * @method mixed blpop(...$keys, $timeout) Remove and get the first element in a list, or block until one is available. <https://redis.io/commands/blpop>
  35. * @method mixed brpop(...$keys, $timeout) Remove and get the last element in a list, or block until one is available. <https://redis.io/commands/brpop>
  36. * @method mixed brpoplpush($source, $destination, $timeout) Pop a value from a list, push it to another list and return it; or block until one is available. <https://redis.io/commands/brpoplpush>
  37. * @method mixed clientKill(...$filters) Kill the connection of a client. <https://redis.io/commands/client-kill>
  38. * @method mixed clientList() Get the list of client connections. <https://redis.io/commands/client-list>
  39. * @method mixed clientGetname() Get the current connection name. <https://redis.io/commands/client-getname>
  40. * @method mixed clientPause($timeout) Stop processing commands from clients for some time. <https://redis.io/commands/client-pause>
  41. * @method mixed clientReply($option) Instruct the server whether to reply to commands. <https://redis.io/commands/client-reply>
  42. * @method mixed clientSetname($connectionName) Set the current connection name. <https://redis.io/commands/client-setname>
  43. * @method mixed clusterAddslots(...$slots) Assign new hash slots to receiving node. <https://redis.io/commands/cluster-addslots>
  44. * @method mixed clusterCountkeysinslot($slot) Return the number of local keys in the specified hash slot. <https://redis.io/commands/cluster-countkeysinslot>
  45. * @method mixed clusterDelslots(...$slots) Set hash slots as unbound in receiving node. <https://redis.io/commands/cluster-delslots>
  46. * @method mixed clusterFailover($option = null) Forces a slave to perform a manual failover of its master.. <https://redis.io/commands/cluster-failover>
  47. * @method mixed clusterForget($nodeId) Remove a node from the nodes table. <https://redis.io/commands/cluster-forget>
  48. * @method mixed clusterGetkeysinslot($slot, $count) Return local key names in the specified hash slot. <https://redis.io/commands/cluster-getkeysinslot>
  49. * @method mixed clusterInfo() Provides info about Redis Cluster node state. <https://redis.io/commands/cluster-info>
  50. * @method mixed clusterKeyslot($key) Returns the hash slot of the specified key. <https://redis.io/commands/cluster-keyslot>
  51. * @method mixed clusterMeet($ip, $port) Force a node cluster to handshake with another node. <https://redis.io/commands/cluster-meet>
  52. * @method mixed clusterNodes() Get Cluster config for the node. <https://redis.io/commands/cluster-nodes>
  53. * @method mixed clusterReplicate($nodeId) Reconfigure a node as a slave of the specified master node. <https://redis.io/commands/cluster-replicate>
  54. * @method mixed clusterReset($resetType = "SOFT") Reset a Redis Cluster node. <https://redis.io/commands/cluster-reset>
  55. * @method mixed clusterSaveconfig() Forces the node to save cluster state on disk. <https://redis.io/commands/cluster-saveconfig>
  56. * @method mixed clusterSetslot($slot, $type, $nodeid = null) Bind a hash slot to a specific node. <https://redis.io/commands/cluster-setslot>
  57. * @method mixed clusterSlaves($nodeId) List slave nodes of the specified master node. <https://redis.io/commands/cluster-slaves>
  58. * @method mixed clusterSlots() Get array of Cluster slot to node mappings. <https://redis.io/commands/cluster-slots>
  59. * @method mixed command() Get array of Redis command details. <https://redis.io/commands/command>
  60. * @method mixed commandCount() Get total number of Redis commands. <https://redis.io/commands/command-count>
  61. * @method mixed commandGetkeys() Extract keys given a full Redis command. <https://redis.io/commands/command-getkeys>
  62. * @method mixed commandInfo(...$commandNames) Get array of specific Redis command details. <https://redis.io/commands/command-info>
  63. * @method mixed configGet($parameter) Get the value of a configuration parameter. <https://redis.io/commands/config-get>
  64. * @method mixed configRewrite() Rewrite the configuration file with the in memory configuration. <https://redis.io/commands/config-rewrite>
  65. * @method mixed configSet($parameter, $value) Set a configuration parameter to the given value. <https://redis.io/commands/config-set>
  66. * @method mixed configResetstat() Reset the stats returned by INFO. <https://redis.io/commands/config-resetstat>
  67. * @method mixed dbsize() Return the number of keys in the selected database. <https://redis.io/commands/dbsize>
  68. * @method mixed debugObject($key) Get debugging information about a key. <https://redis.io/commands/debug-object>
  69. * @method mixed debugSegfault() Make the server crash. <https://redis.io/commands/debug-segfault>
  70. * @method mixed decr($key) Decrement the integer value of a key by one. <https://redis.io/commands/decr>
  71. * @method mixed decrby($key, $decrement) Decrement the integer value of a key by the given number. <https://redis.io/commands/decrby>
  72. * @method mixed del(...$keys) Delete a key. <https://redis.io/commands/del>
  73. * @method mixed discard() Discard all commands issued after MULTI. <https://redis.io/commands/discard>
  74. * @method mixed dump($key) Return a serialized version of the value stored at the specified key.. <https://redis.io/commands/dump>
  75. * @method mixed echo($message) Echo the given string. <https://redis.io/commands/echo>
  76. * @method mixed eval($script, $numkeys, ...$keys, ...$args) Execute a Lua script server side. <https://redis.io/commands/eval>
  77. * @method mixed evalsha($sha1, $numkeys, ...$keys, ...$args) Execute a Lua script server side. <https://redis.io/commands/evalsha>
  78. * @method mixed exec() Execute all commands issued after MULTI. <https://redis.io/commands/exec>
  79. * @method mixed exists(...$keys) Determine if a key exists. <https://redis.io/commands/exists>
  80. * @method mixed expire($key, $seconds) Set a key's time to live in seconds. <https://redis.io/commands/expire>
  81. * @method mixed expireat($key, $timestamp) Set the expiration for a key as a UNIX timestamp. <https://redis.io/commands/expireat>
  82. * @method mixed flushall($ASYNC = null) Remove all keys from all databases. <https://redis.io/commands/flushall>
  83. * @method mixed flushdb($ASYNC = null) Remove all keys from the current database. <https://redis.io/commands/flushdb>
  84. * @method mixed geoadd($key, $longitude, $latitude, $member, ...$more) Add one or more geospatial items in the geospatial index represented using a sorted set. <https://redis.io/commands/geoadd>
  85. * @method mixed geohash($key, ...$members) Returns members of a geospatial index as standard geohash strings. <https://redis.io/commands/geohash>
  86. * @method mixed geopos($key, ...$members) Returns longitude and latitude of members of a geospatial index. <https://redis.io/commands/geopos>
  87. * @method mixed geodist($key, $member1, $member2, $unit = null) Returns the distance between two members of a geospatial index. <https://redis.io/commands/geodist>
  88. * @method mixed georadius($key, $longitude, $latitude, $radius, $metric, ...$options) Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point. <https://redis.io/commands/georadius>
  89. * @method mixed georadiusbymember($key, $member, $radius, $metric, ...$options) Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member. <https://redis.io/commands/georadiusbymember>
  90. * @method mixed get($key) Get the value of a key. <https://redis.io/commands/get>
  91. * @method mixed getbit($key, $offset) Returns the bit value at offset in the string value stored at key. <https://redis.io/commands/getbit>
  92. * @method mixed getrange($key, $start, $end) Get a substring of the string stored at a key. <https://redis.io/commands/getrange>
  93. * @method mixed getset($key, $value) Set the string value of a key and return its old value. <https://redis.io/commands/getset>
  94. * @method mixed hdel($key, ...$fields) Delete one or more hash fields. <https://redis.io/commands/hdel>
  95. * @method mixed hexists($key, $field) Determine if a hash field exists. <https://redis.io/commands/hexists>
  96. * @method mixed hget($key, $field) Get the value of a hash field. <https://redis.io/commands/hget>
  97. * @method mixed hgetall($key) Get all the fields and values in a hash. <https://redis.io/commands/hgetall>
  98. * @method mixed hincrby($key, $field, $increment) Increment the integer value of a hash field by the given number. <https://redis.io/commands/hincrby>
  99. * @method mixed hincrbyfloat($key, $field, $increment) Increment the float value of a hash field by the given amount. <https://redis.io/commands/hincrbyfloat>
  100. * @method mixed hkeys($key) Get all the fields in a hash. <https://redis.io/commands/hkeys>
  101. * @method mixed hlen($key) Get the number of fields in a hash. <https://redis.io/commands/hlen>
  102. * @method mixed hmget($key, ...$fields) Get the values of all the given hash fields. <https://redis.io/commands/hmget>
  103. * @method mixed hmset($key, $field, $value, ...$more) Set multiple hash fields to multiple values. <https://redis.io/commands/hmset>
  104. * @method mixed hset($key, $field, $value) Set the string value of a hash field. <https://redis.io/commands/hset>
  105. * @method mixed hsetnx($key, $field, $value) Set the value of a hash field, only if the field does not exist. <https://redis.io/commands/hsetnx>
  106. * @method mixed hstrlen($key, $field) Get the length of the value of a hash field. <https://redis.io/commands/hstrlen>
  107. * @method mixed hvals($key) Get all the values in a hash. <https://redis.io/commands/hvals>
  108. * @method mixed incr($key) Increment the integer value of a key by one. <https://redis.io/commands/incr>
  109. * @method mixed incrby($key, $increment) Increment the integer value of a key by the given amount. <https://redis.io/commands/incrby>
  110. * @method mixed incrbyfloat($key, $increment) Increment the float value of a key by the given amount. <https://redis.io/commands/incrbyfloat>
  111. * @method mixed info($section = null) Get information and statistics about the server. <https://redis.io/commands/info>
  112. * @method mixed keys($pattern) Find all keys matching the given pattern. <https://redis.io/commands/keys>
  113. * @method mixed lastsave() Get the UNIX time stamp of the last successful save to disk. <https://redis.io/commands/lastsave>
  114. * @method mixed lindex($key, $index) Get an element from a list by its index. <https://redis.io/commands/lindex>
  115. * @method mixed linsert($key, $where, $pivot, $value) Insert an element before or after another element in a list. <https://redis.io/commands/linsert>
  116. * @method mixed llen($key) Get the length of a list. <https://redis.io/commands/llen>
  117. * @method mixed lpop($key) Remove and get the first element in a list. <https://redis.io/commands/lpop>
  118. * @method mixed lpush($key, ...$values) Prepend one or multiple values to a list. <https://redis.io/commands/lpush>
  119. * @method mixed lpushx($key, $value) Prepend a value to a list, only if the list exists. <https://redis.io/commands/lpushx>
  120. * @method mixed lrange($key, $start, $stop) Get a range of elements from a list. <https://redis.io/commands/lrange>
  121. * @method mixed lrem($key, $count, $value) Remove elements from a list. <https://redis.io/commands/lrem>
  122. * @method mixed lset($key, $index, $value) Set the value of an element in a list by its index. <https://redis.io/commands/lset>
  123. * @method mixed ltrim($key, $start, $stop) Trim a list to the specified range. <https://redis.io/commands/ltrim>
  124. * @method mixed mget(...$keys) Get the values of all the given keys. <https://redis.io/commands/mget>
  125. * @method mixed migrate($host, $port, $key, $destinationDb, $timeout, ...$options) Atomically transfer a key from a Redis instance to another one.. <https://redis.io/commands/migrate>
  126. * @method mixed monitor() Listen for all requests received by the server in real time. <https://redis.io/commands/monitor>
  127. * @method mixed move($key, $db) Move a key to another database. <https://redis.io/commands/move>
  128. * @method mixed mset(...$keyValuePairs) Set multiple keys to multiple values. <https://redis.io/commands/mset>
  129. * @method mixed msetnx(...$keyValuePairs) Set multiple keys to multiple values, only if none of the keys exist. <https://redis.io/commands/msetnx>
  130. * @method mixed multi() Mark the start of a transaction block. <https://redis.io/commands/multi>
  131. * @method mixed object($subcommand, ...$argumentss) Inspect the internals of Redis objects. <https://redis.io/commands/object>
  132. * @method mixed persist($key) Remove the expiration from a key. <https://redis.io/commands/persist>
  133. * @method mixed pexpire($key, $milliseconds) Set a key's time to live in milliseconds. <https://redis.io/commands/pexpire>
  134. * @method mixed pexpireat($key, $millisecondsTimestamp) Set the expiration for a key as a UNIX timestamp specified in milliseconds. <https://redis.io/commands/pexpireat>
  135. * @method mixed pfadd($key, ...$elements) Adds the specified elements to the specified HyperLogLog.. <https://redis.io/commands/pfadd>
  136. * @method mixed pfcount(...$keys) Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s).. <https://redis.io/commands/pfcount>
  137. * @method mixed pfmerge($destkey, ...$sourcekeys) Merge N different HyperLogLogs into a single one.. <https://redis.io/commands/pfmerge>
  138. * @method mixed ping($message = null) Ping the server. <https://redis.io/commands/ping>
  139. * @method mixed psetex($key, $milliseconds, $value) Set the value and expiration in milliseconds of a key. <https://redis.io/commands/psetex>
  140. * @method mixed psubscribe(...$patterns) Listen for messages published to channels matching the given patterns. <https://redis.io/commands/psubscribe>
  141. * @method mixed pubsub($subcommand, ...$arguments) Inspect the state of the Pub/Sub subsystem. <https://redis.io/commands/pubsub>
  142. * @method mixed pttl($key) Get the time to live for a key in milliseconds. <https://redis.io/commands/pttl>
  143. * @method mixed publish($channel, $message) Post a message to a channel. <https://redis.io/commands/publish>
  144. * @method mixed punsubscribe(...$patterns) Stop listening for messages posted to channels matching the given patterns. <https://redis.io/commands/punsubscribe>
  145. * @method mixed quit() Close the connection. <https://redis.io/commands/quit>
  146. * @method mixed randomkey() Return a random key from the keyspace. <https://redis.io/commands/randomkey>
  147. * @method mixed readonly() Enables read queries for a connection to a cluster slave node. <https://redis.io/commands/readonly>
  148. * @method mixed readwrite() Disables read queries for a connection to a cluster slave node. <https://redis.io/commands/readwrite>
  149. * @method mixed rename($key, $newkey) Rename a key. <https://redis.io/commands/rename>
  150. * @method mixed renamenx($key, $newkey) Rename a key, only if the new key does not exist. <https://redis.io/commands/renamenx>
  151. * @method mixed restore($key, $ttl, $serializedValue, $REPLACE = null) Create a key using the provided serialized value, previously obtained using DUMP.. <https://redis.io/commands/restore>
  152. * @method mixed role() Return the role of the instance in the context of replication. <https://redis.io/commands/role>
  153. * @method mixed rpop($key) Remove and get the last element in a list. <https://redis.io/commands/rpop>
  154. * @method mixed rpoplpush($source, $destination) Remove the last element in a list, prepend it to another list and return it. <https://redis.io/commands/rpoplpush>
  155. * @method mixed rpush($key, ...$values) Append one or multiple values to a list. <https://redis.io/commands/rpush>
  156. * @method mixed rpushx($key, $value) Append a value to a list, only if the list exists. <https://redis.io/commands/rpushx>
  157. * @method mixed sadd($key, ...$members) Add one or more members to a set. <https://redis.io/commands/sadd>
  158. * @method mixed save() Synchronously save the dataset to disk. <https://redis.io/commands/save>
  159. * @method mixed scard($key) Get the number of members in a set. <https://redis.io/commands/scard>
  160. * @method mixed scriptDebug($option) Set the debug mode for executed scripts.. <https://redis.io/commands/script-debug>
  161. * @method mixed scriptExists(...$sha1s) Check existence of scripts in the script cache.. <https://redis.io/commands/script-exists>
  162. * @method mixed scriptFlush() Remove all the scripts from the script cache.. <https://redis.io/commands/script-flush>
  163. * @method mixed scriptKill() Kill the script currently in execution.. <https://redis.io/commands/script-kill>
  164. * @method mixed scriptLoad($script) Load the specified Lua script into the script cache.. <https://redis.io/commands/script-load>
  165. * @method mixed sdiff(...$keys) Subtract multiple sets. <https://redis.io/commands/sdiff>
  166. * @method mixed sdiffstore($destination, ...$keys) Subtract multiple sets and store the resulting set in a key. <https://redis.io/commands/sdiffstore>
  167. * @method mixed select($index) Change the selected database for the current connection. <https://redis.io/commands/select>
  168. * @method mixed set($key, $value, ...$options) Set the string value of a key. <https://redis.io/commands/set>
  169. * @method mixed setbit($key, $offset, $value) Sets or clears the bit at offset in the string value stored at key. <https://redis.io/commands/setbit>
  170. * @method mixed setex($key, $seconds, $value) Set the value and expiration of a key. <https://redis.io/commands/setex>
  171. * @method mixed setnx($key, $value) Set the value of a key, only if the key does not exist. <https://redis.io/commands/setnx>
  172. * @method mixed setrange($key, $offset, $value) Overwrite part of a string at key starting at the specified offset. <https://redis.io/commands/setrange>
  173. * @method mixed shutdown($saveOption = null) Synchronously save the dataset to disk and then shut down the server. <https://redis.io/commands/shutdown>
  174. * @method mixed sinter(...$keys) Intersect multiple sets. <https://redis.io/commands/sinter>
  175. * @method mixed sinterstore($destination, ...$keys) Intersect multiple sets and store the resulting set in a key. <https://redis.io/commands/sinterstore>
  176. * @method mixed sismember($key, $member) Determine if a given value is a member of a set. <https://redis.io/commands/sismember>
  177. * @method mixed slaveof($host, $port) Make the server a slave of another instance, or promote it as master. <https://redis.io/commands/slaveof>
  178. * @method mixed slowlog($subcommand, $argument = null) Manages the Redis slow queries log. <https://redis.io/commands/slowlog>
  179. * @method mixed smembers($key) Get all the members in a set. <https://redis.io/commands/smembers>
  180. * @method mixed smove($source, $destination, $member) Move a member from one set to another. <https://redis.io/commands/smove>
  181. * @method mixed sort($key, ...$options) Sort the elements in a list, set or sorted set. <https://redis.io/commands/sort>
  182. * @method mixed spop($key, $count = null) Remove and return one or multiple random members from a set. <https://redis.io/commands/spop>
  183. * @method mixed srandmember($key, $count = null) Get one or multiple random members from a set. <https://redis.io/commands/srandmember>
  184. * @method mixed srem($key, ...$members) Remove one or more members from a set. <https://redis.io/commands/srem>
  185. * @method mixed strlen($key) Get the length of the value stored in a key. <https://redis.io/commands/strlen>
  186. * @method mixed subscribe(...$channels) Listen for messages published to the given channels. <https://redis.io/commands/subscribe>
  187. * @method mixed sunion(...$keys) Add multiple sets. <https://redis.io/commands/sunion>
  188. * @method mixed sunionstore($destination, ...$keys) Add multiple sets and store the resulting set in a key. <https://redis.io/commands/sunionstore>
  189. * @method mixed swapdb($index, $index) Swaps two Redis databases. <https://redis.io/commands/swapdb>
  190. * @method mixed sync() Internal command used for replication. <https://redis.io/commands/sync>
  191. * @method mixed time() Return the current server time. <https://redis.io/commands/time>
  192. * @method mixed touch(...$keys) Alters the last access time of a key(s). Returns the number of existing keys specified.. <https://redis.io/commands/touch>
  193. * @method mixed ttl($key) Get the time to live for a key. <https://redis.io/commands/ttl>
  194. * @method mixed type($key) Determine the type stored at key. <https://redis.io/commands/type>
  195. * @method mixed unsubscribe(...$channels) Stop listening for messages posted to the given channels. <https://redis.io/commands/unsubscribe>
  196. * @method mixed unlink(...$keys) Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.. <https://redis.io/commands/unlink>
  197. * @method mixed unwatch() Forget about all watched keys. <https://redis.io/commands/unwatch>
  198. * @method mixed wait($numslaves, $timeout) Wait for the synchronous replication of all the write commands sent in the context of the current connection. <https://redis.io/commands/wait>
  199. * @method mixed watch(...$keys) Watch the given keys to determine execution of the MULTI/EXEC block. <https://redis.io/commands/watch>
  200. * @method mixed xack($stream, $group, ...$ids) Removes one or multiple messages from the pending entries list (PEL) of a stream consumer group <https://redis.io/commands/xack>
  201. * @method mixed xadd($stream, $id, $field, $value, ...$fieldsValues) Appends the specified stream entry to the stream at the specified key <https://redis.io/commands/xadd>
  202. * @method mixed xclaim($stream, $group, $consumer, $minIdleTimeMs, $id, ...$options) Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument <https://redis.io/commands/xclaim>
  203. * @method mixed xdel($stream, ...$ids) Removes the specified entries from a stream, and returns the number of entries deleted <https://redis.io/commands/xdel>
  204. * @method mixed xgroup($subCommand, $stream, $group, ...$options) Manages the consumer groups associated with a stream data structure <https://redis.io/commands/xgroup>
  205. * @method mixed xinfo($subCommand, $stream, ...$options) Retrieves different information about the streams and associated consumer groups <https://redis.io/commands/xinfo>
  206. * @method mixed xlen($stream) Returns the number of entries inside a stream <https://redis.io/commands/xlen>
  207. * @method mixed xpending($stream, $group, ...$options) Fetching data from a stream via a consumer group, and not acknowledging such data, has the effect of creating pending entries <https://redis.io/commands/xpending>
  208. * @method mixed xrange($stream, $start, $end, ...$options) Returns the stream entries matching a given range of IDs <https://redis.io/commands/xrange>
  209. * @method mixed xread(...$options) Read data from one or multiple streams, only returning entries with an ID greater than the last received ID reported by the caller <https://redis.io/commands/xread>
  210. * @method mixed xreadgroup($subCommand, $group, $consumer, ...$options) Special version of the XREAD command with support for consumer groups <https://redis.io/commands/xreadgroup>
  211. * @method mixed xrevrange($stream, $end, $start, ...$options) Exactly like XRANGE, but with the notable difference of returning the entries in reverse order, and also taking the start-end range in reverse order <https://redis.io/commands/xrevrange>
  212. * @method mixed xtrim($stream, $strategy, ...$options) Trims the stream to a given number of items, evicting older items (items with lower IDs) if needed <https://redis.io/commands/xtrim>
  213. * @method mixed zadd($key, ...$options) Add one or more members to a sorted set, or update its score if it already exists. <https://redis.io/commands/zadd>
  214. * @method mixed zcard($key) Get the number of members in a sorted set. <https://redis.io/commands/zcard>
  215. * @method mixed zcount($key, $min, $max) Count the members in a sorted set with scores within the given values. <https://redis.io/commands/zcount>
  216. * @method mixed zincrby($key, $increment, $member) Increment the score of a member in a sorted set. <https://redis.io/commands/zincrby>
  217. * @method mixed zinterstore($destination, $numkeys, $key, ...$options) Intersect multiple sorted sets and store the resulting sorted set in a new key. <https://redis.io/commands/zinterstore>
  218. * @method mixed zlexcount($key, $min, $max) Count the number of members in a sorted set between a given lexicographical range. <https://redis.io/commands/zlexcount>
  219. * @method mixed zrange($key, $start, $stop, $WITHSCORES = null) Return a range of members in a sorted set, by index. <https://redis.io/commands/zrange>
  220. * @method mixed zrangebylex($key, $min, $max, $LIMIT = null, $offset = null, $count = null) Return a range of members in a sorted set, by lexicographical range. <https://redis.io/commands/zrangebylex>
  221. * @method mixed zrevrangebylex($key, $max, $min, $LIMIT = null, $offset = null, $count = null) Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings.. <https://redis.io/commands/zrevrangebylex>
  222. * @method mixed zrangebyscore($key, $min, $max, ...$options) Return a range of members in a sorted set, by score. <https://redis.io/commands/zrangebyscore>
  223. * @method mixed zrank($key, $member) Determine the index of a member in a sorted set. <https://redis.io/commands/zrank>
  224. * @method mixed zrem($key, ...$members) Remove one or more members from a sorted set. <https://redis.io/commands/zrem>
  225. * @method mixed zremrangebylex($key, $min, $max) Remove all members in a sorted set between the given lexicographical range. <https://redis.io/commands/zremrangebylex>
  226. * @method mixed zremrangebyrank($key, $start, $stop) Remove all members in a sorted set within the given indexes. <https://redis.io/commands/zremrangebyrank>
  227. * @method mixed zremrangebyscore($key, $min, $max) Remove all members in a sorted set within the given scores. <https://redis.io/commands/zremrangebyscore>
  228. * @method mixed zrevrange($key, $start, $stop, $WITHSCORES = null) Return a range of members in a sorted set, by index, with scores ordered from high to low. <https://redis.io/commands/zrevrange>
  229. * @method mixed zrevrangebyscore($key, $max, $min, $WITHSCORES = null, $LIMIT = null, $offset = null, $count = null) Return a range of members in a sorted set, by score, with scores ordered from high to low. <https://redis.io/commands/zrevrangebyscore>
  230. * @method mixed zrevrank($key, $member) Determine the index of a member in a sorted set, with scores ordered from high to low. <https://redis.io/commands/zrevrank>
  231. * @method mixed zscore($key, $member) Get the score associated with the given member in a sorted set. <https://redis.io/commands/zscore>
  232. * @method mixed zunionstore($destination, $numkeys, $key, ...$options) Add multiple sorted sets and store the resulting sorted set in a new key. <https://redis.io/commands/zunionstore>
  233. * @method mixed scan($cursor, $MATCH = null, $pattern = null, $COUNT = null, $count = null) Incrementally iterate the keys space. <https://redis.io/commands/scan>
  234. * @method mixed sscan($key, $cursor, $MATCH = null, $pattern = null, $COUNT = null, $count = null) Incrementally iterate Set elements. <https://redis.io/commands/sscan>
  235. * @method mixed hscan($key, $cursor, $MATCH = null, $pattern = null, $COUNT = null, $count = null) Incrementally iterate hash fields and associated values. <https://redis.io/commands/hscan>
  236. * @method mixed zscan($key, $cursor, $MATCH = null, $pattern = null, $COUNT = null, $count = null) Incrementally iterate sorted sets elements and associated scores. <https://redis.io/commands/zscan>
  237. *
  238. * @property-read string $connectionString Socket connection string.
  239. * @property-read string $driverName Name of the DB driver.
  240. * @property-read bool $isActive Whether the DB connection is established.
  241. * @property-read LuaScriptBuilder $luaScriptBuilder
  242. * @property-read resource|false $socket
  243. *
  244. * @author Carsten Brandt <mail@cebe.cc>
  245. * @since 2.0
  246. */
  247. class Connection extends Component
  248. {
  249. /**
  250. * @event Event an event that is triggered after a DB connection is established
  251. */
  252. const EVENT_AFTER_OPEN = 'afterOpen';
  253. /**
  254. * @var string the hostname or ip address to use for connecting to the redis server. Defaults to 'localhost'.
  255. * If [[unixSocket]] is specified, hostname and [[port]] will be ignored.
  256. */
  257. public $hostname = 'localhost';
  258. /**
  259. * @var string if the query gets redirected, use this as the temporary new hostname
  260. * @since 2.0.11
  261. */
  262. public $redirectConnectionString;
  263. /**
  264. * @var integer the port to use for connecting to the redis server. Default port is 6379.
  265. * If [[unixSocket]] is specified, [[hostname]] and port will be ignored.
  266. */
  267. public $port = 6379;
  268. /**
  269. * @var string the unix socket path (e.g. `/var/run/redis/redis.sock`) to use for connecting to the redis server.
  270. * This can be used instead of [[hostname]] and [[port]] to connect to the server using a unix socket.
  271. * If a unix socket path is specified, [[hostname]] and [[port]] will be ignored.
  272. * @since 2.0.1
  273. */
  274. public $unixSocket;
  275. /**
  276. * @var string|null username for establishing DB connection. Defaults to `null` meaning AUTH command will be performed without username.
  277. * Username was introduced in Redis 6.
  278. * @link https://redis.io/commands/auth
  279. * @link https://redis.io/topics/acl
  280. * @since 2.0.16
  281. */
  282. public $username;
  283. /**
  284. * @var string the password for establishing DB connection. Defaults to null meaning no AUTH command is sent.
  285. * See https://redis.io/commands/auth
  286. */
  287. public $password;
  288. /**
  289. * @var integer the redis database to use. This is an integer value starting from 0. Defaults to 0.
  290. * Since version 2.0.6 you can disable the SELECT command sent after connection by setting this property to `null`.
  291. */
  292. public $database = 0;
  293. /**
  294. * @var float timeout to use for connection to redis. If not set the timeout set in php.ini will be used: `ini_get("default_socket_timeout")`.
  295. */
  296. public $connectionTimeout;
  297. /**
  298. * @var float timeout to use for redis socket when reading and writing data. If not set the php default value will be used.
  299. */
  300. public $dataTimeout;
  301. /**
  302. * @var boolean Send sockets over SSL protocol. Default state is false.
  303. * @since 2.0.12
  304. */
  305. public $useSSL = false;
  306. /**
  307. * @var array PHP context options which are used in the Redis connection stream.
  308. * @see https://www.php.net/manual/en/context.ssl.php
  309. * @since 2.0.15
  310. */
  311. public $contextOptions = [];
  312. /**
  313. * @var integer Bitmask field which may be set to any combination of connection flags passed to [stream_socket_client()](https://www.php.net/manual/en/function.stream-socket-client.php).
  314. * Currently the select of connection flags is limited to `STREAM_CLIENT_CONNECT` (default), `STREAM_CLIENT_ASYNC_CONNECT` and `STREAM_CLIENT_PERSISTENT`.
  315. *
  316. * > Warning: `STREAM_CLIENT_PERSISTENT` will make PHP reuse connections to the same server. If you are using multiple
  317. * > connection objects to refer to different redis [[$database|databases]] on the same [[port]], redis commands may
  318. * > get executed on the wrong database. `STREAM_CLIENT_PERSISTENT` is only safe to use if you use only one database.
  319. * >
  320. * > You may still use persistent connections in this case when disambiguating ports as described
  321. * > in [a comment on the PHP manual](https://www.php.net/manual/en/function.stream-socket-client.php#105393)
  322. * > e.g. on the connection used for session storage, specify the port as:
  323. * >
  324. * > ```php
  325. * > 'port' => '6379/session'
  326. * > ```
  327. *
  328. * @see https://www.php.net/manual/en/function.stream-socket-client.php
  329. * @since 2.0.5
  330. */
  331. public $socketClientFlags = STREAM_CLIENT_CONNECT;
  332. /**
  333. * @var integer The number of times a command execution should be retried when a connection failure occurs.
  334. * This is used in [[executeCommand()]] when a [[SocketException]] is thrown.
  335. * Defaults to 0 meaning no retries on failure.
  336. * @since 2.0.7
  337. */
  338. public $retries = 0;
  339. /**
  340. * @var integer The retry interval in microseconds to wait between retry.
  341. * This is used in [[executeCommand()]] when a [[SocketException]] is thrown.
  342. * Defaults to 0 meaning no wait.
  343. * @since 2.0.10
  344. */
  345. public $retryInterval = 0;
  346. /**
  347. * @var array List of available redis commands.
  348. * @see https://redis.io/commands
  349. */
  350. public $redisCommands = [
  351. 'APPEND', // Append a value to a key
  352. 'AUTH', // Authenticate to the server
  353. 'BGREWRITEAOF', // Asynchronously rewrite the append-only file
  354. 'BGSAVE', // Asynchronously save the dataset to disk
  355. 'BITCOUNT', // Count set bits in a string
  356. 'BITFIELD', // Perform arbitrary bitfield integer operations on strings
  357. 'BITOP', // Perform bitwise operations between strings
  358. 'BITPOS', // Find first bit set or clear in a string
  359. 'BLPOP', // Remove and get the first element in a list, or block until one is available
  360. 'BRPOP', // Remove and get the last element in a list, or block until one is available
  361. 'BRPOPLPUSH', // Pop a value from a list, push it to another list and return it; or block until one is available
  362. 'CLIENT KILL', // Kill the connection of a client
  363. 'CLIENT LIST', // Get the list of client connections
  364. 'CLIENT GETNAME', // Get the current connection name
  365. 'CLIENT PAUSE', // Stop processing commands from clients for some time
  366. 'CLIENT REPLY', // Instruct the server whether to reply to commands
  367. 'CLIENT SETNAME', // Set the current connection name
  368. 'CLUSTER ADDSLOTS', // Assign new hash slots to receiving node
  369. 'CLUSTER COUNTKEYSINSLOT', // Return the number of local keys in the specified hash slot
  370. 'CLUSTER DELSLOTS', // Set hash slots as unbound in receiving node
  371. 'CLUSTER FAILOVER', // Forces a slave to perform a manual failover of its master.
  372. 'CLUSTER FORGET', // Remove a node from the nodes table
  373. 'CLUSTER GETKEYSINSLOT', // Return local key names in the specified hash slot
  374. 'CLUSTER INFO', // Provides info about Redis Cluster node state
  375. 'CLUSTER KEYSLOT', // Returns the hash slot of the specified key
  376. 'CLUSTER MEET', // Force a node cluster to handshake with another node
  377. 'CLUSTER NODES', // Get Cluster config for the node
  378. 'CLUSTER REPLICATE', // Reconfigure a node as a slave of the specified master node
  379. 'CLUSTER RESET', // Reset a Redis Cluster node
  380. 'CLUSTER SAVECONFIG', // Forces the node to save cluster state on disk
  381. 'CLUSTER SETSLOT', // Bind a hash slot to a specific node
  382. 'CLUSTER SLAVES', // List slave nodes of the specified master node
  383. 'CLUSTER SLOTS', // Get array of Cluster slot to node mappings
  384. 'COMMAND', // Get array of Redis command details
  385. 'COMMAND COUNT', // Get total number of Redis commands
  386. 'COMMAND GETKEYS', // Extract keys given a full Redis command
  387. 'COMMAND INFO', // Get array of specific Redis command details
  388. 'CONFIG GET', // Get the value of a configuration parameter
  389. 'CONFIG REWRITE', // Rewrite the configuration file with the in memory configuration
  390. 'CONFIG SET', // Set a configuration parameter to the given value
  391. 'CONFIG RESETSTAT', // Reset the stats returned by INFO
  392. 'DBSIZE', // Return the number of keys in the selected database
  393. 'DEBUG OBJECT', // Get debugging information about a key
  394. 'DEBUG SEGFAULT', // Make the server crash
  395. 'DECR', // Decrement the integer value of a key by one
  396. 'DECRBY', // Decrement the integer value of a key by the given number
  397. 'DEL', // Delete a key
  398. 'DISCARD', // Discard all commands issued after MULTI
  399. 'DUMP', // Return a serialized version of the value stored at the specified key.
  400. 'ECHO', // Echo the given string
  401. 'EVAL', // Execute a Lua script server side
  402. 'EVALSHA', // Execute a Lua script server side
  403. 'EXEC', // Execute all commands issued after MULTI
  404. 'EXISTS', // Determine if a key exists
  405. 'EXPIRE', // Set a key's time to live in seconds
  406. 'EXPIREAT', // Set the expiration for a key as a UNIX timestamp
  407. 'FLUSHALL', // Remove all keys from all databases
  408. 'FLUSHDB', // Remove all keys from the current database
  409. 'GEOADD', // Add one or more geospatial items in the geospatial index represented using a sorted set
  410. 'GEOHASH', // Returns members of a geospatial index as standard geohash strings
  411. 'GEOPOS', // Returns longitude and latitude of members of a geospatial index
  412. 'GEODIST', // Returns the distance between two members of a geospatial index
  413. 'GEORADIUS', // Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point
  414. 'GEORADIUSBYMEMBER', // Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member
  415. 'GET', // Get the value of a key
  416. 'GETBIT', // Returns the bit value at offset in the string value stored at key
  417. 'GETRANGE', // Get a substring of the string stored at a key
  418. 'GETSET', // Set the string value of a key and return its old value
  419. 'HDEL', // Delete one or more hash fields
  420. 'HEXISTS', // Determine if a hash field exists
  421. 'HGET', // Get the value of a hash field
  422. 'HGETALL', // Get all the fields and values in a hash
  423. 'HINCRBY', // Increment the integer value of a hash field by the given number
  424. 'HINCRBYFLOAT', // Increment the float value of a hash field by the given amount
  425. 'HKEYS', // Get all the fields in a hash
  426. 'HLEN', // Get the number of fields in a hash
  427. 'HMGET', // Get the values of all the given hash fields
  428. 'HMSET', // Set multiple hash fields to multiple values
  429. 'HSET', // Set the string value of a hash field
  430. 'HSETNX', // Set the value of a hash field, only if the field does not exist
  431. 'HSTRLEN', // Get the length of the value of a hash field
  432. 'HVALS', // Get all the values in a hash
  433. 'INCR', // Increment the integer value of a key by one
  434. 'INCRBY', // Increment the integer value of a key by the given amount
  435. 'INCRBYFLOAT', // Increment the float value of a key by the given amount
  436. 'INFO', // Get information and statistics about the server
  437. 'KEYS', // Find all keys matching the given pattern
  438. 'LASTSAVE', // Get the UNIX time stamp of the last successful save to disk
  439. 'LINDEX', // Get an element from a list by its index
  440. 'LINSERT', // Insert an element before or after another element in a list
  441. 'LLEN', // Get the length of a list
  442. 'LPOP', // Remove and get the first element in a list
  443. 'LPUSH', // Prepend one or multiple values to a list
  444. 'LPUSHX', // Prepend a value to a list, only if the list exists
  445. 'LRANGE', // Get a range of elements from a list
  446. 'LREM', // Remove elements from a list
  447. 'LSET', // Set the value of an element in a list by its index
  448. 'LTRIM', // Trim a list to the specified range
  449. 'MGET', // Get the values of all the given keys
  450. 'MIGRATE', // Atomically transfer a key from a Redis instance to another one.
  451. 'MONITOR', // Listen for all requests received by the server in real time
  452. 'MOVE', // Move a key to another database
  453. 'MSET', // Set multiple keys to multiple values
  454. 'MSETNX', // Set multiple keys to multiple values, only if none of the keys exist
  455. 'MULTI', // Mark the start of a transaction block
  456. 'OBJECT', // Inspect the internals of Redis objects
  457. 'PERSIST', // Remove the expiration from a key
  458. 'PEXPIRE', // Set a key's time to live in milliseconds
  459. 'PEXPIREAT', // Set the expiration for a key as a UNIX timestamp specified in milliseconds
  460. 'PFADD', // Adds the specified elements to the specified HyperLogLog.
  461. 'PFCOUNT', // Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s).
  462. 'PFMERGE', // Merge N different HyperLogLogs into a single one.
  463. 'PING', // Ping the server
  464. 'PSETEX', // Set the value and expiration in milliseconds of a key
  465. 'PSUBSCRIBE', // Listen for messages published to channels matching the given patterns
  466. 'PUBSUB', // Inspect the state of the Pub/Sub subsystem
  467. 'PTTL', // Get the time to live for a key in milliseconds
  468. 'PUBLISH', // Post a message to a channel
  469. 'PUNSUBSCRIBE', // Stop listening for messages posted to channels matching the given patterns
  470. 'QUIT', // Close the connection
  471. 'RANDOMKEY', // Return a random key from the keyspace
  472. 'READONLY', // Enables read queries for a connection to a cluster slave node
  473. 'READWRITE', // Disables read queries for a connection to a cluster slave node
  474. 'RENAME', // Rename a key
  475. 'RENAMENX', // Rename a key, only if the new key does not exist
  476. 'RESTORE', // Create a key using the provided serialized value, previously obtained using DUMP.
  477. 'ROLE', // Return the role of the instance in the context of replication
  478. 'RPOP', // Remove and get the last element in a list
  479. 'RPOPLPUSH', // Remove the last element in a list, prepend it to another list and return it
  480. 'RPUSH', // Append one or multiple values to a list
  481. 'RPUSHX', // Append a value to a list, only if the list exists
  482. 'SADD', // Add one or more members to a set
  483. 'SAVE', // Synchronously save the dataset to disk
  484. 'SCARD', // Get the number of members in a set
  485. 'SCRIPT DEBUG', // Set the debug mode for executed scripts.
  486. 'SCRIPT EXISTS', // Check existence of scripts in the script cache.
  487. 'SCRIPT FLUSH', // Remove all the scripts from the script cache.
  488. 'SCRIPT KILL', // Kill the script currently in execution.
  489. 'SCRIPT LOAD', // Load the specified Lua script into the script cache.
  490. 'SDIFF', // Subtract multiple sets
  491. 'SDIFFSTORE', // Subtract multiple sets and store the resulting set in a key
  492. 'SELECT', // Change the selected database for the current connection
  493. 'SET', // Set the string value of a key
  494. 'SETBIT', // Sets or clears the bit at offset in the string value stored at key
  495. 'SETEX', // Set the value and expiration of a key
  496. 'SETNX', // Set the value of a key, only if the key does not exist
  497. 'SETRANGE', // Overwrite part of a string at key starting at the specified offset
  498. 'SHUTDOWN', // Synchronously save the dataset to disk and then shut down the server
  499. 'SINTER', // Intersect multiple sets
  500. 'SINTERSTORE', // Intersect multiple sets and store the resulting set in a key
  501. 'SISMEMBER', // Determine if a given value is a member of a set
  502. 'SLAVEOF', // Make the server a slave of another instance, or promote it as master
  503. 'SLOWLOG', // Manages the Redis slow queries log
  504. 'SMEMBERS', // Get all the members in a set
  505. 'SMOVE', // Move a member from one set to another
  506. 'SORT', // Sort the elements in a list, set or sorted set
  507. 'SPOP', // Remove and return one or multiple random members from a set
  508. 'SRANDMEMBER', // Get one or multiple random members from a set
  509. 'SREM', // Remove one or more members from a set
  510. 'STRLEN', // Get the length of the value stored in a key
  511. 'SUBSCRIBE', // Listen for messages published to the given channels
  512. 'SUNION', // Add multiple sets
  513. 'SUNIONSTORE', // Add multiple sets and store the resulting set in a key
  514. 'SWAPDB', // Swaps two Redis databases
  515. 'SYNC', // Internal command used for replication
  516. 'TIME', // Return the current server time
  517. 'TOUCH', // Alters the last access time of a key(s). Returns the number of existing keys specified.
  518. 'TTL', // Get the time to live for a key
  519. 'TYPE', // Determine the type stored at key
  520. 'UNSUBSCRIBE', // Stop listening for messages posted to the given channels
  521. 'UNLINK', // Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking.
  522. 'UNWATCH', // Forget about all watched keys
  523. 'WAIT', // Wait for the synchronous replication of all the write commands sent in the context of the current connection
  524. 'WATCH', // Watch the given keys to determine execution of the MULTI/EXEC block
  525. 'XACK', // Removes one or multiple messages from the pending entries list (PEL) of a stream consumer group
  526. 'XADD', // Appends the specified stream entry to the stream at the specified key
  527. 'XCLAIM', // Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument
  528. 'XDEL', // Removes the specified entries from a stream, and returns the number of entries deleted
  529. 'XGROUP', // Manages the consumer groups associated with a stream data structure
  530. 'XINFO', // Retrieves different information about the streams and associated consumer groups
  531. 'XLEN', // Returns the number of entries inside a stream
  532. 'XPENDING', // Fetching data from a stream via a consumer group, and not acknowledging such data, has the effect of creating pending entries
  533. 'XRANGE', // Returns the stream entries matching a given range of IDs
  534. 'XREAD', // Read data from one or multiple streams, only returning entries with an ID greater than the last received ID reported by the caller
  535. 'XREADGROUP', // Special version of the XREAD command with support for consumer groups
  536. 'XREVRANGE', // Exactly like XRANGE, but with the notable difference of returning the entries in reverse order, and also taking the start-end range in reverse order
  537. 'XTRIM', // Trims the stream to a given number of items, evicting older items (items with lower IDs) if needed
  538. 'ZADD', // Add one or more members to a sorted set, or update its score if it already exists
  539. 'ZCARD', // Get the number of members in a sorted set
  540. 'ZCOUNT', // Count the members in a sorted set with scores within the given values
  541. 'ZINCRBY', // Increment the score of a member in a sorted set
  542. 'ZINTERSTORE', // Intersect multiple sorted sets and store the resulting sorted set in a new key
  543. 'ZLEXCOUNT', // Count the number of members in a sorted set between a given lexicographical range
  544. 'ZRANGE', // Return a range of members in a sorted set, by index
  545. 'ZRANGEBYLEX', // Return a range of members in a sorted set, by lexicographical range
  546. 'ZREVRANGEBYLEX', // Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings.
  547. 'ZRANGEBYSCORE', // Return a range of members in a sorted set, by score
  548. 'ZRANK', // Determine the index of a member in a sorted set
  549. 'ZREM', // Remove one or more members from a sorted set
  550. 'ZREMRANGEBYLEX', // Remove all members in a sorted set between the given lexicographical range
  551. 'ZREMRANGEBYRANK', // Remove all members in a sorted set within the given indexes
  552. 'ZREMRANGEBYSCORE', // Remove all members in a sorted set within the given scores
  553. 'ZREVRANGE', // Return a range of members in a sorted set, by index, with scores ordered from high to low
  554. 'ZREVRANGEBYSCORE', // Return a range of members in a sorted set, by score, with scores ordered from high to low
  555. 'ZREVRANK', // Determine the index of a member in a sorted set, with scores ordered from high to low
  556. 'ZSCORE', // Get the score associated with the given member in a sorted set
  557. 'ZUNIONSTORE', // Add multiple sorted sets and store the resulting sorted set in a new key
  558. 'SCAN', // Incrementally iterate the keys space
  559. 'SSCAN', // Incrementally iterate Set elements
  560. 'HSCAN', // Incrementally iterate hash fields and associated values
  561. 'ZSCAN', // Incrementally iterate sorted sets elements and associated scores
  562. ];
  563. /**
  564. * @var array redis redirect socket connection pool
  565. */
  566. private $_pool = [];
  567. /**
  568. * Closes the connection when this component is being serialized.
  569. * @return array
  570. */
  571. public function __sleep()
  572. {
  573. $this->close();
  574. return array_keys(get_object_vars($this));
  575. }
  576. /**
  577. * Return the connection string used to open a socket connection. During a redirect (cluster mode) this will be the
  578. * target of the redirect.
  579. * @return string socket connection string
  580. * @since 2.0.11
  581. */
  582. public function getConnectionString()
  583. {
  584. if ($this->unixSocket) {
  585. return 'unix://' . $this->unixSocket;
  586. }
  587. return 'tcp://' . ($this->redirectConnectionString ?: "$this->hostname:$this->port");
  588. }
  589. /**
  590. * Return the connection resource if a connection to the target has been established before, `false` otherwise.
  591. * @return resource|false
  592. */
  593. public function getSocket()
  594. {
  595. return ArrayHelper::getValue($this->_pool, $this->connectionString, false);
  596. }
  597. /**
  598. * Returns a value indicating whether the DB connection is established.
  599. * @return bool whether the DB connection is established
  600. */
  601. public function getIsActive()
  602. {
  603. return ArrayHelper::getValue($this->_pool, $this->connectionString, false) !== false;
  604. }
  605. /**
  606. * Establishes a DB connection.
  607. * It does nothing if a DB connection has already been established.
  608. * @throws Exception if connection fails
  609. */
  610. public function open()
  611. {
  612. if ($this->socket !== false) {
  613. return;
  614. }
  615. $connection = $this->connectionString . ', database=' . $this->database;
  616. \Yii::trace('Opening redis DB connection: ' . $connection, __METHOD__);
  617. $socket = @stream_socket_client(
  618. $this->connectionString,
  619. $errorNumber,
  620. $errorDescription,
  621. $this->connectionTimeout ?: ini_get('default_socket_timeout'),
  622. $this->socketClientFlags,
  623. stream_context_create($this->contextOptions)
  624. );
  625. if ($socket) {
  626. $this->_pool[ $this->connectionString ] = $socket;
  627. if ($this->dataTimeout !== null) {
  628. stream_set_timeout($socket, $timeout = (int) $this->dataTimeout, (int) (($this->dataTimeout - $timeout) * 1000000));
  629. }
  630. if ($this->useSSL) {
  631. stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
  632. }
  633. if ($this->password !== null) {
  634. $this->executeCommand('AUTH', array_filter([$this->username, $this->password]));
  635. }
  636. if ($this->database !== null) {
  637. $this->executeCommand('SELECT', [$this->database]);
  638. }
  639. $this->initConnection();
  640. } else {
  641. \Yii::error("Failed to open redis DB connection ($connection): $errorNumber - $errorDescription", __CLASS__);
  642. $message = YII_DEBUG ? "Failed to open redis DB connection ($connection): $errorNumber - $errorDescription" : 'Failed to open DB connection.';
  643. throw new Exception($message, $errorDescription, $errorNumber);
  644. }
  645. }
  646. /**
  647. * Closes the currently active DB connection.
  648. * It does nothing if the connection is already closed.
  649. */
  650. public function close()
  651. {
  652. foreach ($this->_pool as $socket) {
  653. $connection = $this->connectionString . ', database=' . $this->database;
  654. \Yii::trace('Closing DB connection: ' . $connection, __METHOD__);
  655. try {
  656. $this->executeCommand('QUIT');
  657. } catch (SocketException $e) {
  658. // ignore errors when quitting a closed connection
  659. }
  660. fclose($socket);
  661. }
  662. $this->_pool = [];
  663. }
  664. /**
  665. * Initializes the DB connection.
  666. * This method is invoked right after the DB connection is established.
  667. * The default implementation triggers an [[EVENT_AFTER_OPEN]] event.
  668. */
  669. protected function initConnection()
  670. {
  671. $this->trigger(self::EVENT_AFTER_OPEN);
  672. }
  673. /**
  674. * Returns the name of the DB driver for the current [[dsn]].
  675. * @return string name of the DB driver
  676. */
  677. public function getDriverName()
  678. {
  679. return 'redis';
  680. }
  681. /**
  682. * @return LuaScriptBuilder
  683. */
  684. public function getLuaScriptBuilder()
  685. {
  686. return new LuaScriptBuilder();
  687. }
  688. /**
  689. * Allows issuing all supported commands via magic methods.
  690. *
  691. * ```php
  692. * $redis->hmset('test_collection', 'key1', 'val1', 'key2', 'val2')
  693. * ```
  694. *
  695. * @param string $name name of the missing method to execute
  696. * @param array $params method call arguments
  697. * @return mixed
  698. */
  699. public function __call($name, $params)
  700. {
  701. $redisCommand = strtoupper(Inflector::camel2words($name, false));
  702. if (in_array($redisCommand, $this->redisCommands)) {
  703. return $this->executeCommand($redisCommand, $params);
  704. }
  705. return parent::__call($name, $params);
  706. }
  707. /**
  708. * Executes a redis command.
  709. * For a list of available commands and their parameters see https://redis.io/commands.
  710. *
  711. * The params array should contain the params separated by white space, e.g. to execute
  712. * `SET mykey somevalue NX` call the following:
  713. *
  714. * ```php
  715. * $redis->executeCommand('SET', ['mykey', 'somevalue', 'NX']);
  716. * ```
  717. *
  718. * @param string $name the name of the command
  719. * @param array $params list of parameters for the command
  720. * @return array|bool|null|string Dependent on the executed command this method
  721. * will return different data types:
  722. *
  723. * - `true` for commands that return "status reply" with the message `'OK'` or `'PONG'`.
  724. * - `string` for commands that return "status reply" that does not have the message `OK` (since version 2.0.1).
  725. * - `string` for commands that return "integer reply"
  726. * as the value is in the range of a signed 64 bit integer.
  727. * - `string` or `null` for commands that return "bulk reply".
  728. * - `array` for commands that return "Multi-bulk replies".
  729. *
  730. * See [redis protocol description](https://redis.io/topics/protocol)
  731. * for details on the mentioned reply types.
  732. * @throws Exception for commands that return [error reply](https://redis.io/topics/protocol#error-reply).
  733. */
  734. public function executeCommand($name, $params = [])
  735. {
  736. $this->open();
  737. $params = array_merge(explode(' ', $name), $params);
  738. $command = '*' . count($params) . "\r\n";
  739. foreach ($params as $arg) {
  740. $command .= '$' . mb_strlen($arg, '8bit') . "\r\n" . $arg . "\r\n";
  741. }
  742. \Yii::trace("Executing Redis Command: {$name}", __METHOD__);
  743. if ($this->retries > 0) {
  744. $tries = $this->retries;
  745. while ($tries-- > 0) {
  746. try {
  747. return $this->sendRawCommand($command, $params);
  748. } catch (SocketException $e) {
  749. \Yii::error($e, __METHOD__);
  750. // backup retries, fail on commands that fail inside here
  751. $retries = $this->retries;
  752. $this->retries = 0;
  753. $this->close();
  754. if ($this->retryInterval > 0) {
  755. usleep($this->retryInterval);
  756. }
  757. try {
  758. $this->open();
  759. } catch (SocketException $exception) {
  760. // Fail to run initial commands, skip current try
  761. \Yii::error($exception, __METHOD__);
  762. $this->close();
  763. } catch (Exception $exception) {
  764. $this->close();
  765. }
  766. $this->retries = $retries;
  767. }
  768. }
  769. }
  770. return $this->sendRawCommand($command, $params);
  771. }
  772. /**
  773. * Sends RAW command string to the server.
  774. *
  775. * @param string $command command string
  776. * @param array $params list of parameters for the command
  777. *
  778. * @return array|bool|null|string Dependent on the executed command this method
  779. * will return different data types:
  780. *
  781. * - `true` for commands that return "status reply" with the message `'OK'` or `'PONG'`.
  782. * - `string` for commands that return "status reply" that does not have the message `OK` (since version 2.0.1).
  783. * - `string` for commands that return "integer reply"
  784. * as the value is in the range of a signed 64 bit integer.
  785. * - `string` or `null` for commands that return "bulk reply".
  786. * - `array` for commands that return "Multi-bulk replies".
  787. *
  788. * See [redis protocol description](https://redis.io/topics/protocol)
  789. * for details on the mentioned reply types.
  790. * @throws Exception for commands that return [error reply](https://redis.io/topics/protocol#error-reply).
  791. * @throws SocketException on connection error.
  792. */
  793. protected function sendRawCommand($command, $params)
  794. {
  795. $written = @fwrite($this->socket, $command);
  796. if ($written === false) {
  797. throw new SocketException("Failed to write to socket.\nRedis command was: " . $command);
  798. }
  799. if ($written !== ($len = mb_strlen($command, '8bit'))) {
  800. throw new SocketException("Failed to write to socket. $written of $len bytes written.\nRedis command was: " . $command);
  801. }
  802. return $this->parseResponse($params, $command);
  803. }
  804. /**
  805. * @param array $params
  806. * @param string|null $command
  807. * @return mixed
  808. * @throws Exception on error
  809. * @throws SocketException
  810. */
  811. private function parseResponse($params, $command = null)
  812. {
  813. $prettyCommand = implode(' ', $params);
  814. if (($line = fgets($this->socket)) === false) {
  815. throw new SocketException("Failed to read from socket.\nRedis command was: " . $prettyCommand);
  816. }
  817. $type = $line[0];
  818. $line = mb_substr($line, 1, -2, '8bit');
  819. switch ($type) {
  820. case '+': // Status reply
  821. if ($line === 'OK' || $line === 'PONG') {
  822. return true;
  823. }
  824. return $line;
  825. case '-': // Error reply
  826. if ($this->isRedirect($line)) {
  827. return $this->redirect($line, $command, $params);
  828. }
  829. throw new Exception("Redis error: " . $line . "\nRedis command was: " . $prettyCommand);
  830. case ':': // Integer reply
  831. // no cast to int as it is in the range of a signed 64 bit integer
  832. return $line;
  833. case '$': // Bulk replies
  834. if ($line == '-1') {
  835. return null;
  836. }
  837. $length = (int)$line + 2;
  838. $data = '';
  839. while ($length > 0) {
  840. if (($block = fread($this->socket, $length)) === false) {
  841. throw new SocketException("Failed to read from socket.\nRedis command was: " . $prettyCommand);
  842. }
  843. $data .= $block;
  844. $length -= mb_strlen($block, '8bit');
  845. }
  846. return mb_substr($data, 0, -2, '8bit');
  847. case '*': // Multi-bulk replies
  848. $count = (int) $line;
  849. $data = [];
  850. for ($i = 0; $i < $count; $i++) {
  851. $data[] = $this->parseResponse($params);
  852. }
  853. return $data;
  854. default:
  855. throw new Exception('Received illegal data from redis: ' . $line . "\nRedis command was: " . $prettyCommand);
  856. }
  857. }
  858. /**
  859. * @param string $line
  860. * @return bool
  861. */
  862. private function isRedirect($line)
  863. {
  864. return is_string($line) && mb_strpos($line, 'MOVED') === 0;
  865. }
  866. /**
  867. * @param string $redirect
  868. * @param string $command
  869. * @param array $params
  870. * @return mixed
  871. * @throws Exception
  872. * @throws SocketException
  873. */
  874. private function redirect($redirect, $command, $params)
  875. {
  876. $responseParts = preg_split('/\s+/', $redirect);
  877. $this->redirectConnectionString = ArrayHelper::getValue($responseParts, 2);
  878. if ($this->redirectConnectionString) {
  879. \Yii::info('Redirecting to ' . $this->connectionString, __METHOD__);
  880. $this->open();
  881. $response = $this->sendRawCommand($command, $params);
  882. $this->redirectConnectionString = null;
  883. return $response;
  884. }
  885. throw new Exception('No hostname found in redis redirect (MOVED): ' . VarDumper::dumpAsString($redirect));
  886. }
  887. }