PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/client-libraries/php/redis.php

http://redis.googlecode.com/
PHP | 330 lines | 272 code | 45 blank | 13 comment | 44 complexity | 4c350ea7e571357d1b1c270fb2427805 MD5 | raw file
  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 &ltrim($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?>