Completed
Push — master ( 579af5...b29473 )
by Oleg
07:53
created

MemcachedCache::__construct()   C

Complexity

Conditions 11
Paths 38

Size

Total Lines 40
Code Lines 27

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 40
rs 5.2653
cc 11
eloc 27
nc 38
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php /** MicroMemcachedCache */
2
3
namespace Micro\Cache;
4
5
use Micro\Base\Exception;
6
7
/**
8
 * Class MemcachedCache
9
 *
10
 * @author Oleg Lunegov <[email protected]>
11
 * @link https://github.com/lugnsk/micro
12
 * @copyright Copyright &copy; 2013 Oleg Lunegov
13
 * @license /LICENSE
14
 * @package Micro
15
 * @subpackage Cache
16
 * @version 1.0
17
 * @since 1.0
18
 */
19
class MemcachedCache extends BaseCache
20
{
21
    /** @var \Memcache|\Memcached $driver driver memcache(d) */
22
    protected $driver;
23
24
    /**
25
     * Constructor
26
     *
27
     * @access public
28
     *
29
     * @param array $config config array
30
     *
31
     * @result void
32
     * @throws Exception
33
     */
34
    public function __construct(array $config = [])
35
    {
36
        parent::__construct($config);
37
38
        if (empty($config['type']) || !$this->check()) {
39
            throw new Exception('Memcache(d) not installed or not select type');
40
        }
41
42
        switch (strtolower($config['type'])) {
43
            case 'memcached':
44
                $this->driver = new \Memcached;
45
                break;
46
47
            case 'memcache':
48
                $this->driver = new \Memcache;
49
                break;
50
51
            default:
52
                throw new Exception('Selected type not valid in the driver');
53
        }
54
55
        if (!empty($config['servers'])) {
56
            $this->driver->addServers($config['servers']);
0 ignored issues
show
Bug introduced by
The method addServers does only exist in Memcached, but not in Memcache.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
57
        } elseif ($config['server']) {
58
            $conf = $config['server'];
59
            $server = [
60
                'hostname' => (!empty($conf['hostname']) ? $conf['hostname'] : '127.0.0.1'),
61
                'port' => (!empty($conf['port']) ? $conf['port'] : 11211),
62
                'weight' => (!empty($conf['weight']) ? $conf['weight'] : 1)
63
            ];
64
65
            if (get_class($this->driver) === 'Memcached') {
66
                $this->driver->addServer($server['hostname'], $server['port'], $server['weight']);
67
            } else {
68
                $this->driver->addServer($server['hostname'], $server['port'], true, $server['weight']);
69
            }
70
        } else {
71
            throw new Exception('Server(s) not configured');
72
        }
73
    }
74
75
    /**
76
     * @inheritdoc
77
     */
78
    public function check()
79
    {
80
        return (!extension_loaded('memcached') && !extension_loaded('memcache')) ?: true;
81
    }
82
83
    /**
84
     * Destructor
85
     *
86
     * @access public
87
     * @result void
88
     */
89
    public function __destruct()
90
    {
91
        if ($this->driver) {
92
            $this->driver->close();
0 ignored issues
show
Bug introduced by
The method close does only exist in Memcache, but not in Memcached.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
93
        }
94
    }
95
96
    /**
97
     * @inheritdoc
98
     */
99
    public function get($name)
100
    {
101
        $data = $this->driver->get($name);
102
103
        return is_array($data) ? $data[0] : $data;
104
    }
105
106
    /**
107
     * @inheritdoc
108
     */
109
    public function set($name, $value, $duration = 0)
110
    {
111
        switch (get_class($this->driver)) {
112
            case 'Memcached':
113
                return $this->driver->set($name, $value, $duration);
114
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
115
116
            case 'Memcache':
117
                return $this->driver->set($name, $value, 0, $duration);
118
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
119
120
            default:
121
                return false;
122
        }
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function delete($name)
129
    {
130
        return $this->driver->delete($name);
131
    }
132
133
    /**
134
     * @inheritdoc
135
     */
136
    public function clean()
137
    {
138
        return $this->driver->flush();
139
    }
140
141
    /**
142
     * @inheritdoc
143
     */
144
    public function info()
145
    {
146
        return $this->driver->getStats();
147
    }
148
149
    /**
150
     * @inheritdoc
151
     */
152
    public function getMeta($id)
153
    {
154
        $stored = $this->driver->get($id);
155
        if (count($stored) !== 3) {
156
            return false;
157
        }
158
159
        list($data, $time, $ttl) = $stored;
160
161
        return ['expire' => $time + $ttl, 'mtime' => $time, 'data' => $data];
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167
    public function increment($name, $offset = 1)
168
    {
169
        return $this->driver->increment($name, $offset);
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175
    public function decrement($name, $offset = 1)
176
    {
177
        return $this->driver->decrement($name, $offset);
178
    }
179
}
180