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