仿AS3实现PHP 事件机制实现代码


Posted in PHP onJanuary 27, 2011
<?php 
/** 
* 事件异常 
* 
* @author lonely 
* @create 2010-10-21 
* @version 0.1 
* @lastupdate lonely 
* @package Event 
*/ 
class Exception_Event extends Exception {} 
/** 
* 事件对象 
* 
* @author lonely 
* @create 2010-10-21 
* @version 0.1 
* @lastupdate lonely 
* @package Event 
*/ 
class Event extends stdClass{ 
public $target=null; 
public $type=null; 
/** 
* 创建事件 
* @param string $type 
*/ 
public function __construct($type){ 
$this->type=trim($type); 
} 
/** 
* 得到事件字符串 
*/ 
public function __toString(){ 
return $this->type; 
} 
} 
/** 
* 事件派发 
* 
* @author lonely 
* @create 2010-10-21 
* @version 0.1 
* @lastupdate lonely 
* @package Event 
*/ 
class EventDispatcher{ 
private $_callback_method; 
/** 
* 添加事件 
* @param Event $event 
* @param string $method 
* @param string||object $class 
* @return boolean true 
*/ 
public function attach(Event $event,$method,$class=null){ 
$event->target=$this; 
$eventstr=$this->_create_event_str($event); 
if($this->has($event,$method,$class)) 
return true; 
if($class!=null){ 
$this->_check_method($class,$method); 
$this->_callback_method[$eventstr][]=$this->_create_listener_method($eventstr,$class,$method); 
}else{ 
$this->_check_function($method); 
$this->_callback_method[$eventstr][]=$this->_create_listener_fn($eventstr,$method); 
} 
return true; 
} 
/** 
* 派发事件 
* @param Event $event 
* @param string $method 
* @param string||object $class 
* @return void 
*/ 
public function dispatch(Event $event){ 
$eventstr=$this->_create_event_str($event); 
if($this->_check_callback($eventstr)){ 
foreach ($this->_callback_method[$eventstr] as $v){ 
if($v['object']){ 
if(is_object($v['class'])){ 
$v['class']->$v['method']($event); 
}else{ 
call_user_func(array($v['class'], $v['method']),$event); 
} 
}else{ 
$v['function']($event); 
} 
} 
} 
} 
/** 
* 删除事件 
* @param Event $event 
* @param string $method 
* @param string $class 
* @return boolean true 
*/ 
public function detact(Event $event,$method,$class=null){ 
$eventstr=$this->_create_event_str($event); 
if(!$this->_check_callback($eventstr)) 
return true; 
if(!$this->has($event,$method,$class)) 
return true; 
if($class!=null){ 
$this->_check_method($class,$method); 
foreach ($this->_callback_method[$eventstr] as $k=>$v) { 
if(($v==$this->_create_listener_method($eventstr,$class,$method))){ 
unset($this->_callback_method[$eventstr][$k]); 
return true; 
} 
} 
return true; 
}else{ 
$this->_check_function($method); 
foreach ($this->_callback_method[$eventstr] as $k=>$v) { 
if(($v==$this->_create_listener_fn($eventstr,$method))){ 
unset($this->_callback_method[$eventstr][$k]); 
return true; 
} 
} 
return true; 
} 
} 
/** 
* 检测事件是否监听 
* @param Event $event 
* @param string $method 
* @param string $class 
* @return boolean 
*/ 
public function has(Event $event,$method,$class=null){ 
$eventstr=$this->_create_event_str($event); 
if(($class!=null)){ 
$this->_check_method($class,$method); 
if($this->_check_callback($eventstr)){ 
foreach($this->_callback_method[$eventstr] as $v){ 
if(is_object($v['class'])){ 
$v_class=get_class($v['class']); 
}else{ 
$v_class=$v['class']; 
} 
if(is_object($class)){ 
$s_class=get_class($class); 
}else{ 
$s_class=$class; 
} 
$temp_v=array( 
"class"=>$v_class, 
"method"=>$method, 
); 
$temp_s=array( 
"class"=>$s_class, 
"method"=>$method, 
); 
if($temp_v==$temp_s){ 
return true; 
} 
} 
} 
}else{ 
$this->_check_function($method); 
if($this->_check_callback($eventstr)){ 
foreach($this->_callback_method[$eventstr] as $v){ 
if($method==$v['function']){ 
return true; 
} 
} 
} 
} 
return false; 
} 
/** 
* 检测指定类是否存在指定方法 
* @param string $class 
* @param string $method 
* @exception Exception_Event 
* @return void 
*/ 
private function _check_method($class,$method){ 
if(!method_exists($class,$method)){ 
throw new Exception_Event(get_class($class)." not exist ".$method." method",1); 
} 
} 
/** 
* 检测指定函数是否存在 
* @param string $function 
* @return void 
*/ 
private function _check_function($function){ 
if(!function_exists($function)){ 
throw new Exception_Event($function." function not exist ",2); 
} 
} 
/** 
* 检测指定事件是否存在监听函数 
* @param string $eventstr 
* @return boolean 
*/ 
private function _check_callback($eventstr){ 
if(isset($this->_callback_method[$eventstr]) 
&&is_array($this->_callback_method[$eventstr]) 
){ 
return true; 
} 
return false; 
} 
/** 
* 创建监听函数数组 
* @param string $eventstr 
* @param string $function 
* @return array 
*/ 
private function _create_listener_fn($eventstr,$function){ 
return array( 
"object"=>false, 
"function"=>$function, 
); 
} 
/** 
* 创建监听类数组 
* @param string $eventstr 
* @param string $class 
* @param string $method 
* @return array 
*/ 
private function _create_listener_method($eventstr,$class,$method){ 
return array( 
"object"=>true, 
"class"=>$class, 
"method"=>$method, 
); 
} 
/** 
* 创建事件字符串 
* @param Event $event 
* @return string 
*/ 
private function _create_event_str(Event $event){ 
$classstr=strtolower(get_class($event)); 
$eventstr=(string)$event; 
return $classstr.$eventstr; 
} 
} 
class test extends EventDispatcher{ } 
function t($e){ 
print_r($e->a); 
} 
$v=new test(); 
$e=new Event("test"); 
$v->attach($e,"t"); 
$v->detact($e,"t"); 
echo $v->has($e,"t"); 
$e->a="dd"; 
$v->dispatch($e);
PHP 相关文章推荐
第十五节--Zend引擎的发展
Nov 16 PHP
php的一个登录的类 [推荐]
Mar 16 PHP
PHP mb_convert_encoding文字编码的转换函数介绍
Nov 10 PHP
php打造属于自己的MVC框架
Mar 07 PHP
PHP关联链接常用代码
Nov 05 PHP
php禁止浏览器使用缓存页面的方法
Nov 07 PHP
PHP中的Session对象如何使用
Sep 25 PHP
PHP 类与构造函数解析
Feb 06 PHP
phpstudy的php版本自由修改的方法
Oct 18 PHP
PHP Trait代码复用类与多继承实现方法详解
Jun 17 PHP
php web环境和命令行环境下查找php.ini的位置
Jul 17 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
Mar 23 PHP
PHP 命名空间实例说明
Jan 27 #PHP
PHP中利用substr_replace将指定两位置之间的字符替换为*号
Jan 27 #PHP
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
Jan 27 #PHP
PHP中通过加号合并数组的一个简单方法分享
Jan 27 #PHP
PHP中删除变量时unset()和null的区别分析
Jan 27 #PHP
PHP企业级应用之常见缓存技术篇
Jan 27 #PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
Jan 18 #PHP
You might like
PHP时间戳使用实例代码
2008/06/07 PHP
phpstorm 配置xdebug的示例代码
2019/03/31 PHP
OfflineSave离线保存代码再次发布使用说明
2007/05/23 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
当json键为数字时的取值方法解析
2013/11/15 Javascript
jQuery 滑动方法slideDown向下滑动元素
2014/01/16 Javascript
浅谈Javascript 数组与字典
2015/01/29 Javascript
js操作cookie保存浏览记录的方法
2015/12/25 Javascript
JavaScript中通过提示框跳转页面的方法
2016/02/14 Javascript
js计算时间差代码【包括计算,天,时,分,秒】
2016/04/26 Javascript
微信小程序  modal弹框组件详解
2016/10/27 Javascript
Canvas实现动态的雪花效果
2017/02/13 Javascript
JS数组搜索之折半搜索实现方法分析
2017/03/27 Javascript
浅谈Node.js CVE-2017-14849 漏洞分析(详细步骤)
2017/11/10 Javascript
JS实现简单的文字无缝上下滚动功能示例
2019/06/22 Javascript
微信小程序使用车牌号输入法的示例代码
2019/08/20 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
javascript前端实现多视频上传
2020/12/13 Javascript
vue调用微信JSDK 扫一扫,相册等需要注意的事项
2021/01/03 Vue.js
浅谈Python对内存的使用(深浅拷贝)
2018/01/17 Python
python3实现钉钉消息推送的方法示例
2019/03/14 Python
python实现udp聊天窗口
2020/03/31 Python
jupyternotebook 撤销删除的操作方式
2020/04/17 Python
python求解汉诺塔游戏
2020/07/09 Python
学python爬虫能做什么
2020/07/29 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
2021/02/02 Python
css3弹性盒模型(Flexbox)详细介绍
2014/10/08 HTML / CSS
FOREO斐珞尔官方旗舰店:LUNA露娜洁面仪
2018/03/11 全球购物
美国Max仓库:Max Warehouse
2020/05/31 全球购物
雾霾停课通知
2015/04/24 职场文书
Django debug为True时,css加载失败的解决方案
2021/04/24 Python
MongoDB数据库的安装步骤
2021/06/18 MongoDB
Python基于百度AI实现抓取表情包
2021/06/27 Python
MySQL系列之六 用户与授权
2021/07/02 MySQL
MongoDB连接数据库并创建数据等使用方法
2021/11/27 MongoDB
Netty分布式客户端接入流程初始化源码分析
2022/03/25 Java/Android