Kaynağa Gözat

Initial support for optional parameters when creating a Client instance. Optional authorization and database selection are now performed automatically upon connection.

Daniele Alessandri 15 yıl önce
ebeveyn
işleme
6df1d02e4c

+ 1 - 1
README.markdown

@@ -54,7 +54,7 @@ Furthermore, a pipeline can be initialized on a cluster of redis instances in th
 same exact way they are created on single connection. Sharding is still transparent 
 to the user:
 
-    $redis = Predis\Client::createCluster(
+    $redis = Predis\Client::create(
         array('host' => '10.0.0.1', 'port' => 6379),
         array('host' => '10.0.0.2', 'port' => 6379)
     );

+ 1 - 2
examples/CommandPipeline.php

@@ -4,8 +4,7 @@ require_once 'SharedConfigurations.php';
 // when you have a whole set of consecutive commands to send to 
 // a redis server, you can use a pipeline to improve performances.
 
-$redis = new Predis\Client(REDIS_HOST, REDIS_PORT);
-$redis->select(REDIS_DB);
+$redis = Predis\Client::create($configurations);
 
 $replies = $redis->pipeline(function($pipe) {
     $pipe->ping();

+ 1 - 2
examples/MultipleSetAndGet.php

@@ -11,8 +11,7 @@ $mkv = array(
     'usr:0003' => 'Third user' 
 );
 
-$redis = new Predis\Client(REDIS_HOST, REDIS_PORT);
-$redis->select(REDIS_DB);
+$redis = Predis\Client::create($configurations);
 
 $redis->mset($mkv);
 $retval = $redis->mget(array_keys($mkv));

+ 5 - 3
examples/SharedConfigurations.php

@@ -1,7 +1,9 @@
 <?php
 require_once '../lib/Predis.php';
 
-const REDIS_HOST = '127.0.0.1';
-const REDIS_PORT = 6379;
-const REDIS_DB   = 15;
+$configurations = array(
+    'host'     => '127.0.0.1', 
+    'port'     => 6379, 
+    'database' => 15
+);
 ?>

+ 1 - 2
examples/SimpleSetAndGet.php

@@ -3,8 +3,7 @@ require_once 'SharedConfigurations.php';
 
 // simple set and get scenario
 
-$redis = new Predis\Client(REDIS_HOST, REDIS_PORT);
-$redis->select(REDIS_DB);
+$redis = Predis\Client::create($configurations);
 
 $redis->set('library', 'predis');
 $retval = $redis->get('library');

+ 93 - 6
lib/Predis.php

@@ -25,16 +25,85 @@ class Client {
         $this->_connection->disconnect();
     }
 
-    public static function createCluster(/* arguments */) {
-        $cluster = new ConnectionCluster();
-        foreach (func_get_args() as $parameters) {
-            $cluster->add(new Connection($parameters['host'], $parameters['port']));
-        }
+    public static function create(/* arguments */) {
+        $argv = func_get_args();
+        $argc = func_num_args();
+
         $client = new Client();
-        $client->setConnection($cluster);
+
+        if ($argc == 1) {
+            $client->setConnection($client->createConnection($argv[0]));
+        }
+        else if ($argc > 1) {
+            $cluster = new ConnectionCluster();
+            foreach ($argv as $parameters) {
+                $cluster->add($client->createConnection($parameters));
+            }
+            $client->setConnection($cluster);
+        }
+
         return $client;
     }
 
+    private static function parseURI($uri) {
+        $parsed = @parse_url($uri);
+
+        if ($parsed == false || $parsed['scheme'] != 'redis' || $parsed['host'] == null) {
+            throw new ClientException("Invalid URI: $uri");
+        }
+
+        $details = array();
+        foreach (explode('&', $parsed['query']) as $kv) {
+            list($k, $v) = explode('=', $kv);
+            switch ($k) {
+                case 'database':
+                    $details['database'] = $v;
+                    break;
+                case 'password':
+                    $details['password'] = $v;
+                    break;
+            }
+        }
+
+        return self::filterConnectionParams(array_merge($parsed, $details));
+    }
+
+    private static function filterConnectionParams($parameters) {
+        return array(
+            'host' => $parameters['host'] != null 
+                ? $parameters['host'] 
+                : Connection::DEFAULT_HOST, 
+            'port' => $parameters['port'] != null 
+                ? (int) $parameters['port'] 
+                : Connection::DEFAULT_PORT, 
+            'database' => $parameters['database'], 
+            'password' => $parameters['password'], 
+        );
+    }
+
+    private function createConnection($connectionDetails) {
+        $parameters = is_array($connectionDetails) 
+            ? self::filterConnectionParams($connectionDetails) 
+            : self::parseURI($connectionDetails);
+
+        $connection = new Connection($parameters['host'], $parameters['port']);
+
+        if ($parameters['password'] !== null) {
+            $connection->pushInitCommand($this->createCommandInstance(
+                'auth', 
+                array($parameters['password'])
+            ));
+        }
+        if ($parameters['database'] !== null) {
+            $connection->pushInitCommand($this->createCommandInstance(
+                'select', 
+                array($parameters['database'])
+            ));
+        }
+
+        return $connection;
+    }
+
     private function setConnection(IConnection $connection) {
         $this->_connection = $connection;
     }
@@ -534,6 +603,7 @@ class Connection implements IConnection {
     public function __construct($host = self::DEFAULT_HOST, $port = self::DEFAULT_PORT) {
         $this->_host = $host;
         $this->_port = $port;
+        $this->_initCmds = array();
     }
 
     public function __destruct() {
@@ -554,6 +624,10 @@ class Connection implements IConnection {
             throw new ClientException(trim($errstr), $errno);
         }
         stream_set_timeout($this->_socket, self::READ_WRITE_TIMEOUT);
+
+        if (count($this->_initCmds) > 0){
+            $this->sendInitializationCommands();
+        }
     }
 
     public function disconnect() {
@@ -562,6 +636,19 @@ class Connection implements IConnection {
         }
     }
 
+    public function pushInitCommand(Command $command){
+        $this->_initCmds[] = $command;
+    }
+
+    private function sendInitializationCommands() {
+        foreach ($this->_initCmds as $command) {
+            $this->writeCommand($command);
+        }
+        foreach ($this->_initCmds as $command) {
+            $this->readResponse($command);
+        }
+    }
+
     public function writeCommand(Command $command) {
         fwrite($this->getSocket(), $command());
     }