仿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 相关文章推荐
定制404错误页面,并发信给管理员的程序
Oct 09 PHP
实例(Smarty+FCKeditor新闻系统)
Jan 02 PHP
php 正则 过滤html 的超链接
Jun 02 PHP
Notice: Trying to get property of non-object problem(PHP)解决办法
Mar 11 PHP
php实现的百度搜索某地天气的小偷代码
Apr 23 PHP
php基于jquery的ajax技术传递json数据简单实例
Apr 15 PHP
joomla实现注册用户添加新字段的方法
May 05 PHP
ThinkPHP3.2.2实现持久登录(记住我)功能的方法
May 16 PHP
PHP页面间传递值和保持值的方法
Aug 24 PHP
PHP函数引用返回的实例详解
Sep 11 PHP
php识别翻转iphone拍摄的颠倒图片
May 17 PHP
thinkPHP事务操作简单案例分析
Oct 17 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自定义函数call_user_func和call_user_func_array详解
2011/07/14 PHP
php中call_user_func函数使用注意事项
2014/11/21 PHP
使用PHPStorm+XDebug搭建单步调试环境
2017/11/19 PHP
ThinkPHP3.2.3框架邮件发送功能图文实例详解
2019/04/23 PHP
js window.open弹出新的网页窗口
2014/01/16 Javascript
Extjs grid panel自带滚动条失效的解决方法
2014/09/11 Javascript
JavaScript中setMonth()方法的使用详解
2015/06/11 Javascript
Js遍历键值对形式对象或Map形式的方法
2016/08/08 Javascript
node.js学习之base64编码解码
2016/10/21 Javascript
js实现可输入可选择的select下拉框
2016/12/21 Javascript
VueJS组件之间通过props交互及验证的方式
2017/09/04 Javascript
详解vue-router 路由元信息
2017/09/13 Javascript
AngularJs 禁止模板缓存的方法
2017/11/28 Javascript
利用Javascript开发一个二维周视图日历
2017/12/14 Javascript
webpack 4.0.0-beta.0版本新特性介绍
2018/02/10 Javascript
AngularJS中的作用域实例分析
2018/05/16 Javascript
jQuery实现ajax回调函数带入参数的方法示例
2018/06/26 jQuery
vue实现可视化可拖放的自定义表单的示例代码
2019/03/20 Javascript
vue 进阶之实现父子组件间的传值
2019/04/26 Javascript
JS面向对象编程基础篇(一) 对象和构造函数实例详解
2020/03/03 Javascript
[03:28]2014DOTA2国际邀请赛 EG战队官方纪录片
2014/07/21 DOTA
[00:32]2018DOTA2亚洲邀请赛VGJ.T出场
2018/04/03 DOTA
[01:10]DOTA2 Supermajor:英雄,由我们见证
2018/05/14 DOTA
Python实现正则表达式匹配任意的邮箱方法
2018/12/20 Python
ERLANG和PYTHON互通实现过程详解
2019/07/05 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
python多进程使用函数封装实例
2020/05/02 Python
python中id函数运行方式
2020/07/03 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
下面代码从性能上考虑,有什么问题
2015/04/03 面试题
大学生期末自我鉴定
2014/02/01 职场文书
市场营销个人求职信范文
2014/02/02 职场文书
家长给学校的建议书
2014/05/15 职场文书
模特大赛策划方案
2014/05/28 职场文书
vue完美实现el-table列宽自适应
2021/05/08 Vue.js
浅谈MySQL函数
2021/10/05 MySQL