仿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 相关文章推荐
简体中文转换为繁体中文的PHP函数
Oct 09 PHP
默默简单的写了一个模板引擎
Jan 02 PHP
php中将图片gif,jpg或mysql longblob或blob字段值转换成16进制字符串
Aug 23 PHP
php自动给文章加关键词链接的函数代码
Nov 29 PHP
php代码中使用换行及(\n或\r\n和br)的应用
Feb 02 PHP
php基于GD库画五星红旗的方法
Feb 24 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
Jul 03 PHP
使用XHGui来测试PHP性能的教程
Jul 03 PHP
在Debian系统下配置LNMP的教程
Jul 09 PHP
Swoole-1.7.22 版本已发布,修复PHP7相关问题
Dec 31 PHP
PHP封装的PDO数据库操作类实例
Jun 21 PHP
Laravel使用原生sql语句并调用的方法
Oct 09 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 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
PHP 通过Socket收发十六进制数据的实现代码
2013/08/16 PHP
php限制上传文件类型并保存上传文件的方法
2015/03/13 PHP
php获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
PHP进制转换实例分析(2,8,16,36,64进制至10进制相互转换)
2017/02/04 PHP
PHP中关于php.ini参数优化详解
2020/02/28 PHP
千分位数字格式化(用逗号隔开 代码已做了修改 支持0-9位逗号隔开)的JS代码
2013/12/05 Javascript
登陆成功后自动计算秒数执行跳转
2014/01/23 Javascript
JS修改iframe页面背景颜色的方法
2015/04/01 Javascript
浅谈javascript原型链与继承
2015/07/13 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
JavaScript基础——使用Canvas绘图
2016/11/02 Javascript
Bootstrap选项卡动态切换效果
2016/11/28 Javascript
详解nodejs 文本操作模块-fs模块(三)
2016/12/22 NodeJs
JavaScript常见继承模式实例小结
2019/01/11 Javascript
Vue页面切换和a链接的本质区别详解
2019/11/12 Javascript
angular inputNumber指令输入框只能输入数字的实现
2019/12/03 Javascript
vue中jsonp插件的使用方法示例
2020/09/10 Javascript
JS中队列和双端队列实现及应用详解
2020/09/29 Javascript
解决Python的str强转int时遇到的问题
2018/04/09 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
2019/04/12 Python
给 TensorFlow 变量进行赋值的方式
2020/02/10 Python
Python实现ElGamal加密算法的示例代码
2020/06/19 Python
Python 保存加载mat格式文件的示例代码
2020/08/04 Python
Vans(范斯)新西兰官方网站:美国原创极限运动品牌
2020/09/19 全球购物
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
人力资源部经理助理岗位职责
2014/03/04 职场文书
《风娃娃》教学反思
2014/04/19 职场文书
霸气队列口号
2014/06/18 职场文书
邓小平理论心得体会
2014/09/09 职场文书
2015商场元旦促销活动策划方案
2014/12/09 职场文书
研究生简历自我评
2015/03/11 职场文书
2015年后备干部工作总结
2015/05/15 职场文书
Python极值整数的边界探讨分析
2021/09/15 Python
千万级用户系统SQL调优实战分享
2022/03/03 MySQL