Ray.Aopã¯PHPã§ã©ã®ããã«AOPãå®ç¾ãã¦ããã®ãï¼
Ray.Aopã使ãã¨ãPHPã§ãAOPï¼ã¢ã¹ãã¯ãæåããã°ã©ãã³ã°ï¼ã使ãã¾ãã
PHPã®è¨èªä»æ§ã«ã¯AOPæ©è½ã¯ããã¾ãããRay.Aopã§ã¯ã©ã®ããã«AOPãå®ç¾ãã¦ããã®ã§ãããï¼
AOPã¨ã¯ï¼
ä¾ãã°ãRay.Aopã使ãã¨ã以ä¸ã®ããã«ã¢ããã¼ã·ã§ã³ãæå®ãããã¨ã§ããã®ã¡ã½ãããã¤ã³ã¿ã¼ã»ããããã¡ã½ããå®è¡ã®åå¾ã«å¦çã追å ãããã¨ãã§ãã¾ãã
src/HelloService.php
<?php
class HelloService
{
/**
* @Benchmark
*/
public function say()
{
return 'Hello World!';
}
}
ä¾ãã°ã以ä¸ã®ãããªã¤ã³ã¿ã¼ã»ãã¿ã¼ãä½æããã¤ã³ãããã°ãã¡ã½ããå®è¡ã®æéãè¨æ¸¬ãã¦è¡¨ç¤ºã§ãã¾ãã
src/Benchmarker.php
<?php
use Ray\Aop\MethodInterceptor;
use Ray\Aop\MethodInvocation;
class Benchmarker implements MethodInterceptor
{
public function invoke(MethodInvocation $invocation)
{
$start = microtime(true);
$result = $invocation->proceed(); // å
ã®ã¡ã½ããã®å®è¡
$time = (microtime(true) - $start) * 1000;
$msg = sprintf("\n%s: %f ms", $invocation->getMethod()->getName(), $time);
return $result . $msg;
}
}
ã¤ã¾ãã以ä¸ã®ãããªã³ã¼ããå®è¡ããã¨ã
/* @var $hello HelloService */
echo $hello->say() . "\n";
é常ã¯ã以ä¸ã«ãªãã¾ãã
Hello World!
ããããRay.Aopã使ãã¨ã以ä¸ã®ããã«ãªãã¾ãã
Hello World!
say: 0.064135 ms
å ã®ã¡ã½ããã®å®è¡çµæã®å¾ã«ããã³ããã¼ã¯çµæã追å ããã¦ãã¾ãã
HelloService::say()
ã¯ãHello World!ããè¿ãã ããªã®ã«ä¸æè°ã§ããã
以ä¸ã®@Benchmark
ã¢ããã¼ã·ã§ã³ãHelloService
ã¯ã©ã¹ããåé¤ããã°ããã³ããã¼ã¯ã¯è¡¨ç¤ºãããªããªãã¾ãã
/**
* @Benchmark
*/
Ray.Aopã®ä½¿ãæ¹
å®éã«ã³ã¼ããåä½ãããã«ã¯ãã¢ããã¼ã·ã§ã³ã表ãBenchmark
ã¯ã©ã¹ãå¿
è¦ã«ãªãã¾ãã
src/Benchmark.php
<?php
/**
* @Annotation
* @Target("METHOD")
*/
final class Benchmark
{
}
composer.json
ã¯ä»¥ä¸ã«ãªãã¾ãã
composer.json
{
"require": {
"ray/aop": "~2.0"
},
"autoload": {
"psr-4": {
"": "src/"
}
}
}
ããã¦ãã¯ã©ã¤ã¢ã³ãã³ã¼ãã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
hello.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Ray\Aop\Pointcut;
use Ray\Aop\Matcher;
use Ray\Aop\Bind;
use Ray\Aop\Compiler;
$pointcut = new Pointcut(
(new Matcher)->any(),
(new Matcher)->annotatedWith(Benchmark::class),
[new Benchmarker()]
);
$bind = (new Bind)->bind(HelloService::class, [$pointcut]);
$tmpDir = __DIR__ . '/tmp';
$compiler = (new Compiler($tmpDir));
$hello = $compiler->newInstance(HelloService::class, [], $bind);
/* @var $hello HelloService */
echo $hello->say() . "\n";
ã¾ãããã¤ã³ãã«ãããä½æããããã¹ã¦ã®ã¯ã©ã¹ãã®ã@Benchmark
ã¢ããã¼ã·ã§ã³ã®ããã¡ã½ãããã«ãBenchmarker
ã¯ã©ã¹ããæå®ãã¾ãã
$pointcut = new Pointcut(
(new Matcher)->any(),
(new Matcher)->annotatedWith(Benchmark::class),
[new Benchmarker()]
);
次ã«ãHelloService
ã¯ã©ã¹ã«ãã®ãã¤ã³ãã«ããããã¤ã³ããã¾ãã
$bind = (new Bind)->bind(HelloService::class, [$pointcut]);
æå¾ã«ã³ã³ãã¤ã©ãä½æããHelloService
ã¯ã©ã¹ãã¤ã³ã¹ã¿ã³ã¹åãã¾ãã
$tmpDir = __DIR__ . '/tmp';
$compiler = (new Compiler($tmpDir));
$hello = $compiler->newInstance(HelloService::class, [], $bind);
ã³ã³ãã¤ã©ã«ã¯ä¸æãã£ã¬ã¯ããªãå¿ è¦ãªã®ã§ç¨æãã¦ããå¿ è¦ãããã¾ãã
AOPã®ä»çµã¿
ã³ã³ãã¤ã©ããã¤ã³ã¹ã¿ã³ã¹ãä½æããã¨ããã«ãAOPã®ä»çµã¿ãããããã§ããã
ä¸åº¦ã³ã¼ããå®è¡ããã¨ãããã¾ãããä¸æãã£ã¬ã¯ããªã«ä»¥ä¸ã®ãããªã¯ã©ã¹ãã¡ã¤ã«ãä½æããã¾ãã
tmp/HelloService_IzSUgmc.php
<?php
class HelloService_IzSUgmc extends HelloService implements Ray\Aop\WeavedInterface
{
private $isIntercepting = true;
public $bind;
/**
* @Benchmark
*/
function say()
{
if (isset($this->bindings[__FUNCTION__]) === false) {
return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
}
if ($this->isIntercepting === false) {
$this->isIntercepting = true;
return call_user_func_array('parent::' . __FUNCTION__, func_get_args());
}
$this->isIntercepting = false;
$invocationResult = (new \Ray\Aop\ReflectiveMethodInvocation($this, new \ReflectionMethod($this, __FUNCTION__), new \Ray\Aop\Arguments(func_get_args()), $this->bindings[__FUNCTION__]))->proceed();
$this->isIntercepting = true;
return $invocationResult;
}
}
ãããAOPã®ç§å¯ã§ãã
$hello
ããã³ããã¦ã¿ãã¨ã以ä¸ã®ããã«ãªã£ã¦ãã¾ãã
class HelloService_IzSUgmc#128 (3) {
private $isIntercepting =>
bool(true)
public $bind =>
NULL
public $bindings =>
array(1) {
'say' =>
array(1) {
[0] =>
class Benchmarker#3 (0) {
...
}
}
}
}
ã¤ã¾ããRay.Aopã§ã¯ã³ã³ãã¤ã©ãã¤ã³ã¹ã¿ã³ã¹ã®çææã«ãã½ã¼ã¹ãå¤æ´ããã¯ã©ã¹ãåçã«ä½æãããã®å¤æ´ããã¯ã©ã¹ãã¤ã³ã¹ã¿ã³ã¹åãè¿ãã¾ãã
ããã§ãã¡ã½ããã®ã¤ã³ã¿ã¼ã»ãããå¯è½ã«ãªãã¾ãã
ã¾ããããããREADMEã«ãã以ä¸ã®å¶éã®çç±ã§ãã
ã¯ã©ã¹ã¨ã¡ã½ããã¯ä»¥ä¸ã®ãã®ã§ããå¿ è¦ãããã¾ãã
- ã¯ã©ã¹ã¯ final ã§ã¯ãªã
- ã¡ã½ãã㯠public
- ã¡ã½ãã㯠final ã§ã¯ãªã
æ¤è¨¼ãããã¼ã¸ã§ã³
ãã®è¨äºã¯ä»¥ä¸ã®ãã¼ã¸ã§ã³ã§æ¤è¨¼ãã¾ããã
$ composer show -i
doctrine/annotations v1.2.7 Docblock Annotations Parser
doctrine/lexer v1.0.1 Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
nikic/php-parser v1.4.1 A PHP parser written in PHP
ray/aop 2.1.1 An aspect oriented framework
è¦ã¦ãããããã«ãRay.Aopã§ã¯ã¢ããã¼ã·ã§ã³ã®è§£æã«ãdoctrine/annotationsããPHPã³ã¼ãã®è§£æã«ãnikic/php-parserããå©ç¨ãã¦ãã¾ãã
åè
Date: 2015/10/27