基于PHP实现的事件机制实例分析

yipeiwu_com6年前PHP代码库

本文实例讲述了基于PHP实现的事件机制。分享给大家供大家参考。具体分析如下:

内置了事件机制的语言不多,php也没有提供这样的功能。事件(Event)说简单了就是一个Observer模式,实现起来很容易。但是有所不同的是,事件的监听者谁都可以加,但是只能由直接包含它的对象触发。这就有一点点难度了。php有一个debug_backtrace函数,可以得到当前的调用栈,由此可以找到判断调用事件触发函数的对象是不是直接包含它的对象的办法。

<?php
/**
* 事件
*
* @author xiezhenye <xiezhenye@gmail.com>
* @since 2007-7-20
*/
class Event {
  private $callbacks = array();
  private $holder;
  function __construct() {
    $bt = debug_backtrace();
    if (count($bt) < 2) {
      $this->holder = null;
      return;
    }
    $this->holder = &$bt[1]['object'];
  }
  function attach() {
    $args = func_get_args();
    switch (count($args)) {
      case 1:
        if (is_callable($args[0])) {
          $this->callbacks[]= $args[0];
          return;
        }
        break;
      case 2:
        if (is_object($args[0]) && is_string($args[1])) {
          $this->callbacks[]= array(&$args[0], $args[1]);
        }
        return;
      default:
        return;
    }
  }
  function notify() {
    $bt = debug_backtrace();
    if ($this->holder && 
        ((count($bt) >= 2 && $bt[count($bt) - 1]['object'] !== $this->holder)
        || (count($bt) < 2))) {
      throw(new Exception('Notify can only be called in holder'));
    }
    foreach ($this->callbacks as $callback) {
      $args = func_get_args();
      call_user_func_array($callback, $args);
    }
  }
}

希望本文所述对大家的php程序设计有所帮助。

相关文章

PHP获取表单数据与HTML嵌入PHP脚本的实现

 php接受通过HTML表单提交的信息时,会将提交的数据保存在全局数组中,我们可以调用系统特定的自动全局变量数组来获取这些值。 常用的自动全局变量如下所示: 1、GET方式...

学习php设计模式 php实现访问者模式(Visitor)

学习php设计模式 php实现访问者模式(Visitor)

访问者模式表示一个作用于某对象结构中各元素的操作。它可以在不修改各元素类的前提下定义作用于这些元素的新操作,即动态的增加具体访问者角色。 访问者模式利用了双重分派。先将访问者传入元素对象...

PHP+redis实现的购物车单例类示例

本文实例讲述了PHP+redis实现的购物车单例类。分享给大家供大家参考,具体如下: <?php /** * 购物车单例类 * * @author YING *...

PHP批量上传图片的具体实现方法介绍.

大家可以通过下面这一段代码,来具体了解PHP批量上传图片的具体方式。我们在学习PHP的时候,肯定是要从实际操作中慢慢积累经验,以巩固我们所学到的知识,逐渐的加强我们的编程水平。 R...

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式

思维导图 点击下图,查看大图。  介绍    条件逻辑有可能十分复杂,因此本章提供一些重构的手法,专门用来简化它们。   全文简述(你可直接跳...