@@ -20,118 +20,123 @@ class RedisException extends Exception {
20
20
*/
21
21
class Redisent {
22
22
23
- /**
24
- * Socket connection to the Redis server
25
- * @var resource
26
- * @access private
27
- */
28
- private $ __sock ;
23
+ /**
24
+ * Socket connection to the Redis server
25
+ * @var resource
26
+ * @access private
27
+ */
28
+ private $ __sock ;
29
29
30
- /**
31
- * Redis bulk commands, they are sent in a slightly different format to the server
32
- * @var array
33
- * @access private
34
- */
35
- private $ bulk_cmds = array (
36
- 'SET ' , 'GETSET ' , 'SETNX ' , 'ECHO ' ,
37
- 'RPUSH ' , 'LPUSH ' , 'LSET ' , 'LREM ' ,
38
- 'SADD ' , 'SREM ' , 'SMOVE ' , 'SISMEMBER '
39
- );
30
+ /**
31
+ * Host of the Redis server
32
+ * @var string
33
+ * @access public
34
+ */
35
+ public $ host ;
40
36
41
- /**
42
- * Creates a Redisent connection to the Redis server on host {@link $host} and port {@link $port}.
43
- * @param string $host The hostname of the Redis server
44
- * @param integer $port The port number of the Redis server
45
- */
46
- function __construct ($ host , $ port = 6379 ) {
47
- $ this ->__sock = fsockopen ($ host , $ port , $ errno , $ errstr );
48
- if (!$ this ->__sock ) {
49
- throw new Exception ("{$ errno } - {$ errstr }" );
50
- }
51
- }
37
+ /**
38
+ * Port on which the Redis server is running
39
+ * @var integer
40
+ * @access public
41
+ */
42
+ public $ port ;
52
43
53
- function __destruct () {
54
- fclose ($ this ->__sock );
55
- }
44
+ /**
45
+ * Creates a Redisent connection to the Redis server on host {@link $host} and port {@link $port}.
46
+ * @param string $host The hostname of the Redis server
47
+ * @param integer $port The port number of the Redis server
48
+ */
49
+ function __construct ($ host , $ port = 6379 ) {
50
+ $ this ->host = $ host ;
51
+ $ this ->port = $ port ;
52
+ $ this ->__sock = fsockopen ($ this ->host , $ this ->port , $ errno , $ errstr );
53
+ if (!$ this ->__sock ) {
54
+ throw new \Exception ("{$ errno } - {$ errstr }" );
55
+ }
56
+ }
56
57
57
- function __call ($ name , $ args ) {
58
+ function __destruct () {
59
+ fclose ($ this ->__sock );
60
+ }
58
61
59
- /* Build the Redis protocol command */
60
- $ name = strtoupper ($ name );
61
- if (in_array ($ name , $ this ->bulk_cmds )) {
62
- $ value = array_pop ($ args );
63
- $ command = sprintf ("%s %s %d%s%s%s " , $ name , trim (implode (' ' , $ args )), strlen ($ value ), CRLF , $ value , CRLF );
64
- }
65
- else {
66
- $ command = sprintf ("%s %s%s " , $ name , trim (implode (' ' , $ args )), CRLF );
67
- }
62
+ function __call ($ name , $ args ) {
68
63
69
- /* Open a Redis connection and execute the command */
70
- fwrite ($ this ->__sock , $ command );
64
+ /* Build the Redis unified protocol command */
65
+ array_unshift ($ args , strtoupper ($ name ));
66
+ $ command = sprintf ('*%d%s%s%s ' , count ($ args ), CRLF , implode (array_map (function ($ arg ) {
67
+ return sprintf ('$%d%s%s ' , strlen ($ arg ), CRLF , $ arg );
68
+ }, $ args ), CRLF ), CRLF );
71
69
72
- /* Parse the response based on the reply identifier */
73
- $ reply = trim (fgets ($ this ->__sock , 512 ));
74
- switch (substr ($ reply , 0 , 1 )) {
75
- /* Error reply */
76
- case '- ' :
77
- echo $ command ."\n" ;
78
- throw new RedisException (substr (trim ($ reply ), 4 ));
79
- break ;
80
- /* Inline reply */
81
- case '+ ' :
82
- $ response = substr (trim ($ reply ), 1 );
83
- break ;
84
- /* Bulk reply */
85
- case '$ ' :
86
- $ response = null ;
87
- if ($ reply == '$-1 ' ) {
88
- break ;
89
- }
90
- $ read = 0 ;
91
- $ size = substr ($ reply , 1 );
92
- do {
93
- $ block_size = ($ size - $ read ) > 1024 ? 1024 : ($ size - $ read );
94
- $ response .= fread ($ this ->__sock , $ block_size );
95
- $ read += $ block_size ;
96
- } while ($ read < $ size );
97
- fread ($ this ->__sock , 2 ); /* discard crlf */
98
- break ;
99
- /* Multi-bulk reply */
100
- case '* ' :
101
- $ count = substr ($ reply , 1 );
102
- if ($ count == '-1 ' ) {
103
- return null ;
104
- }
105
- $ response = array ();
106
- for ($ i = 0 ; $ i < $ count ; $ i ++) {
107
- $ bulk_head = trim (fgets ($ this ->__sock , 512 ));
108
- $ size = substr ($ bulk_head , 1 );
109
- if ($ size == '-1 ' ) {
110
- $ response [] = null ;
111
- }
112
- else {
113
- $ read = 0 ;
114
- $ block = "" ;
115
- do {
116
- $ block_size = ($ size - $ read ) > 1024 ? 1024 : ($ size - $ read );
117
- $ block .= fread ($ this ->__sock , $ block_size );
118
- $ read += $ block_size ;
119
- } while ($ read < $ size );
120
- fread ($ this ->__sock , 2 ); /* discard crlf */
121
- $ response [] = $ block ;
122
- }
123
- }
124
- break ;
125
- /* Integer reply */
126
- case ': ' :
127
- $ response = substr (trim ($ reply ), 1 );
128
- break ;
129
- default :
130
- throw new RedisException ("invalid server response: {$ reply }" );
131
- break ;
132
- }
133
- /* Party on */
134
- return $ response ;
135
- }
70
+ /* Open a Redis connection and execute the command */
71
+ for ($ written = 0 ; $ written < strlen ($ command ); $ written += $ fwrite ) {
72
+ $ fwrite = fwrite ($ this ->__sock , substr ($ command , $ written ));
73
+ if ($ fwrite === FALSE ) {
74
+ throw new \Exception ('Failed to write entire command to stream ' );
75
+ }
76
+ }
77
+
78
+ /* Parse the response based on the reply identifier */
79
+ $ reply = trim (fgets ($ this ->__sock , 512 ));
80
+ switch (substr ($ reply , 0 , 1 )) {
81
+ /* Error reply */
82
+ case '- ' :
83
+ throw new RedisException (substr (trim ($ reply ), 4 ));
84
+ break ;
85
+ /* Inline reply */
86
+ case '+ ' :
87
+ $ response = substr (trim ($ reply ), 1 );
88
+ break ;
89
+ /* Bulk reply */
90
+ case '$ ' :
91
+ $ response = null ;
92
+ if ($ reply == '$-1 ' ) {
93
+ break ;
94
+ }
95
+ $ read = 0 ;
96
+ $ size = substr ($ reply , 1 );
97
+ do {
98
+ $ block_size = ($ size - $ read ) > 1024 ? 1024 : ($ size - $ read );
99
+ $ response .= fread ($ this ->__sock , $ block_size );
100
+ $ read += $ block_size ;
101
+ } while ($ read < $ size );
102
+ fread ($ this ->__sock , 2 ); /* discard crlf */
103
+ break ;
104
+ /* Multi-bulk reply */
105
+ case '* ' :
106
+ $ count = substr ($ reply , 1 );
107
+ if ($ count == '-1 ' ) {
108
+ return null ;
109
+ }
110
+ $ response = array ();
111
+ for ($ i = 0 ; $ i < $ count ; $ i ++) {
112
+ $ bulk_head = trim (fgets ($ this ->__sock , 512 ));
113
+ $ size = substr ($ bulk_head , 1 );
114
+ if ($ size == '-1 ' ) {
115
+ $ response [] = null ;
116
+ }
117
+ else {
118
+ $ read = 0 ;
119
+ $ block = "" ;
120
+ do {
121
+ $ block_size = ($ size - $ read ) > 1024 ? 1024 : ($ size - $ read );
122
+ $ block .= fread ($ this ->__sock , $ block_size );
123
+ $ read += $ block_size ;
124
+ } while ($ read < $ size );
125
+ fread ($ this ->__sock , 2 ); /* discard crlf */
126
+ $ response [] = $ block ;
127
+ }
128
+ }
129
+ break ;
130
+ /* Integer reply */
131
+ case ': ' :
132
+ $ response = intval (substr (trim ($ reply ), 1 ));
133
+ break ;
134
+ default :
135
+ throw new RedisException ("invalid server response: {$ reply }" );
136
+ break ;
137
+ }
138
+ /* Party on */
139
+ return $ response ;
140
+ }
136
141
137
142
}
0 commit comments