Completed
Pull Request — master (#30)
by Alexander
01:22
created

ApcuCache::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
dl 0
loc 4
rs 10
c 1
b 0
f 0
eloc 2
nc 2
nop 2
ccs 0
cts 3
cp 0
crap 6
1
<?php
2
3
namespace Yiisoft\Cache;
4
5
use DateInterval;
6
use DateTime;
7
use Exception;
8
use Psr\SimpleCache\CacheInterface;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Yiisoft\Cache\CacheInterface. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
10
/**
11
 * ApcuCache provides APCu caching in terms of an application component.
12
 *
13
 * To use this application component, the [APCu PHP extension](http://www.php.net/apcu) must be loaded.
14
 * In order to enable APCu for CLI you should add "apc.enable_cli = 1" to your php.ini.
15
 *
16
 * See {@see \Psr\SimpleCache\CacheInterface} for common cache operations that ApcCache supports.
17
 */
18
class ApcuCache implements CacheInterface
19
{
20
    private const TTL_INFINITY = 0;
21
    private const TTL_EXPIRED = -1;
22
23
    public function get($key, $default = null)
24
    {
25
        $value = \apcu_fetch($key, $success);
26
        return $success ? $value : $default;
27
    }
28
29
    public function set($key, $value, $ttl = null)
30
    {
31
        $ttl = $this->normalizeTtl($ttl);
32
        if ($ttl < 0) {
33
            return $this->delete($key);
34
        }
35
        return \apcu_store($key, $value, $ttl);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_store($key, $value, $ttl) also could return the type array which is incompatible with the return type mandated by Psr\SimpleCache\CacheInterface::set() of boolean.
Loading history...
36
    }
37
38
    public function delete($key)
39
    {
40
        return \apcu_delete($key);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_delete($key) also could return the type string[] which is incompatible with the return type mandated by Psr\SimpleCache\CacheInterface::delete() of boolean.
Loading history...
41
    }
42
43
    public function clear()
44
    {
45
        return \apcu_clear_cache();
46
    }
47
48
    public function getMultiple($keys, $default = null)
49
    {
50
        $values = \apcu_fetch($this->iterableToArray($keys), $success) ?: [];
51
        return array_merge(array_fill_keys($this->iterableToArray($keys), $default), $values);
52
    }
53
54
    public function setMultiple($values, $ttl = null)
55
    {
56
        return \apcu_store($this->iterableToArray($values), null, $this->normalizeTtl($ttl)) === [];
57
    }
58
59
    public function deleteMultiple($keys)
60
    {
61
        return \apcu_delete($this->iterableToArray($keys)) === [];
62
    }
63
64
    public function has($key)
65
    {
66
        return \apcu_exists($key);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_exists($key) also could return the type string[] which is incompatible with the return type mandated by Psr\SimpleCache\CacheInterface::has() of boolean.
Loading history...
67
    }
68
69
    /**
70
     * Normalizes cache TTL handling `null` value and {@see DateInterval} objects.
71
     * @param int|DateInterval|null $ttl raw TTL.
72
     * @return int|null TTL value as UNIX timestamp or null meaning infinity
73
     */
74
    private function normalizeTtl($ttl): ?int
75
    {
76
        $normalizedTtl = $ttl;
77
        if ($ttl instanceof DateInterval) {
78
            try {
79
                $normalizedTtl = (new DateTime('@0'))->add($ttl)->getTimestamp();
80
            } catch (Exception $e) {
81
                $normalizedTtl = self::TTL_EXPIRED;
82
            }
83
        }
84
85
        return $normalizedTtl ?? static::TTL_INFINITY;
86
    }
87
88
    /**
89
     * Converts iterable to array
90
     * @param iterable $iterable
91
     * @return array
92
     */
93
    private function iterableToArray(iterable $iterable): array
94
    {
95
        return $iterable instanceof \Traversable ? iterator_to_array($iterable) : (array)$iterable;
96
    }
97
}
98