1 <?php
  2   3   4   5   6   7 
  8 
  9 namespace Cross\Cache\Driver;
 10 
 11 use Cross\Exception\CoreException;
 12 use Redis;
 13 
 14  15  16  17  18 
 19 class RedisDriver
 20 {
 21      22  23 
 24     private $id;
 25 
 26      27  28 
 29     protected $link;
 30 
 31      32  33 
 34     protected $option;
 35 
 36      37  38  39  40  41  42  43  44  45  46 
 47     function __construct(array $option)
 48     {
 49         if (!extension_loaded('redis')) {
 50             throw new CoreException('Not support redis extension !');
 51         }
 52 
 53         if (!isset($option['host'])) {
 54             $option['host'] = '127.0.0.1';
 55         }
 56 
 57         if (!isset($option['port'])) {
 58             $option['port'] = 6379;
 59         }
 60 
 61         if (!isset($option['timeout'])) {
 62             $option['timeout'] = 3;
 63         }
 64 
 65         if (strcasecmp(PHP_OS, 'linux') == 0 && !empty($option['unix_socket'])) {
 66             $id = $option['unix_socket'];
 67             $use_unix_socket = true;
 68         } else {
 69             $id = "{$option['host']}:{$option['port']}:{$option['timeout']}";
 70             $use_unix_socket = false;
 71         }
 72 
 73         static $connects;
 74         if (!isset($connects[$id])) {
 75             $redis = new Redis();
 76             if ($use_unix_socket) {
 77                 $redis->connect($option['unix_socket']);
 78             } else {
 79                 $redis->connect($option['host'], $option['port'], $option['timeout']);
 80             }
 81 
 82             if (!empty($option['pass'])) {
 83                 $authStatus = $redis->auth($option['pass']);
 84                 if (!$authStatus) {
 85                     throw new CoreException('Redis auth failed !');
 86                 }
 87             }
 88 
 89             $connects[$id] = $redis;
 90         } else {
 91             $redis = &$connects[$id];
 92         }
 93 
 94         $this->id = $id;
 95         $this->link = $redis;
 96         $this->option = $option;
 97     }
 98 
 99     100 101 102 103 
104     function getLinkOption()
105     {
106         return $this->option;
107     }
108 
109     110 111 112 113 114 115 116 
117     public function __call($method, $argv)
118     {
119         $result = null;
120         if (method_exists($this->link, $method)) {
121             $this->selectCurrentDatabase();
122             $result = ($argv == null)
123                 ? $this->link->$method()
124                 : call_user_func_array(array($this->link, $method), $argv);
125         }
126 
127         return $result;
128     }
129 
130     131 132 133 134 
135     protected function selectCurrentDatabase()
136     {
137         static $selected = null;
138 
139         $db = &$this->option['db'];
140         $current = $this->id . ':' . $db;
141         if ($selected !== $current) {
142             $select_ret = $this->link->select($db);
143             if ($select_ret) {
144                 $selected = $current;
145             } else {
146                 throw new CoreException("Redis select DB($current) failed!");
147             }
148         }
149     }
150 }
151