1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace Yiisoft\Db\Redis; |
||||
6 | |||||
7 | use Psr\EventDispatcher\EventDispatcherInterface; |
||||
8 | use Psr\Log\LoggerInterface; |
||||
9 | use Psr\Log\LogLevel; |
||||
10 | use Yiisoft\Arrays\ArrayHelper; |
||||
11 | use Yiisoft\Db\Command\Command; |
||||
12 | use Yiisoft\Db\Connection\ConnectionInterface; |
||||
13 | use Yiisoft\Db\Exception\Exception; |
||||
14 | use Yiisoft\Db\Exception\NotSupportedException; |
||||
15 | use Yiisoft\Db\Redis\Event\AfterOpen; |
||||
16 | use Yiisoft\Db\Schema\Schema; |
||||
17 | use Yiisoft\Db\Schema\TableSchema; |
||||
18 | use Yiisoft\Strings\Inflector; |
||||
19 | use Yiisoft\VarDumper\VarDumper; |
||||
20 | |||||
21 | use function array_keys; |
||||
22 | use function array_merge; |
||||
23 | use function count; |
||||
24 | use function explode; |
||||
25 | use function fclose; |
||||
26 | use function fgets; |
||||
27 | use function fread; |
||||
28 | use function fwrite; |
||||
29 | use function get_class; |
||||
30 | use function get_object_vars; |
||||
31 | use function implode; |
||||
32 | use function in_array; |
||||
33 | use function ini_get; |
||||
34 | use function mb_strlen; |
||||
35 | use function mb_substr; |
||||
36 | use function preg_split; |
||||
37 | use function stream_set_timeout; |
||||
38 | use function stream_socket_enable_crypto; |
||||
39 | use function strtoupper; |
||||
40 | use function usleep; |
||||
41 | use function version_compare; |
||||
42 | |||||
43 | /** |
||||
44 | * The redis connection class is used to establish a connection to a [redis](http://redis.io/) server. |
||||
45 | * |
||||
46 | * By default it assumes there is a redis server running on localhost at port 6379 and uses the database number 0. |
||||
47 | * |
||||
48 | * It is possible to connect to a redis server using [[hostname]] and [[port]] or using a [[unixSocket]]. |
||||
49 | * |
||||
50 | * It also supports [the AUTH command](http://redis.io/commands/auth) of redis. |
||||
51 | * When the server needs authentication, you can set the [[password]] property to |
||||
52 | * authenticate with the server after connect. |
||||
53 | * |
||||
54 | * The execution of [redis commands](http://redis.io/commands) is possible with via [[executeCommand()]]. |
||||
55 | * |
||||
56 | * @method mixed append($key, $value) Append a value to a key. <https://redis.io/commands/append> |
||||
57 | * @method mixed auth($password) Authenticate to the server. <https://redis.io/commands/auth> |
||||
58 | * @method mixed bgrewriteaof() Asynchronously rewrite the append-only file. <https://redis.io/commands/bgrewriteaof> |
||||
59 | * @method mixed bgsave() Asynchronously save the dataset to disk. <https://redis.io/commands/bgsave> |
||||
60 | * @method mixed bitcount($key, $start = null, $end = null) Count set bits in a string. <https://redis.io/commands/bitcount> |
||||
61 | * @method mixed bitfield($key, ...$operations) Perform arbitrary bitfield integer operations on strings. <https://redis.io/commands/bitfield> |
||||
62 | * @method mixed bitop($operation, $destkey, ...$keys) Perform bitwise operations between strings. <https://redis.io/commands/bitop> |
||||
63 | * @method mixed bitpos($key, $bit, $start = null, $end = null) Find first bit set or clear in a string. <https://redis.io/commands/bitpos> |
||||
64 | * @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> |
||||
65 | * @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> |
||||
66 | * @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> |
||||
67 | * @method mixed clientKill(...$filters) Kill the connection of a client. <https://redis.io/commands/client-kill> |
||||
68 | * @method mixed clientList() Get the list of client connections. <https://redis.io/commands/client-list> |
||||
69 | * @method mixed clientGetname() Get the current connection name. <https://redis.io/commands/client-getname> |
||||
70 | * @method mixed clientPause($timeout) Stop processing commands from clients for some time. <https://redis.io/commands/client-pause> |
||||
71 | * @method mixed clientReply($option) Instruct the server whether to reply to commands. <https://redis.io/commands/client-reply> |
||||
72 | * @method mixed clientSetname($connectionName) Set the current connection name. <https://redis.io/commands/client-setname> |
||||
73 | * @method mixed clusterAddslots(...$slots) Assign new hash slots to receiving node. <https://redis.io/commands/cluster-addslots> |
||||
74 | * @method mixed clusterCountkeysinslot($slot) Return the number of local keys in the specified hash slot. <https://redis.io/commands/cluster-countkeysinslot> |
||||
75 | * @method mixed clusterDelslots(...$slots) Set hash slots as unbound in receiving node. <https://redis.io/commands/cluster-delslots> |
||||
76 | * @method mixed clusterFailover($option = null) Forces a slave to perform a manual failover of its master.. <https://redis.io/commands/cluster-failover> |
||||
77 | * @method mixed clusterForget($nodeId) Remove a node from the nodes table. <https://redis.io/commands/cluster-forget> |
||||
78 | * @method mixed clusterGetkeysinslot($slot, $count) Return local key names in the specified hash slot. <https://redis.io/commands/cluster-getkeysinslot> |
||||
79 | * @method mixed clusterInfo() Provides info about Redis Cluster node state. <https://redis.io/commands/cluster-info> |
||||
80 | * @method mixed clusterKeyslot($key) Returns the hash slot of the specified key. <https://redis.io/commands/cluster-keyslot> |
||||
81 | * @method mixed clusterMeet($ip, $port) Force a node cluster to handshake with another node. <https://redis.io/commands/cluster-meet> |
||||
82 | * @method mixed clusterNodes() Get Cluster config for the node. <https://redis.io/commands/cluster-nodes> |
||||
83 | * @method mixed clusterReplicate($nodeId) Reconfigure a node as a slave of the specified master node. <https://redis.io/commands/cluster-replicate> |
||||
84 | * @method mixed clusterReset($resetType = "SOFT") Reset a Redis Cluster node. <https://redis.io/commands/cluster-reset> |
||||
85 | * @method mixed clusterSaveconfig() Forces the node to save cluster state on disk. <https://redis.io/commands/cluster-saveconfig> |
||||
86 | * @method mixed clusterSetslot($slot, $type, $nodeid = null) Bind a hash slot to a specific node. <https://redis.io/commands/cluster-setslot> |
||||
87 | * @method mixed clusterSlaves($nodeId) List slave nodes of the specified master node. <https://redis.io/commands/cluster-slaves> |
||||
88 | * @method mixed clusterSlots() Get array of Cluster slot to node mappings. <https://redis.io/commands/cluster-slots> |
||||
89 | * @method mixed command() Get array of Redis command details. <https://redis.io/commands/command> |
||||
90 | * @method mixed commandCount() Get total number of Redis commands. <https://redis.io/commands/command-count> |
||||
91 | * @method mixed commandGetkeys() Extract keys given a full Redis command. <https://redis.io/commands/command-getkeys> |
||||
92 | * @method mixed commandInfo(...$commandNames) Get array of specific Redis command details. <https://redis.io/commands/command-info> |
||||
93 | * @method mixed configGet($parameter) Get the value of a configuration parameter. <https://redis.io/commands/config-get> |
||||
94 | * @method mixed configRewrite() Rewrite the configuration file with the in memory configuration. <https://redis.io/commands/config-rewrite> |
||||
95 | * @method mixed configSet($parameter, $value) Set a configuration parameter to the given value. <https://redis.io/commands/config-set> |
||||
96 | * @method mixed configResetstat() Reset the stats returned by INFO. <https://redis.io/commands/config-resetstat> |
||||
97 | * @method mixed dbsize() Return the number of keys in the selected database. <https://redis.io/commands/dbsize> |
||||
98 | * @method mixed debugObject($key) Get debugging information about a key. <https://redis.io/commands/debug-object> |
||||
99 | * @method mixed debugSegfault() Make the server crash. <https://redis.io/commands/debug-segfault> |
||||
100 | * @method mixed decr($key) Decrement the integer value of a key by one. <https://redis.io/commands/decr> |
||||
101 | * @method mixed decrby($key, $decrement) Decrement the integer value of a key by the given number. <https://redis.io/commands/decrby> |
||||
102 | * @method mixed del(...$keys) Delete a key. <https://redis.io/commands/del> |
||||
103 | * @method mixed discard() Discard all commands issued after MULTI. <https://redis.io/commands/discard> |
||||
104 | * @method mixed dump($key) Return a serialized version of the value stored at the specified key.. <https://redis.io/commands/dump> |
||||
105 | * @method mixed echo($message) Echo the given string. <https://redis.io/commands/echo> |
||||
106 | * @method mixed eval($script, $numkeys, ...$keys, ...$args) Execute a Lua script server side. <https://redis.io/commands/eval> |
||||
107 | * @method mixed evalsha($sha1, $numkeys, ...$keys, ...$args) Execute a Lua script server side. <https://redis.io/commands/evalsha> |
||||
108 | * @method mixed exec() Execute all commands issued after MULTI. <https://redis.io/commands/exec> |
||||
109 | * @method mixed exists(...$keys) Determine if a key exists. <https://redis.io/commands/exists> |
||||
110 | * @method mixed expire($key, $seconds) Set a key's time to live in seconds. <https://redis.io/commands/expire> |
||||
111 | * @method mixed expireat($key, $timestamp) Set the expiration for a key as a UNIX timestamp. <https://redis.io/commands/expireat> |
||||
112 | * @method mixed flushall($ASYNC = null) Remove all keys from all databases. <https://redis.io/commands/flushall> |
||||
113 | * @method mixed flushdb($ASYNC = null) Remove all keys from the current database. <https://redis.io/commands/flushdb> |
||||
114 | * @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> |
||||
115 | * @method mixed geohash($key, ...$members) Returns members of a geospatial index as standard geohash strings. <https://redis.io/commands/geohash> |
||||
116 | * @method mixed geopos($key, ...$members) Returns longitude and latitude of members of a geospatial index. <https://redis.io/commands/geopos> |
||||
117 | * @method mixed geodist($key, $member1, $member2, $unit = null) Returns the distance between two members of a geospatial index. <https://redis.io/commands/geodist> |
||||
118 | * @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> |
||||
119 | * @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> |
||||
120 | * @method mixed get($key) Get the value of a key. <https://redis.io/commands/get> |
||||
121 | * @method mixed getbit($key, $offset) Returns the bit value at offset in the string value stored at key. <https://redis.io/commands/getbit> |
||||
122 | * @method mixed getrange($key, $start, $end) Get a substring of the string stored at a key. <https://redis.io/commands/getrange> |
||||
123 | * @method mixed getset($key, $value) Set the string value of a key and return its old value. <https://redis.io/commands/getset> |
||||
124 | * @method mixed hdel($key, ...$fields) Delete one or more hash fields. <https://redis.io/commands/hdel> |
||||
125 | * @method mixed hexists($key, $field) Determine if a hash field exists. <https://redis.io/commands/hexists> |
||||
126 | * @method mixed hget($key, $field) Get the value of a hash field. <https://redis.io/commands/hget> |
||||
127 | * @method mixed hgetall($key) Get all the fields and values in a hash. <https://redis.io/commands/hgetall> |
||||
128 | * @method mixed hincrby($key, $field, $increment) Increment the integer value of a hash field by the given number. <https://redis.io/commands/hincrby> |
||||
129 | * @method mixed hincrbyfloat($key, $field, $increment) Increment the float value of a hash field by the given amount. <https://redis.io/commands/hincrbyfloat> |
||||
130 | * @method mixed hkeys($key) Get all the fields in a hash. <https://redis.io/commands/hkeys> |
||||
131 | * @method mixed hlen($key) Get the number of fields in a hash. <https://redis.io/commands/hlen> |
||||
132 | * @method mixed hmget($key, ...$fields) Get the values of all the given hash fields. <https://redis.io/commands/hmget> |
||||
133 | * @method mixed hmset($key, $field, $value, ...$more) Set multiple hash fields to multiple values. <https://redis.io/commands/hmset> |
||||
134 | * @method mixed hset($key, $field, $value) Set the string value of a hash field. <https://redis.io/commands/hset> |
||||
135 | * @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> |
||||
136 | * @method mixed hstrlen($key, $field) Get the length of the value of a hash field. <https://redis.io/commands/hstrlen> |
||||
137 | * @method mixed hvals($key) Get all the values in a hash. <https://redis.io/commands/hvals> |
||||
138 | * @method mixed incr($key) Increment the integer value of a key by one. <https://redis.io/commands/incr> |
||||
139 | * @method mixed incrby($key, $increment) Increment the integer value of a key by the given amount. <https://redis.io/commands/incrby> |
||||
140 | * @method mixed incrbyfloat($key, $increment) Increment the float value of a key by the given amount. <https://redis.io/commands/incrbyfloat> |
||||
141 | * @method mixed info($section = null) Get information and statistics about the server. <https://redis.io/commands/info> |
||||
142 | * @method mixed keys($pattern) Find all keys matching the given pattern. <https://redis.io/commands/keys> |
||||
143 | * @method mixed lastsave() Get the UNIX time stamp of the last successful save to disk. <https://redis.io/commands/lastsave> |
||||
144 | * @method mixed lindex($key, $index) Get an element from a list by its index. <https://redis.io/commands/lindex> |
||||
145 | * @method mixed linsert($key, $where, $pivot, $value) Insert an element before or after another element in a list. <https://redis.io/commands/linsert> |
||||
146 | * @method mixed llen($key) Get the length of a list. <https://redis.io/commands/llen> |
||||
147 | * @method mixed lpop($key) Remove and get the first element in a list. <https://redis.io/commands/lpop> |
||||
148 | * @method mixed lpush($key, ...$values) Prepend one or multiple values to a list. <https://redis.io/commands/lpush> |
||||
149 | * @method mixed lpushx($key, $value) Prepend a value to a list, only if the list exists. <https://redis.io/commands/lpushx> |
||||
150 | * @method mixed lrange($key, $start, $stop) Get a range of elements from a list. <https://redis.io/commands/lrange> |
||||
151 | * @method mixed lrem($key, $count, $value) Remove elements from a list. <https://redis.io/commands/lrem> |
||||
152 | * @method mixed lset($key, $index, $value) Set the value of an element in a list by its index. <https://redis.io/commands/lset> |
||||
153 | * @method mixed ltrim($key, $start, $stop) Trim a list to the specified range. <https://redis.io/commands/ltrim> |
||||
154 | * @method mixed mget(...$keys) Get the values of all the given keys. <https://redis.io/commands/mget> |
||||
155 | * @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> |
||||
156 | * @method mixed monitor() Listen for all requests received by the server in real time. <https://redis.io/commands/monitor> |
||||
157 | * @method mixed move($key, $db) Move a key to another database. <https://redis.io/commands/move> |
||||
158 | * @method mixed mset(...$keyValuePairs) Set multiple keys to multiple values. <https://redis.io/commands/mset> |
||||
159 | * @method mixed msetnx(...$keyValuePairs) Set multiple keys to multiple values, only if none of the keys exist. <https://redis.io/commands/msetnx> |
||||
160 | * @method mixed multi() Mark the start of a transaction block. <https://redis.io/commands/multi> |
||||
161 | * @method mixed object($subcommand, ...$argumentss) Inspect the internals of Redis objects. <https://redis.io/commands/object> |
||||
162 | * @method mixed persist($key) Remove the expiration from a key. <https://redis.io/commands/persist> |
||||
163 | * @method mixed pexpire($key, $milliseconds) Set a key's time to live in milliseconds. <https://redis.io/commands/pexpire> |
||||
164 | * @method mixed pexpireat($key, $millisecondsTimestamp) Set the expiration for a key as a UNIX timestamp specified in milliseconds. <https://redis.io/commands/pexpireat> |
||||
165 | * @method mixed pfadd($key, ...$elements) Adds the specified elements to the specified HyperLogLog.. <https://redis.io/commands/pfadd> |
||||
166 | * @method mixed pfcount(...$keys) Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s).. <https://redis.io/commands/pfcount> |
||||
167 | * @method mixed pfmerge($destkey, ...$sourcekeys) Merge N different HyperLogLogs into a single one.. <https://redis.io/commands/pfmerge> |
||||
168 | * @method mixed ping($message = null) Ping the server. <https://redis.io/commands/ping> |
||||
169 | * @method mixed psetex($key, $milliseconds, $value) Set the value and expiration in milliseconds of a key. <https://redis.io/commands/psetex> |
||||
170 | * @method mixed psubscribe(...$patterns) Listen for messages published to channels matching the given patterns. <https://redis.io/commands/psubscribe> |
||||
171 | * @method mixed pubsub($subcommand, ...$arguments) Inspect the state of the Pub/Sub subsystem. <https://redis.io/commands/pubsub> |
||||
172 | * @method mixed pttl($key) Get the time to live for a key in milliseconds. <https://redis.io/commands/pttl> |
||||
173 | * @method mixed publish($channel, $message) Post a message to a channel. <https://redis.io/commands/publish> |
||||
174 | * @method mixed punsubscribe(...$patterns) Stop listening for messages posted to channels matching the given patterns. <https://redis.io/commands/punsubscribe> |
||||
175 | * @method mixed quit() Close the connection. <https://redis.io/commands/quit> |
||||
176 | * @method mixed randomkey() Return a random key from the keyspace. <https://redis.io/commands/randomkey> |
||||
177 | * @method mixed readonly() Enables read queries for a connection to a cluster slave node. <https://redis.io/commands/readonly> |
||||
178 | * @method mixed readwrite() Disables read queries for a connection to a cluster slave node. <https://redis.io/commands/readwrite> |
||||
179 | * @method mixed rename($key, $newkey) Rename a key. <https://redis.io/commands/rename> |
||||
180 | * @method mixed renamenx($key, $newkey) Rename a key, only if the new key does not exist. <https://redis.io/commands/renamenx> |
||||
181 | * @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> |
||||
182 | * @method mixed role() Return the role of the instance in the context of replication. <https://redis.io/commands/role> |
||||
183 | * @method mixed rpop($key) Remove and get the last element in a list. <https://redis.io/commands/rpop> |
||||
184 | * @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> |
||||
185 | * @method mixed rpush($key, ...$values) Append one or multiple values to a list. <https://redis.io/commands/rpush> |
||||
186 | * @method mixed rpushx($key, $value) Append a value to a list, only if the list exists. <https://redis.io/commands/rpushx> |
||||
187 | * @method mixed sadd($key, ...$members) Add one or more members to a set. <https://redis.io/commands/sadd> |
||||
188 | * @method mixed save() Synchronously save the dataset to disk. <https://redis.io/commands/save> |
||||
189 | * @method mixed scard($key) Get the number of members in a set. <https://redis.io/commands/scard> |
||||
190 | * @method mixed scriptDebug($option) Set the debug mode for executed scripts.. <https://redis.io/commands/script-debug> |
||||
191 | * @method mixed scriptExists(...$sha1s) Check existence of scripts in the script cache.. <https://redis.io/commands/script-exists> |
||||
192 | * @method mixed scriptFlush() Remove all the scripts from the script cache.. <https://redis.io/commands/script-flush> |
||||
193 | * @method mixed scriptKill() Kill the script currently in execution.. <https://redis.io/commands/script-kill> |
||||
194 | * @method mixed scriptLoad($script) Load the specified Lua script into the script cache.. <https://redis.io/commands/script-load> |
||||
195 | * @method mixed sdiff(...$keys) Subtract multiple sets. <https://redis.io/commands/sdiff> |
||||
196 | * @method mixed sdiffstore($destination, ...$keys) Subtract multiple sets and store the resulting set in a key. <https://redis.io/commands/sdiffstore> |
||||
197 | * @method mixed select($index) Change the selected database for the current connection. <https://redis.io/commands/select> |
||||
198 | * @method mixed set($key, $value, ...$options) Set the string value of a key. <https://redis.io/commands/set> |
||||
199 | * @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> |
||||
200 | * @method mixed setex($key, $seconds, $value) Set the value and expiration of a key. <https://redis.io/commands/setex> |
||||
201 | * @method mixed setnx($key, $value) Set the value of a key, only if the key does not exist. <https://redis.io/commands/setnx> |
||||
202 | * @method mixed setrange($key, $offset, $value) Overwrite part of a string at key starting at the specified offset. <https://redis.io/commands/setrange> |
||||
203 | * @method mixed shutdown($saveOption = null) Synchronously save the dataset to disk and then shut down the server. <https://redis.io/commands/shutdown> |
||||
204 | * @method mixed sinter(...$keys) Intersect multiple sets. <https://redis.io/commands/sinter> |
||||
205 | * @method mixed sinterstore($destination, ...$keys) Intersect multiple sets and store the resulting set in a key. <https://redis.io/commands/sinterstore> |
||||
206 | * @method mixed sismember($key, $member) Determine if a given value is a member of a set. <https://redis.io/commands/sismember> |
||||
207 | * @method mixed slaveof($host, $port) Make the server a slave of another instance, or promote it as master. <https://redis.io/commands/slaveof> |
||||
208 | * @method mixed slowlog($subcommand, $argument = null) Manages the Redis slow queries log. <https://redis.io/commands/slowlog> |
||||
209 | * @method mixed smembers($key) Get all the members in a set. <https://redis.io/commands/smembers> |
||||
210 | * @method mixed smove($source, $destination, $member) Move a member from one set to another. <https://redis.io/commands/smove> |
||||
211 | * @method mixed sort($key, ...$options) Sort the elements in a list, set or sorted set. <https://redis.io/commands/sort> |
||||
212 | * @method mixed spop($key, $count = null) Remove and return one or multiple random members from a set. <https://redis.io/commands/spop> |
||||
213 | * @method mixed srandmember($key, $count = null) Get one or multiple random members from a set. <https://redis.io/commands/srandmember> |
||||
214 | * @method mixed srem($key, ...$members) Remove one or more members from a set. <https://redis.io/commands/srem> |
||||
215 | * @method mixed strlen($key) Get the length of the value stored in a key. <https://redis.io/commands/strlen> |
||||
216 | * @method mixed subscribe(...$channels) Listen for messages published to the given channels. <https://redis.io/commands/subscribe> |
||||
217 | * @method mixed sunion(...$keys) Add multiple sets. <https://redis.io/commands/sunion> |
||||
218 | * @method mixed sunionstore($destination, ...$keys) Add multiple sets and store the resulting set in a key. <https://redis.io/commands/sunionstore> |
||||
219 | * @method mixed swapdb($index, $index) Swaps two Redis databases. <https://redis.io/commands/swapdb> |
||||
220 | * @method mixed sync() Internal command used for replication. <https://redis.io/commands/sync> |
||||
221 | * @method mixed time() Return the current server time. <https://redis.io/commands/time> |
||||
222 | * @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> |
||||
223 | * @method mixed ttl($key) Get the time to live for a key. <https://redis.io/commands/ttl> |
||||
224 | * @method mixed type($key) Determine the type stored at key. <https://redis.io/commands/type> |
||||
225 | * @method mixed unsubscribe(...$channels) Stop listening for messages posted to the given channels. <https://redis.io/commands/unsubscribe> |
||||
226 | * @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> |
||||
227 | * @method mixed unwatch() Forget about all watched keys. <https://redis.io/commands/unwatch> |
||||
228 | * @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> |
||||
229 | * @method mixed watch(...$keys) Watch the given keys to determine execution of the MULTI/EXEC block. <https://redis.io/commands/watch> |
||||
230 | * @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> |
||||
231 | * @method mixed zcard($key) Get the number of members in a sorted set. <https://redis.io/commands/zcard> |
||||
232 | * @method mixed zcount($key, $min, $max) Count the members in a sorted set with scores within the given values. <https://redis.io/commands/zcount> |
||||
233 | * @method mixed zincrby($key, $increment, $member) Increment the score of a member in a sorted set. <https://redis.io/commands/zincrby> |
||||
234 | * @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> |
||||
235 | * @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> |
||||
236 | * @method mixed zrange($key, $start, $stop, $WITHSCORES = null) Return a range of members in a sorted set, by index. <https://redis.io/commands/zrange> |
||||
237 | * @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> |
||||
238 | * @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> |
||||
239 | * @method mixed zrangebyscore($key, $min, $max, $WITHSCORES = null, $LIMIT = null, $offset = null, $count = null) Return a range of members in a sorted set, by score. <https://redis.io/commands/zrangebyscore> |
||||
240 | * @method mixed zrank($key, $member) Determine the index of a member in a sorted set. <https://redis.io/commands/zrank> |
||||
241 | * @method mixed zrem($key, ...$members) Remove one or more members from a sorted set. <https://redis.io/commands/zrem> |
||||
242 | * @method mixed zremrangebylex($key, $min, $max) Remove all members in a sorted set between the given lexicographical range. <https://redis.io/commands/zremrangebylex> |
||||
243 | * @method mixed zremrangebyrank($key, $start, $stop) Remove all members in a sorted set within the given indexes. <https://redis.io/commands/zremrangebyrank> |
||||
244 | * @method mixed zremrangebyscore($key, $min, $max) Remove all members in a sorted set within the given scores. <https://redis.io/commands/zremrangebyscore> |
||||
245 | * @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> |
||||
246 | * @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> |
||||
247 | * @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> |
||||
248 | * @method mixed zscore($key, $member) Get the score associated with the given member in a sorted set. <https://redis.io/commands/zscore> |
||||
249 | * @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> |
||||
250 | * @method mixed scan($cursor, $MATCH = null, $pattern = null, $COUNT = null, $count = null) Incrementally iterate the keys space. <https://redis.io/commands/scan> |
||||
251 | * @method mixed sscan($key, $cursor, $MATCH = null, $pattern = null, $COUNT = null, $count = null) Incrementally iterate Set elements. <https://redis.io/commands/sscan> |
||||
252 | * @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> |
||||
253 | * @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> |
||||
254 | */ |
||||
255 | final class Connection implements ConnectionInterface |
||||
256 | { |
||||
257 | private string $hostname = 'localhost'; |
||||
258 | private string $redirectConnectionString = ''; |
||||
259 | private int $port = 6379; |
||||
260 | private string $unixSocket = ''; |
||||
261 | private ?string $password = null; |
||||
262 | private ?int $database = null; |
||||
263 | private ?float $connectionTimeout = null; |
||||
264 | private ?float $dataTimeout = null; |
||||
265 | private bool $useSSL = false; |
||||
266 | private int $socketClientFlags = STREAM_CLIENT_CONNECT; |
||||
267 | private int $retries = 0; |
||||
268 | private int $retryInterval = 0; |
||||
269 | private array $redisCommands = [ |
||||
270 | 'APPEND', // Append a value to a key |
||||
271 | 'AUTH', // Authenticate to the server |
||||
272 | 'BGREWRITEAOF', // Asynchronously rewrite the append-only file |
||||
273 | 'BGSAVE', // Asynchronously save the dataset to disk |
||||
274 | 'BITCOUNT', // Count set bits in a string |
||||
275 | 'BITFIELD', // Perform arbitrary bitfield integer operations on strings |
||||
276 | 'BITOP', // Perform bitwise operations between strings |
||||
277 | 'BITPOS', // Find first bit set or clear in a string |
||||
278 | 'BLPOP', // Remove and get the first element in a list, or block until one is available |
||||
279 | 'BRPOP', // Remove and get the last element in a list, or block until one is available |
||||
280 | 'BRPOPLPUSH', // Pop a value from a list, push it to another list and return it; or block until one is available |
||||
281 | 'CLIENT KILL', // Kill the connection of a client |
||||
282 | 'CLIENT LIST', // Get the list of client connections |
||||
283 | 'CLIENT GETNAME', // Get the current connection name |
||||
284 | 'CLIENT PAUSE', // Stop processing commands from clients for some time |
||||
285 | 'CLIENT REPLY', // Instruct the server whether to reply to commands |
||||
286 | 'CLIENT SETNAME', // Set the current connection name |
||||
287 | 'CLUSTER ADDSLOTS', // Assign new hash slots to receiving node |
||||
288 | 'CLUSTER COUNTKEYSINSLOT', // Return the number of local keys in the specified hash slot |
||||
289 | 'CLUSTER DELSLOTS', // Set hash slots as unbound in receiving node |
||||
290 | 'CLUSTER FAILOVER', // Forces a slave to perform a manual failover of its master. |
||||
291 | 'CLUSTER FORGET', // Remove a node from the nodes table |
||||
292 | 'CLUSTER GETKEYSINSLOT', // Return local key names in the specified hash slot |
||||
293 | 'CLUSTER INFO', // Provides info about Redis Cluster node state |
||||
294 | 'CLUSTER KEYSLOT', // Returns the hash slot of the specified key |
||||
295 | 'CLUSTER MEET', // Force a node cluster to handshake with another node |
||||
296 | 'CLUSTER NODES', // Get Cluster config for the node |
||||
297 | 'CLUSTER REPLICATE', // Reconfigure a node as a slave of the specified master node |
||||
298 | 'CLUSTER RESET', // Reset a Redis Cluster node |
||||
299 | 'CLUSTER SAVECONFIG', // Forces the node to save cluster state on disk |
||||
300 | 'CLUSTER SETSLOT', // Bind a hash slot to a specific node |
||||
301 | 'CLUSTER SLAVES', // List slave nodes of the specified master node |
||||
302 | 'CLUSTER SLOTS', // Get array of Cluster slot to node mappings |
||||
303 | 'COMMAND', // Get array of Redis command details |
||||
304 | 'COMMAND COUNT', // Get total number of Redis commands |
||||
305 | 'COMMAND GETKEYS', // Extract keys given a full Redis command |
||||
306 | 'COMMAND INFO', // Get array of specific Redis command details |
||||
307 | 'CONFIG GET', // Get the value of a configuration parameter |
||||
308 | 'CONFIG REWRITE', // Rewrite the configuration file with the in memory configuration |
||||
309 | 'CONFIG SET', // Set a configuration parameter to the given value |
||||
310 | 'CONFIG RESETSTAT', // Reset the stats returned by INFO |
||||
311 | 'DBSIZE', // Return the number of keys in the selected database |
||||
312 | 'DEBUG OBJECT', // Get debugging information about a key |
||||
313 | 'DEBUG SEGFAULT', // Make the server crash |
||||
314 | 'DECR', // Decrement the integer value of a key by one |
||||
315 | 'DECRBY', // Decrement the integer value of a key by the given number |
||||
316 | 'DEL', // Delete a key |
||||
317 | 'DISCARD', // Discard all commands issued after MULTI |
||||
318 | 'DUMP', // Return a serialized version of the value stored at the specified key. |
||||
319 | 'ECHO', // Echo the given string |
||||
320 | 'EVAL', // Execute a Lua script server side |
||||
321 | 'EVALSHA', // Execute a Lua script server side |
||||
322 | 'EXEC', // Execute all commands issued after MULTI |
||||
323 | 'EXISTS', // Determine if a key exists |
||||
324 | 'EXPIRE', // Set a key's time to live in seconds |
||||
325 | 'EXPIREAT', // Set the expiration for a key as a UNIX timestamp |
||||
326 | 'FLUSHALL', // Remove all keys from all databases |
||||
327 | 'FLUSHDB', // Remove all keys from the current database |
||||
328 | 'GEOADD', // Add one or more geospatial items in the geospatial index represented using a sorted set |
||||
329 | 'GEOHASH', // Returns members of a geospatial index as standard geohash strings |
||||
330 | 'GEOPOS', // Returns longitude and latitude of members of a geospatial index |
||||
331 | 'GEODIST', // Returns the distance between two members of a geospatial index |
||||
332 | 'GEORADIUS', // Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point |
||||
333 | 'GEORADIUSBYMEMBER', // Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member |
||||
334 | 'GET', // Get the value of a key |
||||
335 | 'GETBIT', // Returns the bit value at offset in the string value stored at key |
||||
336 | 'GETRANGE', // Get a substring of the string stored at a key |
||||
337 | 'GETSET', // Set the string value of a key and return its old value |
||||
338 | 'HDEL', // Delete one or more hash fields |
||||
339 | 'HEXISTS', // Determine if a hash field exists |
||||
340 | 'HGET', // Get the value of a hash field |
||||
341 | 'HGETALL', // Get all the fields and values in a hash |
||||
342 | 'HINCRBY', // Increment the integer value of a hash field by the given number |
||||
343 | 'HINCRBYFLOAT', // Increment the float value of a hash field by the given amount |
||||
344 | 'HKEYS', // Get all the fields in a hash |
||||
345 | 'HLEN', // Get the number of fields in a hash |
||||
346 | 'HMGET', // Get the values of all the given hash fields |
||||
347 | 'HMSET', // Set multiple hash fields to multiple values |
||||
348 | 'HSET', // Set the string value of a hash field |
||||
349 | 'HSETNX', // Set the value of a hash field, only if the field does not exist |
||||
350 | 'HSTRLEN', // Get the length of the value of a hash field |
||||
351 | 'HVALS', // Get all the values in a hash |
||||
352 | 'INCR', // Increment the integer value of a key by one |
||||
353 | 'INCRBY', // Increment the integer value of a key by the given amount |
||||
354 | 'INCRBYFLOAT', // Increment the float value of a key by the given amount |
||||
355 | 'INFO', // Get information and statistics about the server |
||||
356 | 'KEYS', // Find all keys matching the given pattern |
||||
357 | 'LASTSAVE', // Get the UNIX time stamp of the last successful save to disk |
||||
358 | 'LINDEX', // Get an element from a list by its index |
||||
359 | 'LINSERT', // Insert an element before or after another element in a list |
||||
360 | 'LLEN', // Get the length of a list |
||||
361 | 'LPOP', // Remove and get the first element in a list |
||||
362 | 'LPUSH', // Prepend one or multiple values to a list |
||||
363 | 'LPUSHX', // Prepend a value to a list, only if the list exists |
||||
364 | 'LRANGE', // Get a range of elements from a list |
||||
365 | 'LREM', // Remove elements from a list |
||||
366 | 'LSET', // Set the value of an element in a list by its index |
||||
367 | 'LTRIM', // Trim a list to the specified range |
||||
368 | 'MGET', // Get the values of all the given keys |
||||
369 | 'MIGRATE', // Atomically transfer a key from a Redis instance to another one. |
||||
370 | 'MONITOR', // Listen for all requests received by the server in real time |
||||
371 | 'MOVE', // Move a key to another database |
||||
372 | 'MSET', // Set multiple keys to multiple values |
||||
373 | 'MSETNX', // Set multiple keys to multiple values, only if none of the keys exist |
||||
374 | 'MULTI', // Mark the start of a transaction block |
||||
375 | 'OBJECT', // Inspect the internals of Redis objects |
||||
376 | 'PERSIST', // Remove the expiration from a key |
||||
377 | 'PEXPIRE', // Set a key's time to live in milliseconds |
||||
378 | 'PEXPIREAT', // Set the expiration for a key as a UNIX timestamp specified in milliseconds |
||||
379 | 'PFADD', // Adds the specified elements to the specified HyperLogLog. |
||||
380 | 'PFCOUNT', // Return the approximated cardinality of the set(s) observed by the HyperLogLog at key(s). |
||||
381 | 'PFMERGE', // Merge N different HyperLogLogs into a single one. |
||||
382 | 'PING', // Ping the server |
||||
383 | 'PSETEX', // Set the value and expiration in milliseconds of a key |
||||
384 | 'PSUBSCRIBE', // Listen for messages published to channels matching the given patterns |
||||
385 | 'PUBSUB', // Inspect the state of the Pub/Sub subsystem |
||||
386 | 'PTTL', // Get the time to live for a key in milliseconds |
||||
387 | 'PUBLISH', // Post a message to a channel |
||||
388 | 'PUNSUBSCRIBE', // Stop listening for messages posted to channels matching the given patterns |
||||
389 | 'QUIT', // Close the connection |
||||
390 | 'RANDOMKEY', // Return a random key from the keyspace |
||||
391 | 'READONLY', // Enables read queries for a connection to a cluster slave node |
||||
392 | 'READWRITE', // Disables read queries for a connection to a cluster slave node |
||||
393 | 'RENAME', // Rename a key |
||||
394 | 'RENAMENX', // Rename a key, only if the new key does not exist |
||||
395 | 'RESTORE', // Create a key using the provided serialized value, previously obtained using DUMP. |
||||
396 | 'ROLE', // Return the role of the instance in the context of replication |
||||
397 | 'RPOP', // Remove and get the last element in a list |
||||
398 | 'RPOPLPUSH', // Remove the last element in a list, prepend it to another list and return it |
||||
399 | 'RPUSH', // Append one or multiple values to a list |
||||
400 | 'RPUSHX', // Append a value to a list, only if the list exists |
||||
401 | 'SADD', // Add one or more members to a set |
||||
402 | 'SAVE', // Synchronously save the dataset to disk |
||||
403 | 'SCARD', // Get the number of members in a set |
||||
404 | 'SCRIPT DEBUG', // Set the debug mode for executed scripts. |
||||
405 | 'SCRIPT EXISTS', // Check existence of scripts in the script cache. |
||||
406 | 'SCRIPT FLUSH', // Remove all the scripts from the script cache. |
||||
407 | 'SCRIPT KILL', // Kill the script currently in execution. |
||||
408 | 'SCRIPT LOAD', // Load the specified Lua script into the script cache. |
||||
409 | 'SDIFF', // Subtract multiple sets |
||||
410 | 'SDIFFSTORE', // Subtract multiple sets and store the resulting set in a key |
||||
411 | 'SELECT', // Change the selected database for the current connection |
||||
412 | 'SET', // Set the string value of a key |
||||
413 | 'SETBIT', // Sets or clears the bit at offset in the string value stored at key |
||||
414 | 'SETEX', // Set the value and expiration of a key |
||||
415 | 'SETNX', // Set the value of a key, only if the key does not exist |
||||
416 | 'SETRANGE', // Overwrite part of a string at key starting at the specified offset |
||||
417 | 'SHUTDOWN', // Synchronously save the dataset to disk and then shut down the server |
||||
418 | 'SINTER', // Intersect multiple sets |
||||
419 | 'SINTERSTORE', // Intersect multiple sets and store the resulting set in a key |
||||
420 | 'SISMEMBER', // Determine if a given value is a member of a set |
||||
421 | 'SLAVEOF', // Make the server a slave of another instance, or promote it as master |
||||
422 | 'SLOWLOG', // Manages the Redis slow queries log |
||||
423 | 'SMEMBERS', // Get all the members in a set |
||||
424 | 'SMOVE', // Move a member from one set to another |
||||
425 | 'SORT', // Sort the elements in a list, set or sorted set |
||||
426 | 'SPOP', // Remove and return one or multiple random members from a set |
||||
427 | 'SRANDMEMBER', // Get one or multiple random members from a set |
||||
428 | 'SREM', // Remove one or more members from a set |
||||
429 | 'STRLEN', // Get the length of the value stored in a key |
||||
430 | 'SUBSCRIBE', // Listen for messages published to the given channels |
||||
431 | 'SUNION', // Add multiple sets |
||||
432 | 'SUNIONSTORE', // Add multiple sets and store the resulting set in a key |
||||
433 | 'SWAPDB', // Swaps two Redis databases |
||||
434 | 'SYNC', // Internal command used for replication |
||||
435 | 'TIME', // Return the current server time |
||||
436 | 'TOUCH', // Alters the last access time of a key(s). Returns the number of existing keys specified. |
||||
437 | 'TTL', // Get the time to live for a key |
||||
438 | 'TYPE', // Determine the type stored at key |
||||
439 | 'UNSUBSCRIBE', // Stop listening for messages posted to the given channels |
||||
440 | 'UNLINK', // Delete a key asynchronously in another thread. Otherwise it is just as DEL, but non blocking. |
||||
441 | 'UNWATCH', // Forget about all watched keys |
||||
442 | 'WAIT', // Wait for the synchronous replication of all the write commands sent in the context of the current connection |
||||
443 | 'WATCH', // Watch the given keys to determine execution of the MULTI/EXEC block |
||||
444 | 'XACK', // Removes one or multiple messages from the pending entries list (PEL) of a stream consumer group |
||||
445 | 'XADD', // Appends the specified stream entry to the stream at the specified key |
||||
446 | 'XCLAIM', // Changes the ownership of a pending message, so that the new owner is the consumer specified as the command argument |
||||
447 | 'XDEL', // Removes the specified entries from a stream, and returns the number of entries deleted |
||||
448 | 'XGROUP', // Manages the consumer groups associated with a stream data structure |
||||
449 | 'XINFO', // Retrieves different information about the streams and associated consumer groups |
||||
450 | 'XLEN', // Returns the number of entries inside a stream |
||||
451 | 'XPENDING', // Fetching data from a stream via a consumer group, and not acknowledging such data, has the effect of creating pending entries |
||||
452 | 'XRANGE', // Returns the stream entries matching a given range of IDs |
||||
453 | 'XREAD', // Read data from one or multiple streams, only returning entries with an ID greater than the last received ID reported by the caller |
||||
454 | 'XREADGROUP', // Special version of the XREAD command with support for consumer groups |
||||
455 | '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 |
||||
456 | 'XTRIM', // Trims the stream to a given number of items, evicting older items (items with lower IDs) if needed |
||||
457 | 'ZADD', // Add one or more members to a sorted set, or update its score if it already exists |
||||
458 | 'ZCARD', // Get the number of members in a sorted set |
||||
459 | 'ZCOUNT', // Count the members in a sorted set with scores within the given values |
||||
460 | 'ZINCRBY', // Increment the score of a member in a sorted set |
||||
461 | 'ZINTERSTORE', // Intersect multiple sorted sets and store the resulting sorted set in a new key |
||||
462 | 'ZLEXCOUNT', // Count the number of members in a sorted set between a given lexicographical range |
||||
463 | 'ZRANGE', // Return a range of members in a sorted set, by index |
||||
464 | 'ZRANGEBYLEX', // Return a range of members in a sorted set, by lexicographical range |
||||
465 | 'ZREVRANGEBYLEX', // Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings. |
||||
466 | 'ZRANGEBYSCORE', // Return a range of members in a sorted set, by score |
||||
467 | 'ZRANK', // Determine the index of a member in a sorted set |
||||
468 | 'ZREM', // Remove one or more members from a sorted set |
||||
469 | 'ZREMRANGEBYLEX', // Remove all members in a sorted set between the given lexicographical range |
||||
470 | 'ZREMRANGEBYRANK', // Remove all members in a sorted set within the given indexes |
||||
471 | 'ZREMRANGEBYSCORE', // Remove all members in a sorted set within the given scores |
||||
472 | 'ZREVRANGE', // Return a range of members in a sorted set, by index, with scores ordered from high to low |
||||
473 | 'ZREVRANGEBYSCORE', // Return a range of members in a sorted set, by score, with scores ordered from high to low |
||||
474 | 'ZREVRANK', // Determine the index of a member in a sorted set, with scores ordered from high to low |
||||
475 | 'ZSCORE', // Get the score associated with the given member in a sorted set |
||||
476 | 'ZUNIONSTORE', // Add multiple sorted sets and store the resulting sorted set in a new key |
||||
477 | 'SCAN', // Incrementally iterate the keys space |
||||
478 | 'SSCAN', // Incrementally iterate Set elements |
||||
479 | 'HSCAN', // Incrementally iterate hash fields and associated values |
||||
480 | 'ZSCAN', // Incrementally iterate sorted sets elements and associated scores |
||||
481 | ]; |
||||
482 | private array $pool = []; |
||||
483 | private bool $runEvent = false; |
||||
484 | private EventDispatcherInterface $dispatch; |
||||
485 | private LoggerInterface $logger; |
||||
486 | private string $dsn; |
||||
487 | |||||
488 | 14 | public function __construct(EventDispatcherInterface $dispatch, LoggerInterface $logger) |
|||
489 | { |
||||
490 | 14 | $this->dispatch = $dispatch; |
|||
491 | 14 | $this->logger = $logger; |
|||
492 | 14 | } |
|||
493 | |||||
494 | /** |
||||
495 | * Closes the connection when this component is being serialized. |
||||
496 | * |
||||
497 | * @return array |
||||
498 | */ |
||||
499 | 1 | public function __sleep(): array |
|||
500 | { |
||||
501 | 1 | unset($this->dispatch); |
|||
502 | |||||
503 | 1 | $this->close(); |
|||
504 | |||||
505 | 1 | return array_keys(get_object_vars($this)); |
|||
506 | } |
||||
507 | |||||
508 | /** |
||||
509 | * Return the connection string used to open a socket connection. During a redirect (cluster mode) this will be the |
||||
510 | * target of the redirect. |
||||
511 | * |
||||
512 | * @return string socket connection string |
||||
513 | */ |
||||
514 | 14 | public function getConnectionString(): string |
|||
515 | { |
||||
516 | 14 | if ($this->unixSocket) { |
|||
517 | return 'unix://' . $this->unixSocket; |
||||
518 | } |
||||
519 | |||||
520 | 14 | return 'tcp://' . ($this->redirectConnectionString ?: "$this->hostname:$this->port"); |
|||
521 | } |
||||
522 | |||||
523 | /** |
||||
524 | * Return the connection resource if a connection to the target has been established before, `false` otherwise. |
||||
525 | * |
||||
526 | * @return resource|false |
||||
527 | */ |
||||
528 | 14 | public function getSocket() |
|||
529 | { |
||||
530 | 14 | return ArrayHelper::getValue($this->pool, $this->getConnectionString(), false); |
|||
531 | } |
||||
532 | |||||
533 | /** |
||||
534 | * Returns a value indicating whether the DB connection is established. |
||||
535 | * |
||||
536 | * @return bool whether the DB connection is established |
||||
537 | */ |
||||
538 | public function getIsActive(): bool |
||||
539 | { |
||||
540 | return ArrayHelper::getValue($this->pool, "$this->hostname:$this->port", false) !== false; |
||||
541 | } |
||||
542 | |||||
543 | /** |
||||
544 | * Establishes a DB connection. |
||||
545 | * |
||||
546 | * It does nothing if a DB connection has already been established. |
||||
547 | * |
||||
548 | * @throws Exception if connection fails |
||||
549 | */ |
||||
550 | 14 | public function open(): void |
|||
551 | { |
||||
552 | 14 | if ($this->getSocket() !== false) { |
|||
553 | 14 | return; |
|||
554 | } |
||||
555 | |||||
556 | 14 | $this->dsn = $this->getConnectionString() . ', database=' . $this->database; |
|||
557 | |||||
558 | 14 | $this->logger->log(LogLevel::INFO, 'Opening redis DB connection: ' . $this->dsn . ' ' . __METHOD__); |
|||
559 | |||||
560 | 14 | $socket = @stream_socket_client( |
|||
561 | 14 | $this->getConnectionString(), |
|||
562 | $errorNumber, |
||||
563 | $errorDescription, |
||||
564 | 14 | $this->connectionTimeout ?? (float) ini_get('default_socket_timeout'), |
|||
565 | 14 | $this->socketClientFlags |
|||
566 | ); |
||||
567 | |||||
568 | 14 | if ($socket) { |
|||
569 | 14 | $this->pool[ $this->getConnectionString() ] = $socket; |
|||
570 | |||||
571 | 14 | if ($this->dataTimeout !== null) { |
|||
572 | stream_set_timeout( |
||||
573 | $socket, |
||||
574 | $timeout = (int) $this->dataTimeout, |
||||
575 | (int) (($this->dataTimeout - $timeout) * 1000000) |
||||
576 | ); |
||||
577 | } |
||||
578 | |||||
579 | 14 | if ($this->useSSL) { |
|||
580 | stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); |
||||
581 | } |
||||
582 | |||||
583 | 14 | if ($this->password !== null) { |
|||
584 | $this->executeCommand('AUTH', [$this->password]); |
||||
585 | } |
||||
586 | |||||
587 | 14 | if ($this->database !== null) { |
|||
588 | 14 | $this->executeCommand('SELECT', [$this->database]); |
|||
589 | } |
||||
590 | |||||
591 | 14 | if ($this->runEvent) { |
|||
592 | 14 | $this->dispatch->dispatch(new AfterOpen()); |
|||
593 | } |
||||
594 | } else { |
||||
595 | $message = "Failed to open redis DB connection ($this->dsn): $errorNumber - $errorDescription " . __CLASS__; |
||||
596 | |||||
597 | $this->logger->log( |
||||
598 | LogLevel::ERROR, |
||||
599 | $message |
||||
600 | ); |
||||
601 | |||||
602 | throw new Exception($message, $errorDescription, $errorNumber); |
||||
603 | } |
||||
604 | 14 | } |
|||
605 | |||||
606 | /** |
||||
607 | * Closes the currently active DB connection. |
||||
608 | * |
||||
609 | * It does nothing if the connection is already closed. |
||||
610 | */ |
||||
611 | 5 | public function close(): void |
|||
612 | { |
||||
613 | 5 | foreach ($this->pool as $socket) { |
|||
614 | 5 | $this->dsn = $this->getConnectionString() . ', database=' . $this->database; |
|||
615 | |||||
616 | 5 | $this->logger->log(LogLevel::INFO, 'Closing DB connection: ' . $this->dsn . ' ' . __METHOD__); |
|||
617 | |||||
618 | try { |
||||
619 | 5 | $this->executeCommand('QUIT'); |
|||
620 | 2 | } catch (SocketException $e) { |
|||
621 | /** ignore errors when quitting a closed connection. */ |
||||
622 | } |
||||
623 | |||||
624 | 5 | fclose($socket); |
|||
625 | } |
||||
626 | |||||
627 | 5 | $this->pool = []; |
|||
628 | 5 | } |
|||
629 | |||||
630 | /** |
||||
631 | * Returns the name of the DB driver. |
||||
632 | * |
||||
633 | * @return string name of the DB driver. |
||||
634 | */ |
||||
635 | public function getDriverName(): string |
||||
636 | { |
||||
637 | return 'redis'; |
||||
638 | } |
||||
639 | |||||
640 | /** |
||||
641 | * Allows issuing all supported commands via magic methods. |
||||
642 | * |
||||
643 | * ```php |
||||
644 | * $redis->hmset('test_collection', 'key1', 'val1', 'key2', 'val2') |
||||
645 | * ``` |
||||
646 | * |
||||
647 | * @param string $name name of the missing method to execute. |
||||
648 | * @param array $params method call arguments. |
||||
649 | * |
||||
650 | * @throws Exception |
||||
651 | * |
||||
652 | * @return mixed |
||||
653 | */ |
||||
654 | 14 | public function __call(string $name, array $params) |
|||
655 | { |
||||
656 | 14 | $redisCommand = strtoupper((new Inflector())->toWords($name, false)); |
|||
0 ignored issues
–
show
|
|||||
657 | |||||
658 | 14 | if (in_array($redisCommand, $this->redisCommands, true)) { |
|||
659 | 14 | return $this->executeCommand($redisCommand, $params); |
|||
660 | } |
||||
661 | } |
||||
662 | |||||
663 | /** |
||||
664 | * Executes a redis command. |
||||
665 | * |
||||
666 | * For a list of available commands and their parameters see https://redis.io/commands. |
||||
667 | * |
||||
668 | * The params array should contain the params separated by white space, e.g. to execute |
||||
669 | * `SET mykey somevalue NX` call the following: |
||||
670 | * |
||||
671 | * ```php |
||||
672 | * $redis->executeCommand('SET', ['mykey', 'somevalue', 'NX']); |
||||
673 | * ``` |
||||
674 | * |
||||
675 | * @param string $name the name of the command. |
||||
676 | * @param array $params list of parameters for the command. |
||||
677 | * |
||||
678 | * @throws Exception for commands that return [error reply](https://redis.io/topics/protocol#error-reply). |
||||
679 | * |
||||
680 | * @return array|bool|null|string Dependent on the executed command this method will return different data types: |
||||
681 | * |
||||
682 | * - `true` for commands that return "status reply" with the message `'OK'` or `'PONG'`. |
||||
683 | * - `string` for commands that return "status reply" that does not have the message `OK`. |
||||
684 | * - `string` for commands that return "integer reply" |
||||
685 | * as the value is in the range of a signed 64 bit integer. |
||||
686 | * - `string` or `null` for commands that return "bulk reply". |
||||
687 | * - `array` for commands that return "Multi-bulk replies". |
||||
688 | * |
||||
689 | * See [redis protocol description](https://redis.io/topics/protocol) |
||||
690 | * |
||||
691 | * for details on the mentioned reply types. |
||||
692 | */ |
||||
693 | 14 | public function executeCommand($name, $params = []) |
|||
694 | { |
||||
695 | 14 | $this->open(); |
|||
696 | |||||
697 | 14 | $params = array_merge(explode(' ', $name), $params); |
|||
698 | 14 | $command = '*' . count($params) . "\r\n"; |
|||
699 | |||||
700 | 14 | foreach ($params as $arg) { |
|||
701 | 14 | $command .= '$' . mb_strlen((string) $arg, '8bit') . "\r\n" . $arg . "\r\n"; |
|||
702 | } |
||||
703 | |||||
704 | 14 | $this->logger->log(LogLevel::INFO, "Executing Redis Command: {$name} " . ' ' . __METHOD__); |
|||
705 | |||||
706 | 14 | if ($this->retries > 0) { |
|||
707 | 2 | $tries = $this->retries; |
|||
708 | 2 | while ($tries-- > 0) { |
|||
709 | try { |
||||
710 | 2 | return $this->sendCommandInternal($command, $params); |
|||
711 | 2 | } catch (SocketException $e) { |
|||
712 | 2 | $this->logger->log(LogLevel::ERROR, $e . ' ' . __METHOD__); |
|||
713 | |||||
714 | /** backup retries, fail on commands that fail inside here. */ |
||||
715 | 2 | $retries = $this->retries; |
|||
716 | |||||
717 | 2 | $this->retries = 0; |
|||
718 | |||||
719 | 2 | $this->close(); |
|||
720 | |||||
721 | 2 | if ($this->retryInterval > 0) { |
|||
722 | usleep($this->retryInterval); |
||||
723 | } |
||||
724 | |||||
725 | 2 | $this->open(); |
|||
726 | |||||
727 | 2 | $this->retries = $retries; |
|||
728 | } |
||||
729 | } |
||||
730 | } |
||||
731 | |||||
732 | 14 | return $this->sendCommandInternal($command, $params); |
|||
733 | } |
||||
734 | |||||
735 | /** |
||||
736 | * Sends RAW command string to the server. |
||||
737 | * |
||||
738 | * @param string $command |
||||
739 | * @param array $params |
||||
740 | * |
||||
741 | * @throws Exception |
||||
742 | * @throws SocketException on connection error. |
||||
743 | * |
||||
744 | * @return array|bool|false|mixed|string|null |
||||
745 | */ |
||||
746 | 14 | private function sendCommandInternal(string $command, array $params = []) |
|||
747 | { |
||||
748 | 14 | $written = @fwrite($this->getSocket(), $command); |
|||
749 | |||||
750 | 14 | if ($written === false) { |
|||
751 | throw new SocketException("Failed to write to socket.\nRedis command was: " . $command); |
||||
752 | } |
||||
753 | 14 | if ($written !== ($len = mb_strlen($command, '8bit'))) { |
|||
754 | throw new SocketException("Failed to write to socket. $written of $len bytes written.\nRedis command was: " . $command); |
||||
755 | } |
||||
756 | |||||
757 | 14 | return $this->parseResponse($params, $command); |
|||
758 | } |
||||
759 | |||||
760 | 14 | private function parseResponse(array $params, ?string $command = null) |
|||
761 | { |
||||
762 | 14 | $prettyCommand = implode(' ', $params); |
|||
763 | |||||
764 | 14 | if (($line = fgets($this->getSocket())) === false) { |
|||
765 | 3 | throw new SocketException("Failed to read from socket.\nRedis command was: " . $prettyCommand); |
|||
766 | } |
||||
767 | |||||
768 | 14 | $type = $line[0]; |
|||
769 | 14 | $line = mb_substr($line, 1, -2, '8bit'); |
|||
770 | |||||
771 | switch ($type) { |
||||
772 | 14 | case '+': // Status reply |
|||
773 | 14 | if ($line === 'OK' || $line === 'PONG') { |
|||
774 | 14 | return true; |
|||
775 | } |
||||
776 | |||||
777 | 1 | return $line; |
|||
778 | 9 | case '-': // Error reply |
|||
779 | if ($this->isRedirect($line)) { |
||||
780 | return $this->redirect($line, $command, $params); |
||||
781 | } |
||||
782 | |||||
783 | throw new Exception("Redis error: " . $line . "\nRedis command was: " . $prettyCommand); |
||||
784 | 9 | case ':': // Integer reply |
|||
785 | // no cast to int as it is in the range of a signed 64 bit integer |
||||
786 | 1 | return $line; |
|||
787 | 9 | case '$': // Bulk replies |
|||
788 | 9 | if ($line === '-1') { |
|||
789 | 1 | return null; |
|||
790 | } |
||||
791 | |||||
792 | 9 | $length = (int)$line + 2; |
|||
793 | 9 | $data = ''; |
|||
794 | |||||
795 | 9 | while ($length > 0) { |
|||
796 | 9 | if (($block = fread($this->getSocket(), $length)) === false) { |
|||
797 | throw new SocketException("Failed to read from socket.\nRedis command was: " . $prettyCommand); |
||||
798 | } |
||||
799 | 9 | $data .= $block; |
|||
800 | 9 | $length -= mb_strlen($block, '8bit'); |
|||
801 | } |
||||
802 | |||||
803 | 9 | return mb_substr($data, 0, -2, '8bit'); |
|||
804 | 2 | case '*': // Multi-bulk replies |
|||
805 | 2 | $count = (int) $line; |
|||
806 | 2 | $data = []; |
|||
807 | 2 | for ($i = 0; $i < $count; $i++) { |
|||
808 | 2 | $data[] = $this->parseResponse($params); |
|||
809 | } |
||||
810 | |||||
811 | 2 | return $data; |
|||
812 | default: |
||||
813 | throw new Exception( |
||||
814 | 'Received illegal data from redis: ' . $line . "\nRedis command was: " . $prettyCommand |
||||
815 | ); |
||||
816 | } |
||||
817 | } |
||||
818 | |||||
819 | private function isRedirect(string $line): bool |
||||
820 | { |
||||
821 | return is_string($line) && mb_strpos($line, 'MOVED') === 0; |
||||
822 | } |
||||
823 | |||||
824 | private function redirect(string $redirect, string $command, array $params = []) |
||||
825 | { |
||||
826 | $responseParts = preg_split('/\s+/', $redirect); |
||||
827 | |||||
828 | $this->redirectConnectionString = ArrayHelper::getValue($responseParts, 2); |
||||
829 | |||||
830 | if ($this->redirectConnectionString) { |
||||
831 | $this->logger->log(LogLevel::INFO, 'Redirecting to ' . $this->getConnectionString() . ' ' . __METHOD__); |
||||
832 | |||||
833 | $this->open(); |
||||
834 | |||||
835 | $response = $this->sendCommandInternal($command, $params); |
||||
836 | |||||
837 | $this->redirectConnectionString = ''; |
||||
838 | |||||
839 | return $response; |
||||
840 | } |
||||
841 | |||||
842 | throw new Exception('No hostname found in redis redirect (MOVED): ' . VarDumper::dumpAsString($redirect)); |
||||
843 | } |
||||
844 | |||||
845 | /** |
||||
846 | * @return float timeout to use for connection to redis. If not set the timeout set in php.ini will be used: |
||||
847 | * `ini_get("default_socket_timeout")`. |
||||
848 | */ |
||||
849 | public function getConnectionTimeout(): ?float |
||||
850 | { |
||||
851 | return $this->connectionTimeout; |
||||
852 | } |
||||
853 | |||||
854 | /** |
||||
855 | * @return int the redis database to use. This is an integer value starting from 0. Defaults to 0. |
||||
856 | * |
||||
857 | * You can disable the SELECT command sent after connection by setting this property to `null`. |
||||
858 | */ |
||||
859 | 1 | public function getDatabase(): ?int |
|||
860 | { |
||||
861 | 1 | return $this->database; |
|||
862 | } |
||||
863 | |||||
864 | /** |
||||
865 | * @return float timeout to use for redis socket when reading and writing data. If not set the php default value |
||||
866 | * will be used. |
||||
867 | */ |
||||
868 | public function getDataTimeout(): ?float |
||||
869 | { |
||||
870 | return $this->dataTimeout; |
||||
871 | } |
||||
872 | |||||
873 | /** |
||||
874 | * @return string the hostname or ip address to use for connecting to the redis server. Defaults to 'localhost'. |
||||
875 | * |
||||
876 | * If {@see unixSocket} is specified, hostname and {@see port} will be ignored. |
||||
877 | */ |
||||
878 | public function getHostname(): string |
||||
879 | { |
||||
880 | return $this->hostname; |
||||
881 | } |
||||
882 | |||||
883 | /** |
||||
884 | * @return string the password for establishing DB connection. Defaults to null meaning no AUTH command is sent. |
||||
885 | * |
||||
886 | * {@see https://redis.io/commands/auth} |
||||
887 | */ |
||||
888 | public function getPassword(): string |
||||
889 | { |
||||
890 | return $this->password; |
||||
891 | } |
||||
892 | |||||
893 | /** |
||||
894 | * @return array redis redirect socket connection pool. |
||||
895 | */ |
||||
896 | public function getPool(): array |
||||
897 | { |
||||
898 | return $this->pool; |
||||
899 | } |
||||
900 | |||||
901 | /** |
||||
902 | * @return int the port to use for connecting to the redis server. Default port is 6379. |
||||
903 | * |
||||
904 | * If {@see unixSocket} is specified, {@see hostname} and port will be ignored. |
||||
905 | */ |
||||
906 | public function getPort(): int |
||||
907 | { |
||||
908 | return $this->port; |
||||
909 | } |
||||
910 | |||||
911 | /** |
||||
912 | * @return string if the query gets redirected, use this as the temporary new hostname. |
||||
913 | */ |
||||
914 | public function getRedirectConnectionString(): string |
||||
915 | { |
||||
916 | return $this->redirectConnectionString; |
||||
917 | } |
||||
918 | |||||
919 | /** |
||||
920 | * @return array List of available redis commands. |
||||
921 | * |
||||
922 | * {@see https://redis.io/commands} |
||||
923 | */ |
||||
924 | public function getRedisCommands(): array |
||||
925 | { |
||||
926 | return $this->redisCommands; |
||||
927 | } |
||||
928 | |||||
929 | /** |
||||
930 | * @return int The number of times a command execution should be retried when a connection failure occurs. |
||||
931 | * |
||||
932 | * This is used in {@see executeCommand()} when a {@see SocketException} is thrown. |
||||
933 | * |
||||
934 | * Defaults to 0 meaning no retries on failure. |
||||
935 | */ |
||||
936 | public function getRetries(): int |
||||
937 | { |
||||
938 | return $this->retries; |
||||
939 | } |
||||
940 | |||||
941 | /** |
||||
942 | * @return int The retry interval in microseconds to wait between retry. |
||||
943 | * |
||||
944 | * This is used in {@see executeCommand()} when a {@see SocketException} is thrown. |
||||
945 | * |
||||
946 | * Defaults to 0 meaning no wait. |
||||
947 | */ |
||||
948 | public function getRetryInterval(): int |
||||
949 | { |
||||
950 | return $this->retryInterval; |
||||
951 | } |
||||
952 | |||||
953 | public function getRunEvent(): bool |
||||
954 | { |
||||
955 | return $this->runEvent; |
||||
956 | } |
||||
957 | |||||
958 | /** |
||||
959 | * @return integer Bitmask field which may be set to any combination of connection flags passed to |
||||
960 | * [stream_socket_client()](https://www.php.net/manual/en/function.stream-socket-client.php). |
||||
961 | * |
||||
962 | * Currently the select of connection flags is limited to `STREAM_CLIENT_CONNECT` (default), |
||||
963 | * `STREAM_CLIENT_ASYNC_CONNECT` and `STREAM_CLIENT_PERSISTENT`. |
||||
964 | * |
||||
965 | * > Warning: `STREAM_CLIENT_PERSISTENT` will make PHP reuse connections to the same server. If you are using |
||||
966 | * > multiple connection objects to refer to different redis {@see $database|databases} on the same {@see port}, |
||||
967 | * > redis commands may get executed on the wrong database. `STREAM_CLIENT_PERSISTENT` is only safe to use if you |
||||
968 | * > use only one database. |
||||
969 | * > |
||||
970 | * > You may still use persistent connections in this case when disambiguating ports as described |
||||
971 | * > in [a comment on the PHP manual](https://www.php.net/manual/en/function.stream-socket-client.php#105393) |
||||
972 | * > e.g. on the connection used for session storage, specify the port as: |
||||
973 | * > |
||||
974 | * > ```php |
||||
975 | * > 'port' => '6379/session' |
||||
976 | * > ``` |
||||
977 | * |
||||
978 | * {@see https://www.php.net/manual/en/function.stream-socket-client.php} |
||||
979 | */ |
||||
980 | public function getSocketClientFlags(): int |
||||
981 | { |
||||
982 | return $this->socketClientFlags; |
||||
983 | } |
||||
984 | |||||
985 | /** |
||||
986 | * @return string the unix socket path (e.g. `/var/run/redis/redis.sock`) to use for connecting to the redis server. |
||||
987 | * This can be used instead of {@see hostname} and {@see port} to connect to the server using a unix socket. If a |
||||
988 | * unix socket path is specified, {@see hostname} and {@see port} will be ignored. |
||||
989 | */ |
||||
990 | public function getUnixSocket(): string |
||||
991 | { |
||||
992 | return $this->unixSocket; |
||||
993 | } |
||||
994 | |||||
995 | /** |
||||
996 | * @return bool Send sockets over SSL protocol. Default state is false. |
||||
997 | */ |
||||
998 | public function getUseSSL(): bool |
||||
999 | { |
||||
1000 | return $this->useSSL; |
||||
1001 | } |
||||
1002 | |||||
1003 | public function connectionTimeout(float $value): void |
||||
1004 | { |
||||
1005 | $this->connectionTimeout = $value; |
||||
1006 | } |
||||
1007 | |||||
1008 | 14 | public function database(int $value): void |
|||
1009 | { |
||||
1010 | 14 | $this->database = $value; |
|||
1011 | 14 | } |
|||
1012 | |||||
1013 | public function dataTimeout(float $value): void |
||||
1014 | { |
||||
1015 | $this->dataTimeout = $value; |
||||
1016 | } |
||||
1017 | |||||
1018 | 14 | public function hostname(string $value): void |
|||
1019 | { |
||||
1020 | 14 | $this->hostname = $value; |
|||
1021 | 14 | } |
|||
1022 | |||||
1023 | 14 | public function password(?string $value): void |
|||
1024 | { |
||||
1025 | 14 | $this->password = $value; |
|||
1026 | 14 | } |
|||
1027 | |||||
1028 | 14 | public function port(int $value): void |
|||
1029 | { |
||||
1030 | 14 | $this->port = $value; |
|||
1031 | 14 | } |
|||
1032 | |||||
1033 | public function pool(array $value): void |
||||
1034 | { |
||||
1035 | $this->pool = $value; |
||||
1036 | } |
||||
1037 | |||||
1038 | public function redirectConnectionString(string $value): void |
||||
1039 | { |
||||
1040 | $this->redirectConnectionString = $value; |
||||
1041 | } |
||||
1042 | |||||
1043 | public function redisCommands(array $value): void |
||||
1044 | { |
||||
1045 | $this->redisCommands = $value; |
||||
1046 | } |
||||
1047 | |||||
1048 | 2 | public function retries(int $value): void |
|||
1049 | { |
||||
1050 | 2 | $this->retries = $value; |
|||
1051 | 2 | } |
|||
1052 | |||||
1053 | public function retryInterval(int $value): void |
||||
1054 | { |
||||
1055 | $this->retryInterval = $value; |
||||
1056 | } |
||||
1057 | |||||
1058 | 1 | public function runEvent(bool $value): void |
|||
1059 | { |
||||
1060 | 1 | $this->runEvent = $value; |
|||
1061 | 1 | } |
|||
1062 | |||||
1063 | public function socketClientFlags(int $value): void |
||||
1064 | { |
||||
1065 | $this->socketClientFlags = $value; |
||||
1066 | } |
||||
1067 | |||||
1068 | public function unixSocket(string $value): void |
||||
1069 | { |
||||
1070 | $this->unixSocket = $value; |
||||
1071 | } |
||||
1072 | |||||
1073 | public function useSSL(bool $useSSL): void |
||||
1074 | { |
||||
1075 | $this->useSSL = $useSSL; |
||||
1076 | } |
||||
1077 | |||||
1078 | /** |
||||
1079 | * Creates a command for execution. |
||||
1080 | * |
||||
1081 | * @param string|null $sql the SQL statement to be executed |
||||
1082 | * @param array $params the parameters to be bound to the SQL statement |
||||
1083 | * |
||||
1084 | * @throws NotSupportedException |
||||
1085 | * |
||||
1086 | * @return Command the DB command |
||||
1087 | */ |
||||
1088 | public function createCommand(?string $sql = null, array $params = []): Command |
||||
1089 | { |
||||
1090 | throw new NotSupportedException(get_class($this) . ' does not support Command::class.'); |
||||
1091 | } |
||||
1092 | |||||
1093 | /** |
||||
1094 | * @return string the Data Source Name, or DSN, contains the information required to connect to the database. |
||||
1095 | * |
||||
1096 | * Please refer to the [PHP manual](https://secure.php.net/manual/en/pdo.construct.php) on the format of the DSN |
||||
1097 | * string. |
||||
1098 | */ |
||||
1099 | public function getDsn(): string |
||||
1100 | { |
||||
1101 | return $this->dsn; |
||||
1102 | } |
||||
1103 | |||||
1104 | /** |
||||
1105 | * Returns the schema information for the database opened by this connection. |
||||
1106 | * |
||||
1107 | * @throws NotSupportedException |
||||
1108 | * |
||||
1109 | * @return Schema the schema information for the database opened by this connection. |
||||
1110 | */ |
||||
1111 | public function getSchema(): Schema |
||||
1112 | { |
||||
1113 | throw new NotSupportedException(get_class($this) . ' does not support Schema::class.'); |
||||
1114 | } |
||||
1115 | |||||
1116 | /** |
||||
1117 | * Returns a server version as a string comparable by {@see version_compare()}. |
||||
1118 | * |
||||
1119 | * @throws Exception |
||||
1120 | * |
||||
1121 | * @return string server version as a string. |
||||
1122 | */ |
||||
1123 | public function getServerVersion(): string |
||||
1124 | { |
||||
1125 | $version = (explode("\r\n", $this->executeCommand('INFO', ['server']))); |
||||
1126 | |||||
1127 | return $version[1]; |
||||
1128 | } |
||||
1129 | |||||
1130 | /** |
||||
1131 | * Obtains the schema information for the named table. |
||||
1132 | * |
||||
1133 | * @param string $name table name. |
||||
1134 | * @param bool $refresh whether to reload the table schema even if it is found in the cache. |
||||
1135 | * |
||||
1136 | * @throws NotSupportedException |
||||
1137 | * |
||||
1138 | * @return TableSchema|null |
||||
1139 | */ |
||||
1140 | public function getTableSchema($name, $refresh = false): ?TableSchema |
||||
1141 | { |
||||
1142 | throw new NotSupportedException(get_class($this) . ' does not support TableShema::class.'); |
||||
1143 | } |
||||
1144 | |||||
1145 | /** |
||||
1146 | * @inheritDoc |
||||
1147 | */ |
||||
1148 | public function isAutoSlaveForReadQueriesEnabled(): bool |
||||
1149 | { |
||||
1150 | throw new NotSupportedException(get_class($this) . ' does not support SetEnableSlaves() method.'); |
||||
1151 | } |
||||
1152 | |||||
1153 | /** |
||||
1154 | * Whether to enable read/write splitting by using {@see setSlaves()} to read data. Note that if {@see setSlaves()} |
||||
1155 | * is empty, read/write splitting will NOT be enabled no matter what value this property takes. |
||||
1156 | * |
||||
1157 | * @param bool $value |
||||
1158 | * |
||||
1159 | * @throws NotSupportedException |
||||
1160 | */ |
||||
1161 | public function setEnableSlaves(bool $value): void |
||||
0 ignored issues
–
show
The parameter
$value is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
1162 | { |
||||
1163 | throw new NotSupportedException(get_class($this) . ' does not support SetEnableSlaves() method.'); |
||||
1164 | } |
||||
1165 | |||||
1166 | /** |
||||
1167 | * Whether to enable schema caching. Note that in order to enable truly schema caching, a valid cache component as |
||||
1168 | * specified must be enabled and {@see setEnable()} must be set true. |
||||
1169 | * |
||||
1170 | * @param bool $value |
||||
1171 | */ |
||||
1172 | public function setSchemaCacheEnable(bool $value): void |
||||
0 ignored issues
–
show
The parameter
$value is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
1173 | { |
||||
1174 | throw new NotSupportedException(get_class($this) . ' does not support setSchemaCacheEnable() method.'); |
||||
1175 | } |
||||
1176 | |||||
1177 | /** |
||||
1178 | * Whether to enable query caching. Note that in order to enable query caching, a valid cache component as specified |
||||
1179 | * must be enabled and {@see enabled} must be set true. Also, only the results of the queries enclosed within |
||||
1180 | * {@see cache()} will be cached. |
||||
1181 | */ |
||||
1182 | public function setQueryCacheEnable(bool $value): void |
||||
0 ignored issues
–
show
The parameter
$value is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
1183 | { |
||||
1184 | throw new NotSupportedException(get_class($this) . ' does not support setQueryCacheEnable() method.'); |
||||
1185 | } |
||||
1186 | |||||
1187 | /** |
||||
1188 | * Quotes a column name for use in a query. |
||||
1189 | * |
||||
1190 | * If the column name contains prefix, the prefix will also be properly quoted. |
||||
1191 | * If the column name is already quoted or contains special characters including '(', '[[' and '{{', then this |
||||
1192 | * method will do nothing. |
||||
1193 | * |
||||
1194 | * @param string $name column name |
||||
1195 | * |
||||
1196 | * @return string the properly quoted column name |
||||
1197 | */ |
||||
1198 | public function quoteColumnName(string $name): string |
||||
0 ignored issues
–
show
The parameter
$name is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
1199 | { |
||||
1200 | throw new NotSupportedException(get_class($this) . ' does not support quoteColumnName() method.'); |
||||
1201 | } |
||||
1202 | } |
||||
1203 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.