Driver_Redis::__construct()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 32
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 5
nop 1
dl 0
loc 32
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Provides caching functionality for Redis
5
 *
6
 * PHP Version 5
7
 *
8
 * @category  Core
9
 * @package   Cache
10
 * @author    Hans-Joachim Piepereit <[email protected]>
11
 * @copyright 2013 cSphere Team
12
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
13
 * @link      http://www.csphere.eu
14
 **/
15
16
namespace csphere\core\cache;
17
18
/**
19
 * Provides caching functionality for Redis
20
 *
21
 * @category  Core
22
 * @package   Cache
23
 * @author    Hans-Joachim Piepereit <[email protected]>
24
 * @copyright 2013 cSphere Team
25
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
26
 * @link      http://www.csphere.eu
27
 **/
28
29
class Driver_Redis extends Base
30
{
31
    /**
32
     * Redis object
33
     **/
34
    private $_redis = null;
35
36
    /**
37
     * Creates the cache handler object
38
     *
39
     * @param array $config Configuration details as an array
40
     *
41
     * @throws \Exception
42
     *
43
     * @return \csphere\core\cache\Driver_Redis
44
     **/
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
45
46
    public function __construct(array $config)
47
    {
48
        parent::__construct($config);
49
50
        if (!extension_loaded('redis')) {
51
52
            throw new \Exception('Extension "redis" not found');
53
        }
54
55
        // Create redis object and connect to server
56
        $this->_redis = new \Redis();
57
58
        $check = $this->_redis->connect(
59
            $config['host'], (int)$config['port'], (int)$config['timeout']
60
        );
61
62
        if ($check === false) {
63
64
            throw new \Exception('Connection to "redis" failed');
65
        }
66
67
        // Authenticate connection if password is given
68
        if (!empty($config['password'])) {
69
70
            $auth = $this->_redis->auth($config['password']);
71
72
            if ($auth === false) {
73
74
                throw new \Exception('Authentication for "redis" failed');
75
            }
76
        }
77
    }
78
79
    /**
80
     * Clears the cache content
81
     *
82
     * @return boolean
83
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
84
85
    public function clear()
86
    {
87
        $this->_redis->flushDB();
88
89
        return true;
90
    }
91
92
    /**
93
     * Removes a cached key
94
     *
95
     * @param string $key Name of the key
96
     * @param int    $ttl Time to life used for the key
97
     *
98
     * @return boolean
99
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
100
101
    public function delete($key, $ttl = 0)
102
    {
103
        $token = empty($ttl) ? $key : 'ttl_' . $key;
104
105
        if ($this->_redis->exists($token)) {
106
107
            $this->_redis->delete($token);
108
        }
109
110
        return true;
111
    }
112
113
    /**
114
     * Returns a formatted array with statistics
115
     *
116
     * @return array
117
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
118
119
    public function info()
120
    {
121
        $info = parent::info();
122
123
        $redis_info = $this->_redis->info();
124
125
        $info['version'] = phpversion('redis');
126
        $info['client']  = $info['version'];
127
        $info['server']  = $redis_info['redis_version'];
128
        $info['keys']    = $this->_redis->dbSize();
129
130
        return $info;
131
    }
132
133
    /**
134
     * Returns a formatted array with all keys and additional information
135
     *
136
     * @return array
137
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
138
139
    public function keys()
140
    {
141
        $form = [];
142
143
        // Time request may not work in all cases
144
        $time = $this->_redis->time();
145
146
        if (is_array($time) && isset($time[0])) {
147
148
            $time = $time[0];
149
150
        } else {
151
152
            $time = (int)$time;
153
        }
154
155
        // Wildcard to get all keys
156
        $keys = $this->_redis->keys('*');
157
158
        foreach ($keys AS $key) {
159
160
            // Size hopes that storage uses UTF-8
161
            $size = $this->_redis->strlen($key);
162
163
            $form[$key] = ['name' => $key,
164
                           'time' => $time,
165
                           'size' => $size];
166
        }
167
168
        ksort($form);
169
170
        return array_values($form);
171
    }
172
173
    /**
174
     * Fetches the desired key
175
     *
176
     * @param string $key Name of the key
177
     * @param int    $ttl Time to life used for the key
178
     *
179
     * @return array
180
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
181
182
    public function load($key, $ttl = 0)
183
    {
184
        $token = empty($ttl) ? $key : 'ttl_' . $key;
185
186
        if ($this->_redis->exists($token)) {
187
188
            return unserialize($this->_redis->get($token));
189
        }
190
191
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type declared by the abstract method csphere\core\cache\Base::load of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
192
    }
193
194
    /**
195
     * Stores the key with its value in the cache
196
     *
197
     * @param string $key   Name of the key
198
     * @param array  $value Content to be stored
199
     * @param int    $ttl   Time to life used for the key
200
     *
201
     * @return boolean
202
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
203
204
    public function save($key, $value, $ttl = 0)
205
    {
206
        $token = empty($ttl) ? $key : 'ttl_' . $key;
207
208
        $this->_redis->set($token, serialize($value));
209
210
        if (!empty($ttl)) {
211
212
            $this->_redis->setTimeout($token, $ttl);
213
        }
214
215
        $this->log($key);
216
217
        return true;
218
    }
219
}
220