twm 发表于 2013-3-8 14:45:52

为 Codeigniter 添加事件订阅/监听机制

本帖最后由 twm 于 2013-3-8 15:19 编辑

有了 Composer 为 Codeigniter 添加事件订阅/监听机制很简单,这里我们也使用了 Symfony2 框架中的 event-dispatcher 包,仅需要以下几个简单的步骤:(如果你还不了解监听者模式,你应该先Google一下)

1.执行如下命令安装 event-dispatcher Bundle

php composer.phar require symfony/event-dispatcher:dev-master


2.创建 配置文件

在 application/config 目录创建一个名为 listeners.php 的文件,这个文件用于注册事件的订阅者。

return array(
);
3.利用 Codeigniter 的 hooks 机制,来完成注册事件的订阅者。

a) 找到 application/config/config.php 文件,将 enable_hooks 值设置为 true
b) 修改 application/config/hooks.php 文件,加入以下内容:

<?phpif (!defined('BASEPATH')) exit('No direct script access allowed');

// ...
/**
* 在你的控制器实例化之后, 任何方法调用之前调用.
*/
$hook['post_controller_constructor'][] = array(
    'class'    => 'EventDispatcher',
    'function' => 'postControllerConstructor',
    'filename' => 'EventDispatcher.php',
    'filepath' => 'hooks',
);
4.创建 EventDispatcher.php 文件

第 3 步时我们定义了该文件的位置为 hooks 目录,所以我们在 applicaiton/hooks 目录创建该文件:

<?php
// ...
class EventDispatcher
{
    /**
   * 注册监听者对象
   *
   * 在控制器实例化之后, 任何方法调用之前调用.
   */
    public function postControllerConstructor()
    {
      $ci = & get_instance();

      if (!file_exists($filename = APPPATH . 'config/listeners.php')) {
            throw new RuntimeException("$filename not found");
      }

      $subscribers = include ($filename);
      foreach ($subscribers as $subscriber) {
            $ci->dispatcher->addSubscriber($subscriber);
      }
    }
}
5.最后一步

在 application/core 目录添加/修改 MY_Controller.php 文件(该文件会被自动加载),我们需要初始化 Symfony2 的 EventDispatcher 对象:

<?php
// ...
class MY_Controller extends CI_Controller
{
    /**
   * @var EventDispatcher
   */
    public $dispatcher;

    /**
   * Constructor
   */
    public function __construct()
    {
      parent::__construct();

      $this->dispatcher = new EventDispatcher();
    }
到这里你已经完成了所有的安装工作,我们需要测试一下:

假设你的用户注册后需要发送激活邮件并且需要写入系统日志又或者是发条短信给老板说有新用户注册了,我们创建一个控制器来执行这个测试:

a) 创建一个用户注册控制器

# controllers/register.php
<?php
class Register extends AppController
{
    public function index()
    {
      // ...
      // save user to db
      // ...
      $user = array();

      // ...
      // send register email ....
      $this->dispatcher->dispatch('user_registered', new \Bundles\Event\UserEvent($user));
    }
}
上面的 index 方法的最后一句导致 user_registered 事件被调用,并且一个 UserEvent 对象被传递。
dispatch方法的第一个参数为事件名称,这个名称你可以自己定义,第2个参数为事件本身,上面我们传递了一个 UserEvent 对象供我们的订阅者/监听者使用。

b) 添加订阅者

在 config/listeners.php 文件中添加一个订阅者

return array(
    new \Bundles\EventListener\UserEventListener()
);
c) 创建这个 UserEventListener 对象

# bundles\Bundles\EventListener\UserEventListener.php
<?php
namespace Bundles\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Bundles\Event\UserEvent;

class UserEventListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
      return array(
            'user_registered' => 'onRegistered'
      );
    }

    public function onRegistered(UserEvent $event)
    {
      $user = $event->getUser();

      // send email or ....
    }
}
# bundles\Bundles\Event\UserEvent.php
<?php
namespace Bundles\Event;

use Symfony\Component\EventDispatcher\Event;

class UserEvent extends Event {
    protected $user;

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

    public function getUser()
    {
      return $this->user;
    }
}
当你访问 http://path/register 时,或者用户注册成功后(这取决于你),一个 user_registered 事件将被调用,所有订阅了该事件的对象将会被调用,你可以在订阅者中做你想要的任何事。
页: [1]
查看完整版本: 为 Codeigniter 添加事件订阅/监听机制