PHP 事件机制(2)


Posted in PHP onMarch 23, 2011
<?php 
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; 
} 
} abstract class EventDispatcher{ 
private $_callback_method; 
/** 
* 添加事件 
* @param Event $event 
* @param string $method 
* @param string||object $class 
* @return boolean true 
*/ 
public function attach($event,$method,$class=null){ 
$eventstr=(string)$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){ 
$event->target=$this; 
$eventstr=(string)$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,$method,$class=null){ 
$eventstr=(string)$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,$method,$class=null){ 
$eventstr=(string)$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(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($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, 
); 
} 
} 

class myevent extends Event{ 
const aa='aaa'; 
} 
class ball extends EventDispatcher{ 
public function aa(){ 
$event=new myevent(myevent::aa); 
$this->dispatch($event); 
} 
} 
class mytest { 
public function test(){ 
$ball=new ball(); 
$ball->attach(myevent::aa,'kk'); 
$ball->aa(); 
} 
public function kk($e){ 
print_r($e); 
} 
} 

try{ 
$t=new mytest(); 
$t->test(); 
}catch (Exception $e){ 
echo $e->getmessage(); 
}
PHP 相关文章推荐
PHP开发大型项目的一点经验
Oct 09 PHP
PHP中显示格式化的用户输入
Oct 09 PHP
PHP 5.3.0 安装分析心得
Aug 07 PHP
PHP常用代码大全(新手入门必备)
Jun 29 PHP
微信公众号点击菜单即可打开并登录微站的实现方法
Nov 14 PHP
php源码分析之DZX1.5字符串截断函数cutstr用法
Jun 17 PHP
一个完整的php文件上传类实例讲解
Oct 27 PHP
CodeIgniter配置之autoload.php自动加载用法分析
Jan 20 PHP
php生成txt文件实例代码介绍
Apr 28 PHP
php+ajax注册实时验证功能
Jul 20 PHP
php版微信开发之接收消息,自动判断及回复相应消息的方法
Sep 23 PHP
php获取linux命令结果的实例
Mar 13 PHP
php函数之子字符串替换&amp;#65279; str_replace
Mar 23 #PHP
php expects parameter 1 to be resource, array given 错误
Mar 23 #PHP
php去掉字符串的最后一个字符附substr()的用法
Mar 23 #PHP
PHPUnit PHP测试框架安装方法
Mar 23 #PHP
开启CURL扩展,让服务器支持PHP curl函数(远程采集)
Mar 19 #PHP
windows下开发并编译PHP扩展的方法
Mar 18 #PHP
WordPress判断用户是否登录的代码
Mar 17 #PHP
You might like
BBS(php &amp; mysql)完整版(六)
2006/10/09 PHP
PHP 引用是个坏习惯
2010/03/12 PHP
thinkphp判断访客为手机端或PC端的方法
2014/11/24 PHP
javascript 简单高效判断数据类型 系列函数 By shawl.qiu
2007/03/06 Javascript
Jquery常用技巧收集整理篇
2010/11/14 Javascript
利用jQuery操作对象数组的实现代码
2011/04/27 Javascript
(跨浏览器基础事件/浏览器检测/判断浏览器)经验代码分享
2013/01/24 Javascript
js+css实现增加表单可用性之提示文字
2013/06/03 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
2015/01/19 Javascript
javascript实现tab切换的四种方法
2015/11/05 Javascript
Position属性之relative用法
2015/12/14 Javascript
JavaScript对象参数的引用传递
2016/01/14 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
jQuery实现的选择商品飞入文本框动画效果完整实例
2016/08/10 Javascript
Vue父子模版传值及组件传值的三种方法
2017/11/27 Javascript
JS写谷歌浏览器chrome的外挂实例
2018/01/11 Javascript
js实现点击展开隐藏效果(实例代码)
2018/09/28 Javascript
详解python开发环境搭建
2016/12/16 Python
Python 关于反射和类的特殊成员方法
2017/09/14 Python
Python基于高斯消元法计算线性方程组示例
2018/01/17 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
python基于递归解决背包问题详解
2019/07/03 Python
python实现中文文本分句的例子
2019/07/15 Python
浅析pandas 数据结构中的DataFrame
2019/10/12 Python
解决pytorch DataLoader num_workers出现的问题
2020/01/14 Python
关于Kotlin中SAM转换的那些事
2020/09/15 Python
python中如何打包用户自定义模块
2020/09/23 Python
劲霸男装广告词改编版
2014/03/21 职场文书
孝老爱亲模范事迹材料
2014/05/25 职场文书
2014小学教师个人工作总结
2014/11/10 职场文书
借款民事起诉状范文
2015/05/19 职场文书
2015双创工作总结
2015/07/24 职场文书
Vue.Draggable实现交换位置
2022/04/07 Vue.js
Mysql 8.x 创建用户以及授予权限的操作记录
2022/04/18 MySQL
SQLyog的下载、安装、破解、配置教程(MySQL可视化工具安装)
2022/09/23 MySQL