Completed
Push — master ( d64c7f...d0ede0 )
by Nicolas
11s
created

src/Gaufrette/Adapter/Apc.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Gaufrette\Adapter;
4
5
use Gaufrette\Adapter;
6
use Gaufrette\Util;
7
8
@trigger_error('The '.__NAMESPACE__.'\Apc adapter is deprecated since version 0.4 and will be removed in 1.0.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
9
10
/**
11
 * Apc adapter, a non-persistent adapter for when this sort of thing is appropriate.
12
 *
13
 * @author Alexander Deruwe <[email protected]>
14
 * @author Antoine Hérault <[email protected]>
15
 * @author Leszek Prabucki <[email protected]>
16
 *
17
 * @deprecated The Apc adapter is deprecated since version 0.4 and will be removed in 1.0.
18
 */
19
class Apc implements Adapter
20
{
21
    protected $prefix;
22
    protected $ttl;
23
24
    /**
25
     * @throws \RuntimeException
26
     *
27
     * @param string $prefix to avoid conflicts between filesystems
28
     * @param int    $ttl    time to live, default is 0
29
     */
30
    public function __construct($prefix, $ttl = 0)
31
    {
32
        if (!extension_loaded('apc')) {
33
            throw new \RuntimeException('Unable to use Gaufrette\Adapter\Apc as the APC extension is not available.');
34
        }
35
36
        $this->prefix = $prefix;
37
        $this->ttl = $ttl;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function read($key)
44
    {
45
        return apc_fetch($this->computePath($key));
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    public function write($key, $content, array $metadata = null)
52
    {
53
        $result = apc_store($this->computePath($key), $content, $this->ttl);
54
55
        if (!$result) {
56
            return false;
57
        }
58
59
        return Util\Size::fromContent($content);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function exists($key)
66
    {
67
        return apc_exists($this->computePath($key));
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function keys()
74
    {
75
        $cachedKeys = $this->getCachedKeysIterator();
76
77
        if (null === $cachedKeys) {
78
            return array();
79
        }
80
81
        $keys = array();
82
        foreach ($cachedKeys as $key => $value) {
83
            $pattern = sprintf('/^%s/', preg_quote($this->prefix, '/'));
84
            $keys[] = preg_replace($pattern, '', $key);
85
        }
86
        sort($keys);
87
88
        return $keys;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function mtime($key)
95
    {
96
        $cachedKeys = iterator_to_array($this->getCachedKeysIterator($key, APC_ITER_MTIME));
97
98
        return $cachedKeys[$this->computePath($key)]['mtime'];
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function delete($key)
105
    {
106
        return apc_delete($this->computePath($key));
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function rename($sourceKey, $targetKey)
113
    {
114
        // TODO: this probably allows for race conditions...
115
        $written = $this->write($targetKey, $this->read($sourceKey));
0 ignored issues
show
It seems like $this->read($sourceKey) targeting Gaufrette\Adapter\Apc::read() can also be of type boolean; however, Gaufrette\Adapter\Apc::write() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
116
        $deleted = $this->delete($sourceKey);
117
118
        return $written && $deleted;
0 ignored issues
show
Bug Best Practice introduced by
The expression $written of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function isDirectory($key)
125
    {
126
        return false;
127
    }
128
129
    /**
130
     * Computes the path for the given key.
131
     *
132
     * @param string $key
133
     *
134
     * @return string
135
     */
136
    public function computePath($key)
137
    {
138
        return $this->prefix.$key;
139
    }
140
141
    /**
142
     * @param string $key    - by default ''
143
     * @param int    $format - by default APC_ITER_NONE
144
     *
145
     * @return \APCIterator
146
     */
147
    protected function getCachedKeysIterator($key = '', $format = APC_ITER_NONE)
148
    {
149
        $pattern = sprintf('/^%s/', preg_quote($this->prefix.$key, '/'));
150
151
        return new \APCIterator('user', $pattern, $format);
152
    }
153
}
154