Completed
Push — 1.x ( a98302...e42f79 )
by Alexander
07:32
created

CachingAspect::aroundCacheable()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 22
rs 8.9197
cc 4
eloc 12
nc 6
nop 1
1
<?php
2
/*
3
 * Go! AOP framework
4
 *
5
 * @copyright Copyright 2014, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Demo\Aspect;
12
13
use Go\Aop\Aspect;
14
use Go\Aop\Intercept\MethodInvocation;
15
use Go\Lang\Annotation\Around;
16
17
/**
18
 * Caching aspect
19
 */
20
class CachingAspect implements Aspect
21
{
22
    /**
23
     * This advice intercepts an execution of cacheable methods
24
     *
25
     * Logic is pretty simple: we look for the value in the cache and if it's not present here
26
     * then invoke original method and store it's result in the cache.
27
     *
28
     * Real-life examples will use APC or Memcache to store value in the cache
29
     *
30
     * @param MethodInvocation $invocation Invocation
31
     *
32
     * @Around("@execution(Demo\Annotation\Cacheable)")
33
     */
34
    public function aroundCacheable(MethodInvocation $invocation)
0 ignored issues
show
Coding Style introduced by
aroundCacheable uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
35
    {
36
        static $memoryCache = [];
37
38
        $time  = microtime(true);
39
40
        $obj   = $invocation->getThis();
41
        $class = is_object($obj) ? get_class($obj) : $obj;
42
        $key   = $class . ':' . $invocation->getMethod()->name;
43
        if (!isset($memoryCache[$key])) {
44
            // We can use ttl value from annotation, but Doctrine annotations doesn't work under GAE
45
            if (!isset($_SERVER['APPENGINE_RUNTIME'])) {
46
                echo "Ttl is: ", $invocation->getMethod()->getAnnotation('Demo\Annotation\Cacheable')->time, PHP_EOL;
47
            }
48
49
            $memoryCache[$key] = $invocation->proceed();
50
        }
51
52
        echo "Take ", sprintf("%0.3f", (microtime(true) - $time) * 1e3), "ms to call method $key", PHP_EOL;
53
54
        return $memoryCache[$key];
55
    }
56
}
57