仿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 调试工具Debug Tools
Apr 30 PHP
php设计模式 Builder(建造者模式)
Jun 26 PHP
关于IIS php调用com组件的权限问题
Jan 11 PHP
配置php网页显示各种语法错误
Sep 23 PHP
PHP写的资源下载防盗链类分享
May 12 PHP
PHP合并静态文件详解
Nov 14 PHP
PHP使用数组依次替换字符串中匹配项
Jan 08 PHP
php base64 编码与解码实例代码
Mar 21 PHP
windows下的WAMP环境搭建图文教程(推荐)
Jul 27 PHP
PHP实现数据库的增删查改功能及完整代码
Apr 18 PHP
thinkPHP框架实现多表查询的方法
Jun 14 PHP
THINKPHP-Apache服务器中使用Alias虚拟目录URL重写 隐藏index.php
Mar 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中Session的概念
2006/10/09 PHP
PHP array 的加法操作代码
2010/07/24 PHP
五款常用mysql slow log分析工具的比较分析
2011/05/22 PHP
php在window iis的莫名问题的测试方法
2013/05/14 PHP
PHP下获取上个月、下个月、本月的日期(strtotime,date)
2014/02/02 PHP
PHP使用Redis实现防止大并发下二次写入的方法
2017/10/09 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
PHP XML Expat解析器知识点总结
2019/02/15 PHP
PHP中的输出echo、print、printf、sprintf、print_r和var_dump的示例代码
2020/12/01 PHP
firefox下frameset取不到值的解决方法
2010/09/06 Javascript
在标题栏显示新消息提示,很多公司项目中用到这个方法
2011/11/04 Javascript
js类式继承的具体实现方法
2013/12/31 Javascript
jquery通过ajax加载一段文本内容的方法
2015/01/15 Javascript
AngularJS基础 ng-mousemove 指令简单示例
2016/08/02 Javascript
jquery实现多次上传同一张图片
2017/01/09 Javascript
angularjs实现上拉加载和下拉刷新数据功能
2017/06/12 Javascript
实现jquery放大镜的两种方法
2018/02/22 jQuery
Node.js原生api搭建web服务器的方法步骤
2019/02/15 Javascript
layui加载数据显示loading加载完成loading消失的实例代码
2019/09/23 Javascript
jQuery实现穿梭框效果
2021/01/19 jQuery
[01:06:42]VP vs NewBee Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
pygame学习笔记(1):矩形、圆型画图实例
2015/04/15 Python
python爬虫之urllib3的使用示例
2018/07/09 Python
TensorFlow 多元函数的极值实例
2020/02/10 Python
python 图像判断,清晰度(明暗),彩色与黑白实例
2020/06/04 Python
美国床垫和床上用品公司:Nest Bedding
2017/06/12 全球购物
Sephora丝芙兰印尼官方网站:购买化妆品和护肤品
2018/07/02 全球购物
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
《兰亭集序》教学反思
2014/02/11 职场文书
个性发展自我评价
2014/02/11 职场文书
文明礼仪伴我行演讲稿
2014/05/12 职场文书
新文化运动的口号
2014/06/21 职场文书
2015年学校少先队工作总结
2015/07/20 职场文书
被委托人身份证明
2015/08/07 职场文书
2016猴年春节问候语
2015/11/11 职场文书
MySQL连表查询分组去重的实现示例
2021/07/01 MySQL