事件机制在一个可扩展的系统里面尤为重要。通常一个系统我们不想让用户对核心代码进行修改,如何不修改核心代码却能对核心部分进行操作呢。symfony中的event机制就很好的解决了这个问题。现在我一步一步的来定制一个事件监听
1. 首先定义了一个Events的枚举类用于管理所有的event,通过定义一个枚举类方便的进行所有事件的管理,避免遗忘定义的事件
<?php
namespace Wolehao\HomeBundle\Event;
final class Events{
const HOMEPAGE_VISIT = "home.homepage_visit";
}
2. 在HomepageBundle定义了一个event
<?php
namespace Wolehao\HomeBundle\Event;
// 这个是sf为你提供的一个基础类
use Symfony\Component\EventDispatcher\Event;
// 你的事件类
class HomepageVisit extends Event {
public $container;
public function __construct($container) {
$this->container = $container;
}
}
3.在FileBundle中定义了一个listener
<?php
namespace Wolehao\FileBundle\EventListener;
use Wolehao\HomeBundle\Event\HomepageVisit;
class FileListener
{
public function onHomepageVisit(HomepageVisit $event)
{
$event->container->get("logger")->info("我执行了");
// ...
}
}
4. 在service.xml中注册服务
<services>
<service id="file.listener" class="Wolehao\FileBundle\EventListener\FileListener">
<tag name="kernel.event_listener" event="home.homepage_visit" method="onHomepageVisit"/>
</service>
</services>
5.在HomepageBundle的controller中触发事件
<?php
namespace Wolehao\HomeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Wolehao\HomeBundle\Event\HomepageVisit;
use Wolehao\HomeBundle\Event\Events;
use Wolehao\FileBundle\Event\Listener;
class DefaultController extends Controller
{
/**
* @Route("/home/{name}")
* @Template()
*/
public function indexAction($name)
{
$event = new HomepageVisit($this->container);
// 在controller里取事件分发器
$dispatcher = $this->get('event_dispatcher');
$dispatcher->dispatch(Events::HOMEPAGE_VISIT, $event);
return array('name' => $name);
}
}
最后通过http://localhost/fm/web/app_dev.php/home/index访问,控制台成功的打印出"我执行了"的日志。
这里就是一个跨模块进行执行的一个例子,在Homepage的controller里面我们通过事先做一个事件的触发操作。然后在其他的模块里面写入监听者,最后通过注册服务把监听者加入到事件里面去。然后在我们自己的监听器类里面就可以做你自己想要做的事情了。