/client-libraries/php/redis.php
PHP | 330 lines | 272 code | 45 blank | 13 comment | 44 complexity | 4c350ea7e571357d1b1c270fb2427805 MD5 | raw file
Possible License(s): BSD-3-Clause
1<?php 2/******************************************************************************* 3 * Redis PHP Bindings - http://code.google.com/p/redis/ 4 * 5 * Copyright 2009 Ludovico Magnocavallo 6 * Released under the same license as Redis. 7 * 8 * Version: 0.1 9 * 10 * $Revision: 139 $ 11 * $Date: 2009-03-15 22:59:40 +0100 (Sun, 15 Mar 2009) $ 12 * 13 ******************************************************************************/ 14 15 16class Redis { 17 18 var $server; 19 var $port; 20 var $_sock; 21 22 function Redis($host, $port=6379) { 23 $this->host = $host; 24 $this->port = $port; 25 } 26 27 function connect() { 28 if ($this->_sock) 29 return; 30 if ($sock = fsockopen($this->host, $this->port, $errno, $errstr)) { 31 $this->_sock = $sock; 32 return; 33 } 34 $msg = "Cannot open socket to {$this->host}:{$this->port}"; 35 if ($errno || $errmsg) 36 $msg .= "," . ($errno ? " error $errno" : "") . ($errmsg ? " $errmsg" : ""); 37 trigger_error("$msg.", E_USER_ERROR); 38 } 39 40 function disconnect() { 41 if ($this->_sock) 42 @fclose($this->_sock); 43 $this->_sock = null; 44 } 45 46 function &ping() { 47 $this->connect(); 48 $this->_write("PING\r\n"); 49 return $this->_simple_response(); 50 } 51 52 function &do_echo($s) { 53 $this->connect(); 54 $this->_write("ECHO " . strlen($s) . "\r\n$s\r\n"); 55 return $this->_get_value(); 56 } 57 58 function &set($name, $value, $preserve=false) { 59 $this->connect(); 60 $this->_write( 61 ($preserve ? 'SETNX' : 'SET') . 62 " $name " . strlen($value) . "\r\n$value\r\n" 63 ); 64 return $preserve ? $this->_numeric_response() : $this->_simple_response(); 65 } 66 67 function &get($name) { 68 $this->connect(); 69 $this->_write("GET $name\r\n"); 70 return $this->_get_value(); 71 } 72 73 function &incr($name, $amount=1) { 74 $this->connect(); 75 if ($amount == 1) 76 $this->_write("INCR $name\r\n"); 77 else 78 $this->_write("INCRBY $name $amount\r\n"); 79 return $this->_numeric_response(); 80 } 81 82 function &decr($name, $amount=1) { 83 $this->connect(); 84 if ($amount == 1) 85 $this->_write("DECR $name\r\n"); 86 else 87 $this->_write("DECRBY $name $amount\r\n"); 88 return $this->_numeric_response(); 89 } 90 91 function &exists($name) { 92 $this->connect(); 93 $this->_write("EXISTS $name\r\n"); 94 return $this->_numeric_response(); 95 } 96 97 function &delete($name) { 98 $this->connect(); 99 $this->_write("DEL $name\r\n"); 100 return $this->_numeric_response(); 101 } 102 103 function &keys($pattern) { 104 $this->connect(); 105 $this->_write("KEYS $pattern\r\n"); 106 return explode(' ', $this->_get_value()); 107 } 108 109 function &randomkey() { 110 $this->connect(); 111 $this->_write("RANDOMKEY\r\n"); 112 $s =& trim($this->_read()); 113 $this->_check_for_error($s); 114 return $s; 115 } 116 117 function &rename($src, $dst, $preserve=False) { 118 $this->connect(); 119 if ($preserve) { 120 $this->_write("RENAMENX $src $dst\r\n"); 121 return $this->_numeric_response(); 122 } 123 $this->_write("RENAME $src $dst\r\n"); 124 return trim($this->_simple_response()); 125 } 126 127 function &push($name, $value, $tail=true) { 128 // default is to append the element to the list 129 $this->connect(); 130 $this->_write( 131 ($tail ? 'RPUSH' : 'LPUSH') . 132 " $name " . strlen($value) . "\r\n$value\r\n" 133 ); 134 return $this->_simple_response(); 135 } 136 137 function <rim($name, $start, $end) { 138 $this->connect(); 139 $this->_write("LTRIM $name $start $end\r\n"); 140 return $this->_simple_response(); 141 } 142 143 function &lindex($name, $index) { 144 $this->connect(); 145 $this->_write("LINDEX $name $index\r\n"); 146 return $this->_get_value(); 147 } 148 149 function &pop($name, $tail=true) { 150 $this->connect(); 151 $this->_write( 152 ($tail ? 'RPOP' : 'LPOP') . 153 " $name\r\n" 154 ); 155 return $this->_get_value(); 156 } 157 158 function &llen($name) { 159 $this->connect(); 160 $this->_write("LLEN $name\r\n"); 161 return $this->_numeric_response(); 162 } 163 164 function &lrange($name, $start, $end) { 165 $this->connect(); 166 $this->_write("LRANGE $name $start $end\r\n"); 167 return $this->_get_multi(); 168 } 169 170 function &sort($name, $query=false) { 171 $this->connect(); 172 if ($query === false) { 173 $this->_write("SORT $name\r\n"); 174 } else { 175 $this->_write("SORT $name $query\r\n"); 176 } 177 return $this->_get_multi(); 178 } 179 180 function &lset($name, $value, $index) { 181 $this->connect(); 182 $this->_write("LSET $name $index " . strlen($value) . "\r\n$value\r\n"); 183 return $this->_simple_response(); 184 } 185 186 function &sadd($name, $value) { 187 $this->connect(); 188 $this->_write("SADD $name " . strlen($value) . "\r\n$value\r\n"); 189 return $this->_numeric_response(); 190 } 191 192 function &srem($name, $value) { 193 $this->connect(); 194 $this->_write("SREM $name " . strlen($value) . "\r\n$value\r\n"); 195 return $this->_numeric_response(); 196 } 197 198 function &sismember($name, $value) { 199 $this->connect(); 200 $this->_write("SISMEMBER $name " . strlen($value) . "\r\n$value\r\n"); 201 return $this->_numeric_response(); 202 } 203 204 function &sinter($sets) { 205 $this->connect(); 206 $this->_write('SINTER ' . implode(' ', $sets) . "\r\n"); 207 return $this->_get_multi(); 208 } 209 210 function &smembers($name) { 211 $this->connect(); 212 $this->_write("SMEMBERS $name\r\n"); 213 return $this->_get_multi(); 214 } 215 216 function &scard($name) { 217 $this->connect(); 218 $this->_write("SCARD $name\r\n"); 219 return $this->_numeric_response(); 220 } 221 222 function &select_db($name) { 223 $this->connect(); 224 $this->_write("SELECT $name\r\n"); 225 return $this->_simple_response(); 226 } 227 228 function &move($name, $db) { 229 $this->connect(); 230 $this->_write("MOVE $name $db\r\n"); 231 return $this->_numeric_response(); 232 } 233 234 function &save($background=false) { 235 $this->connect(); 236 $this->_write(($background ? "BGSAVE\r\n" : "SAVE\r\n")); 237 return $this->_simple_response(); 238 } 239 240 function &lastsave() { 241 $this->connect(); 242 $this->_write("LASTSAVE\r\n"); 243 return $this->_numeric_response(); 244 } 245 246 function &_write($s) { 247 while ($s) { 248 $i = fwrite($this->_sock, $s); 249 if ($i == 0) 250 break; 251 $s = substr($s, $i); 252 } 253 } 254 255 function &_read($len=1024) { 256 if ($s = fgets($this->_sock)) 257 return $s; 258 $this->disconnect(); 259 trigger_error("Cannot read from socket.", E_USER_ERROR); 260 } 261 262 function _check_for_error(&$s) { 263 if (!$s || $s[0] != '-') 264 return; 265 if (substr($s, 0, 4) == '-ERR') 266 trigger_error("Redis error: " . trim(substr($s, 4)), E_USER_ERROR); 267 trigger_error("Redis error: " . substr(trim($this->_read()), 5), E_USER_ERROR); 268 } 269 270 function &_simple_response() { 271 $s =& trim($this->_read()); 272 if ($s[0] == '+') 273 return substr($s, 1); 274 if ($err =& $this->_check_for_error($s)) 275 return $err; 276 trigger_error("Cannot parse first line '$s' for a simple response", E_USER_ERROR); 277 } 278 279 function &_numeric_response($allow_negative=True) { 280 $s =& trim($this->_read()); 281 $i = (int)$s; 282 if ($i . '' == $s) { 283 if (!$allow_negative && $i < 0) 284 $this->_check_for_error($s); 285 return $i; 286 } 287 if ($s == 'nil') 288 return null; 289 trigger_error("Cannot parse '$s' as numeric response."); 290 } 291 292 function &_get_value() { 293 $s =& trim($this->_read()); 294 if ($s == 'nil') 295 return ''; 296 else if ($s[0] == '-') 297 $this->_check_for_error($s); 298 $i = (int)$s; 299 if ($i . '' != $s) 300 trigger_error("Cannot parse '$s' as data length."); 301 $buffer = ''; 302 while ($i > 0) { 303 $s = $this->_read(); 304 $l = strlen($s); 305 $i -= $l; 306 if ($l > $i) // ending crlf 307 $s = rtrim($s); 308 $buffer .= $s; 309 } 310 if ($i == 0) // let's restore the trailing crlf 311 $buffer .= $this->_read(); 312 return $buffer; 313 } 314 315 function &_get_multi() { 316 $results = array(); 317 $num =& $this->_numeric_response(false); 318 if ($num === false) 319 return $results; 320 while ($num) { 321 $results[] =& $this->_get_value(); 322 $num -= 1; 323 } 324 return $results; 325 } 326 327} 328 329 330?>