Zend Framework 2 - SignalSlotの利用メモ

Zend Framwork2で使われそうなSignalSlotの利用メモ
(元々はPhly_PubSubとしてマシューが開発を進めてたもの)。
もうZend\Sessionでは使われてますけど。


利用したZF2のソースは
http://github.com/zendframework/zf2からpullしたものです。
(今InvalidArgumentExceptionのときrequireがないとかでるけど多分気のせい。きっと)


その1 単純なロガーなどのオンオフに利用できそうなあれ

emitの第一引数には"ポイント名"となる信号キー文字列を設定します

<?php
set_include_path(__DIR__.'/library/');
require_once 'Zend/Loader/Autoloader.php';
Zend\Loader\Autoloader::getInstance();

use Zend\SignalSlot\GlobalSignals;

class TestClass
{  
    public function request()
    {
        GlobalSignals::emit('before', 'http://test');
        echo 'request!!', PHP_EOL;
        GlobalSignals::emit('after', 'http://test', 'world');
    }
}

function setUp()
{  
    global $argv;
    if (isset($argv[1]) && $argv[1] == 'dev') {
        //logger
        GlobalSignals::connect('before', function() {echo 'hello', PHP_EOL;});
        GlobalSignals::connect('after', function($url, $response) {echo $url, '--', $response,PHP_EOL;});
    }
}

// your action
setUp();
$test = new TestClass;
$test->request();


実行

$ php sample1.php
request!!
$ php sample1.php dev
hello
request!!
http://test--world


その2 同じ信号キー文字列に登録したものでもdetachが可能

<?php
function setUp()
{       
    global $argv;
    if (isset($argv[1]) && strtolower($argv[1]) == 'dev') {
        //logger
        $before1 = GlobalSignals::connect('before', function() {echo 'hello', PHP_EOL;});
        $before2 = GlobalSignals::connect('before', function($url) {echo $url, PHP_EOL;});
    
        if ($argv[1] === 'DEV') {
            GlobalSignals::detach($before1);
        }
    }
}


実行

$ php sample2.php dev
hello
http://test
request!!
$ php sample2.php DEV
http://test
request!!


その3 emitUntilを利用した場合、特定の条件にマッチしたとき(そしてtrueを返す)ときまで順にコネクトの内容を実行可能
実行順序はFIFO

<?php
class TestClass2
{  
    public function request2($uri = null)
    {
        $uri = 'http://test';
        GlobalSignals::emitUntil(function($value) {var_dump($value); return (boolean)$value;}, 'before', $uri);
        echo 'request!!', PHP_EOL;
    }
}   
    
function setUp()
{   
    $before1 = GlobalSignals::connect('before', function($url) {return ($url == 'http://te') ? true : null;});
    $before1 = GlobalSignals::connect('before', function($url) {return ($url == 'http://tes') ? true : 0;});
    $before1 = GlobalSignals::connect('before', function($url) {return ($url == 'http://test') ? true : false;});
    $before1 = GlobalSignals::connect('before', function($url) {return ($url == 'http://test') ? true: false;});
    $before1 = GlobalSignals::connect('before', function($url) {return ($url == 'http://tests_') ? true: false;});
}

// your action
setUp();
$test = new TestClass2;
$test->request2();


実行

$  php sample3.php
NULL
int(0)
bool(true)
request!!