]> git.saurik.com Git - redis.git/blame - client-libraries/php/redis.php
PHP client ported to PHP5 and fixed
[redis.git] / client-libraries / php / redis.php
CommitLineData
ed9b544e 1<?php
2/*******************************************************************************
3 * Redis PHP Bindings - http://code.google.com/p/redis/
4 *
5 * Copyright 2009 Ludovico Magnocavallo
8d03032a 6 * Copyright 2009 Salvatore Sanfilippo (ported it to PHP5, fixed some bug)
ed9b544e 7 * Released under the same license as Redis.
8 *
9 * Version: 0.1
10 *
11 * $Revision: 139 $
12 * $Date: 2009-03-15 22:59:40 +0100 (Dom, 15 Mar 2009) $
13 *
14 ******************************************************************************/
15
16
17class Redis {
8d03032a 18 public $server;
19 public $port;
20 private $_sock;
21
22 public function __construct($host='localhost', $port=6379) {
ed9b544e 23 $this->host = $host;
24 $this->port = $port;
25 }
26
8d03032a 27 public function connect() {
28 if ($this->_sock) return;
ed9b544e 29 if ($sock = fsockopen($this->host, $this->port, $errno, $errstr)) {
30 $this->_sock = $sock;
31 return;
32 }
33 $msg = "Cannot open socket to {$this->host}:{$this->port}";
34 if ($errno || $errmsg)
8d03032a 35 $msg .= "," . ($errno ? " error $errno" : "") .
36 ($errmsg ? " $errmsg" : "");
ed9b544e 37 trigger_error("$msg.", E_USER_ERROR);
38 }
39
8d03032a 40 public function disconnect() {
41 if ($this->_sock) @fclose($this->_sock);
ed9b544e 42 $this->_sock = null;
43 }
44
8d03032a 45 public function ping() {
ed9b544e 46 $this->connect();
8d03032a 47 $this->write("PING\r\n");
bb7dcc1e 48 return $this->get_response();
ed9b544e 49 }
50
8d03032a 51 public function do_echo($s) {
ed9b544e 52 $this->connect();
8d03032a 53 $this->write("ECHO " . strlen($s) . "\r\n$s\r\n");
54 return $this->get_response();
ed9b544e 55 }
56
8d03032a 57 public function set($name, $value, $preserve=false) {
ed9b544e 58 $this->connect();
8d03032a 59 $this->write(
ed9b544e 60 ($preserve ? 'SETNX' : 'SET') .
61 " $name " . strlen($value) . "\r\n$value\r\n"
62 );
bb7dcc1e 63 return $this->get_response();
ed9b544e 64 }
65
8d03032a 66 public function get($name) {
ed9b544e 67 $this->connect();
8d03032a 68 $this->write("GET $name\r\n");
69 return $this->get_response();
ed9b544e 70 }
71
8d03032a 72 public function incr($name, $amount=1) {
ed9b544e 73 $this->connect();
74 if ($amount == 1)
8d03032a 75 $this->write("INCR $name\r\n");
ed9b544e 76 else
8d03032a 77 $this->write("INCRBY $name $amount\r\n");
bb7dcc1e 78 return $this->get_response();
ed9b544e 79 }
80
8d03032a 81 public function decr($name, $amount=1) {
ed9b544e 82 $this->connect();
83 if ($amount == 1)
8d03032a 84 $this->write("DECR $name\r\n");
ed9b544e 85 else
8d03032a 86 $this->write("DECRBY $name $amount\r\n");
bb7dcc1e 87 return $this->get_response();
ed9b544e 88 }
89
8d03032a 90 public function exists($name) {
ed9b544e 91 $this->connect();
8d03032a 92 $this->write("EXISTS $name\r\n");
bb7dcc1e 93 return $this->get_response();
ed9b544e 94 }
95
8d03032a 96 public function delete($name) {
ed9b544e 97 $this->connect();
8d03032a 98 $this->write("DEL $name\r\n");
bb7dcc1e 99 return $this->get_response();
ed9b544e 100 }
101
8d03032a 102 public function keys($pattern) {
ed9b544e 103 $this->connect();
8d03032a 104 $this->write("KEYS $pattern\r\n");
105 return explode(' ', $this->get_response());
ed9b544e 106 }
107
8d03032a 108 public function randomkey() {
ed9b544e 109 $this->connect();
8d03032a 110 $this->write("RANDOMKEY\r\n");
bb7dcc1e 111 return $this->get_response();
ed9b544e 112 }
113
8d03032a 114 public function rename($src, $dst) {
115 $this->connect();
116 $this->write("RENAME $src $dst\r\n");
117 return $this->get_response();
118 }
119
120 public function renamenx($src, $dst) {
ed9b544e 121 $this->connect();
8d03032a 122 $this->write("RENAMENX $src $dst\r\n");
bb7dcc1e 123 return $this->get_response();
ed9b544e 124 }
125
8d03032a 126 public function expire($name, $time) {
9a2944ac 127 $this->connect();
8d03032a 128 $this->write("EXPIRE $name $time\r\n");
9a2944ac
LM
129 return $this->get_response();
130 }
131
8d03032a 132 public function push($name, $value, $tail=true) {
ed9b544e 133 // default is to append the element to the list
134 $this->connect();
8d03032a 135 $this->write(
ed9b544e 136 ($tail ? 'RPUSH' : 'LPUSH') .
137 " $name " . strlen($value) . "\r\n$value\r\n"
138 );
bb7dcc1e 139 return $this->get_response();
ed9b544e 140 }
8d03032a 141
142 public function lpush($name, $value) {
143 return $this->push($name, $value, false);
144 }
145
146 public function rpush($name, $value) {
147 return $this->push($name, $value, true);
148 }
149
150 public function ltrim($name, $start, $end) {
ed9b544e 151 $this->connect();
8d03032a 152 $this->write("LTRIM $name $start $end\r\n");
bb7dcc1e 153 return $this->get_response();
ed9b544e 154 }
155
8d03032a 156 public function lindex($name, $index) {
ed9b544e 157 $this->connect();
8d03032a 158 $this->write("LINDEX $name $index\r\n");
159 return $this->get_response();
ed9b544e 160 }
161
8d03032a 162 public function pop($name, $tail=true) {
ed9b544e 163 $this->connect();
8d03032a 164 $this->write(
ed9b544e 165 ($tail ? 'RPOP' : 'LPOP') .
166 " $name\r\n"
167 );
8d03032a 168 return $this->get_response();
169 }
170
171 public function lpop($name, $value) {
172 return $this->pop($name, $value, false);
173 }
174
175 public function rpop($name, $value) {
176 return $this->pop($name, $value, true);
ed9b544e 177 }
178
8d03032a 179 public function llen($name) {
ed9b544e 180 $this->connect();
8d03032a 181 $this->write("LLEN $name\r\n");
bb7dcc1e 182 return $this->get_response();
ed9b544e 183 }
184
8d03032a 185 public function lrange($name, $start, $end) {
ed9b544e 186 $this->connect();
8d03032a 187 $this->write("LRANGE $name $start $end\r\n");
bb7dcc1e 188 return $this->get_response();
ed9b544e 189 }
190
8d03032a 191 public function sort($name, $query=false) {
ed9b544e 192 $this->connect();
8d03032a 193 $this->write($query == false ? "SORT $name\r\n" : "SORT $name $query\r\n");
bb7dcc1e 194 return $this->get_response();
ed9b544e 195 }
196
8d03032a 197 public function lset($name, $value, $index) {
ed9b544e 198 $this->connect();
8d03032a 199 $this->write("LSET $name $index " . strlen($value) . "\r\n$value\r\n");
bb7dcc1e 200 return $this->get_response();
ed9b544e 201 }
202
8d03032a 203 public function sadd($name, $value) {
ed9b544e 204 $this->connect();
8d03032a 205 $this->write("SADD $name " . strlen($value) . "\r\n$value\r\n");
bb7dcc1e 206 return $this->get_response();
ed9b544e 207 }
208
8d03032a 209 public function srem($name, $value) {
ed9b544e 210 $this->connect();
8d03032a 211 $this->write("SREM $name " . strlen($value) . "\r\n$value\r\n");
bb7dcc1e 212 return $this->get_response();
ed9b544e 213 }
214
8d03032a 215 public function sismember($name, $value) {
ed9b544e 216 $this->connect();
8d03032a 217 $this->write("SISMEMBER $name " . strlen($value) . "\r\n$value\r\n");
bb7dcc1e 218 return $this->get_response();
ed9b544e 219 }
220
8d03032a 221 public function sinter($sets) {
ed9b544e 222 $this->connect();
8d03032a 223 $this->write('SINTER ' . implode(' ', $sets) . "\r\n");
bb7dcc1e 224 return $this->get_response();
ed9b544e 225 }
226
8d03032a 227 public function smembers($name) {
ed9b544e 228 $this->connect();
8d03032a 229 $this->write("SMEMBERS $name\r\n");
bb7dcc1e 230 return $this->get_response();
ed9b544e 231 }
232
8d03032a 233 public function scard($name) {
ed9b544e 234 $this->connect();
8d03032a 235 $this->write("SCARD $name\r\n");
bb7dcc1e 236 return $this->get_response();
ed9b544e 237 }
238
8d03032a 239 public function select_db($name) {
ed9b544e 240 $this->connect();
8d03032a 241 $this->write("SELECT $name\r\n");
bb7dcc1e 242 return $this->get_response();
ed9b544e 243 }
244
8d03032a 245 public function move($name, $db) {
ed9b544e 246 $this->connect();
8d03032a 247 $this->write("MOVE $name $db\r\n");
bb7dcc1e 248 return $this->get_response();
ed9b544e 249 }
250
8d03032a 251 public function save($background=false) {
ed9b544e 252 $this->connect();
8d03032a 253 $this->write(($background ? "BGSAVE\r\n" : "SAVE\r\n"));
bb7dcc1e 254 return $this->get_response();
ed9b544e 255 }
256
8d03032a 257 public function bgsave($background=false) {
258 return $this->save(true);
259 }
260
261 public function lastsave() {
ed9b544e 262 $this->connect();
8d03032a 263 $this->write("LASTSAVE\r\n");
bb7dcc1e
LM
264 return $this->get_response();
265 }
266
8d03032a 267 public function flushdb($all=false) {
bb7dcc1e 268 $this->connect();
8d03032a 269 $this->write($all ? "FLUSHALL\r\n" : "FLUSHDB\r\n");
bb7dcc1e
LM
270 return $this->get_response();
271 }
8d03032a 272
273 public function flushall() {
274 return $this->flush(true);
275 }
bb7dcc1e 276
8d03032a 277 public function info() {
bb7dcc1e 278 $this->connect();
8d03032a 279 $this->write("INFO\r\n");
bb7dcc1e
LM
280 $info = array();
281 $data =& $this->get_response();
282 foreach (explode("\r\n", $data) as $l) {
283 if (!$l)
284 continue;
285 list($k, $v) = explode(':', $l, 2);
286 $_v = strpos($v, '.') !== false ? (float)$v : (int)$v;
287 $info[$k] = (string)$_v == $v ? $_v : $v;
288 }
289 return $info;
ed9b544e 290 }
291
8d03032a 292 private function write($s) {
ed9b544e 293 while ($s) {
294 $i = fwrite($this->_sock, $s);
bb7dcc1e 295 if ($i == 0) // || $i == strlen($s))
ed9b544e 296 break;
297 $s = substr($s, $i);
298 }
299 }
300
8d03032a 301 private function read($len=1024) {
ed9b544e 302 if ($s = fgets($this->_sock))
303 return $s;
304 $this->disconnect();
305 trigger_error("Cannot read from socket.", E_USER_ERROR);
306 }
307
8d03032a 308 private function get_response() {
309 $data = trim($this->read());
bb7dcc1e
LM
310 $c = $data[0];
311 $data = substr($data, 1);
312 switch ($c) {
313 case '-':
8d03032a 314 trigger_error($data, E_USER_ERROR);
bb7dcc1e
LM
315 break;
316 case '+':
317 return $data;
8d03032a 318 case ':':
319 $i = strpos($data, '.') !== false ? (int)$data : (float)$data;
320 if ((string)$i != $data)
321 trigger_error("Cannot convert data '$c$data' to integer", E_USER_ERROR);
322 return $i;
323 case '$':
324 return $this->get_bulk_reply($c . $data);
bb7dcc1e
LM
325 case '*':
326 $num = (int)$data;
327 if ((string)$num != $data)
328 trigger_error("Cannot convert multi-response header '$data' to integer", E_USER_ERROR);
329 $result = array();
330 for ($i=0; $i<$num; $i++)
8d03032a 331 $result[] =& $this->get_response();
bb7dcc1e
LM
332 return $result;
333 default:
8d03032a 334 trigger_error("Invalid reply type byte: '$c'");
ed9b544e 335 }
bb7dcc1e
LM
336 }
337
8d03032a 338 private function get_bulk_reply($data=null) {
bb7dcc1e 339 if ($data === null)
8d03032a 340 $data = trim($this->read());
bb7dcc1e 341 if ($data == '$-1')
ed9b544e 342 return null;
bb7dcc1e
LM
343 $c = $data[0];
344 $data = substr($data, 1);
8d03032a 345 $bulklen = (int)$data;
346 if ((string)$bulklen != $data)
347 trigger_error("Cannot convert bulk read header '$c$data' to integer", E_USER_ERROR);
bb7dcc1e
LM
348 if ($c != '$')
349 trigger_error("Unkown response prefix for '$c$data'", E_USER_ERROR);
ed9b544e 350 $buffer = '';
8d03032a 351 while ($bulklen) {
352 $data = fread($this->_sock,$bulklen);
353 $bulklen -= strlen($data);
bb7dcc1e 354 $buffer .= $data;
ed9b544e 355 }
8d03032a 356 $crlf = fread($this->_sock,2);
357 return $buffer;
ed9b544e 358 }
8d03032a 359}
ed9b544e 360
8d03032a 361$r = new Redis();
362var_dump($r->get("foo"));
363var_dump($r->info());
ed9b544e 364
365?>