仿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 相关文章推荐
FCKeditor添加自定义按钮
Mar 27 PHP
一个简单php扩展介绍与开发教程
Aug 19 PHP
php开发留言板的CRUD(增,删,改,查)操作
Apr 19 PHP
phpmyadmin config.inc.php配置示例
Aug 27 PHP
php递归方法实现无限分类实例代码
Feb 28 PHP
php实现utf-8转unicode函数分享
Jan 06 PHP
PHP date函数常用时间处理方法
May 11 PHP
PHP结合jQuery实现找回密码
Jul 22 PHP
CodeIgniter 完美解决URL含有中文字符串
May 13 PHP
Laravel5.1框架路由分组用法实例分析
Jan 04 PHP
PHP实现倒计时功能
Nov 16 PHP
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
Apr 16 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
印尼林东PWN黄金曼特宁咖啡豆:怎么冲世界上最醇厚的咖啡冲煮教程
2021/03/03 冲泡冲煮
用PHP和ACCESS写聊天室(四)
2006/10/09 PHP
Thinkphp 空操作、空控制器、命名空间(详解)
2017/05/05 PHP
一种JavaScript的设计模式
2006/11/22 Javascript
JavaScript去掉空格的方法集合
2010/12/28 Javascript
jQuery拖拽 &amp; 弹出层 介绍与示例
2013/12/27 Javascript
jquery分析文本里url或邮件地址为真实链接的方法
2015/06/20 Javascript
基于jQuery实现拖拽图标到回收站并删除功能
2015/11/25 Javascript
一款简单的jQuery图片标注效果附源码下载
2016/03/22 Javascript
Web性能优化系列 10个提升JavaScript性能的技巧
2016/09/27 Javascript
node.js入门学习之url模块
2017/02/25 Javascript
JavaScript闭包的简单应用
2017/09/01 Javascript
javaScript产生随机数的用法小结
2018/04/21 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
js模拟F11页面全屏显示
2019/09/17 Javascript
js基础之事件捕获与冒泡原理
2019/10/09 Javascript
element跨分页操作选择详解
2020/06/29 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
[01:06:39]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第三局
2016/03/02 DOTA
python遍历文件夹并删除特定格式文件的示例
2014/03/05 Python
高性能web服务器框架Tornado简单实现restful接口及开发实例
2014/07/16 Python
python3操作微信itchat实现发送图片
2018/02/24 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
Python计算公交发车时间的完整代码
2020/02/12 Python
Python Selenium 设置元素等待的三种方式
2020/03/18 Python
python怎么判断素数
2020/07/01 Python
Idea安装python显示无SDK问题解决方案
2020/08/12 Python
英国第一豪华护肤品牌:Elemis
2017/10/12 全球购物
英国领先的亚洲旅游专家:Wendy Wu Tours
2018/01/21 全球购物
英国儿童设计师服装和玩具购物网站:Zac & Lulu
2020/10/19 全球购物
SQL里面IN比较快还是EXISTS比较快
2012/07/19 面试题
应聘医学检验人员自荐信
2013/09/27 职场文书
幼儿园大班毕业教师寄语
2014/04/03 职场文书
学生手册评语
2014/05/05 职场文书
Java中使用Filter过滤器的方法
2021/06/28 Java/Android
Python实现查询剪贴板自动匹配信息的思路详解
2021/07/09 Python