123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- <?php namespace Laravel;
- class Redis {
-
- protected $host;
-
- protected $port;
-
- protected $database;
-
- protected $connection;
-
- protected static $databases = array();
-
- public function __construct($host, $port, $database = 0)
- {
- $this->host = $host;
- $this->port = $port;
- $this->database = $database;
- }
-
- public static function db($name = 'default')
- {
- if ( ! isset(static::$databases[$name]))
- {
- if (is_null($config = Config::get("database.redis.{$name}")))
- {
- throw new \Exception("Redis database [$name] is not defined.");
- }
- extract($config);
- static::$databases[$name] = new static($host, $port, $database);
- }
- return static::$databases[$name];
- }
-
- public function run($method, $parameters)
- {
- fwrite($this->connect(), $this->command($method, (array) $parameters));
- $response = trim(fgets($this->connection, 512));
- return $this->parse($response);
- }
-
- protected function parse($response)
- {
- switch (substr($response, 0, 1))
- {
- case '-':
- throw new \Exception('Redis error: '.substr(trim($response), 4));
-
- case '+':
- case ':':
- return $this->inline($response);
-
- case '$':
- return $this->bulk($response);
-
- case '*':
- return $this->multibulk($response);
-
- default:
- throw new \Exception("Unknown Redis response: ".substr($response, 0, 1));
- }
- }
-
- protected function connect()
- {
- if ( ! is_null($this->connection)) return $this->connection;
- $this->connection = @fsockopen($this->host, $this->port, $error, $message);
- if ($this->connection === false)
- {
- throw new \Exception("Error making Redis connection: {$error} - {$message}");
- }
- $this->select($this->database);
- return $this->connection;
- }
-
- protected function command($method, $parameters)
- {
- $command = '*'.(count($parameters) + 1).CRLF;
- $command .= '$'.strlen($method).CRLF;
- $command .= strtoupper($method).CRLF;
- foreach ($parameters as $parameter)
- {
- $command .= '$'.strlen($parameter).CRLF.$parameter.CRLF;
- }
- return $command;
- }
-
- protected function inline($response)
- {
- return substr(trim($response), 1);
- }
-
- protected function bulk($head)
- {
- if ($head == '$-1') return;
- list($read, $response, $size) = array(0, '', substr($head, 1));
- if ($size > 0)
- {
- do
- {
-
-
-
- $block = (($remaining = $size - $read) < 1024) ? $remaining : 1024;
- $response .= fread($this->connection, $block);
- $read += $block;
- } while ($read < $size);
- }
-
-
-
- fread($this->connection, 2);
- return $response;
- }
-
- protected function multibulk($head)
- {
- if (($count = substr($head, 1)) == '-1') return;
- $response = array();
-
-
-
- for ($i = 0; $i < $count; $i++)
- {
- $response[] = $this->parse(trim(fgets($this->connection, 512)));
- }
- return $response;
- }
-
- public function __call($method, $parameters)
- {
- return $this->run($method, $parameters);
- }
-
- public static function __callStatic($method, $parameters)
- {
- return static::db()->run($method, $parameters);
- }
-
- public function __destruct()
- {
- if ($this->connection)
- {
- fclose($this->connection);
- }
- }
- }
|