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 相关文章推荐
example2.php
Oct 09 PHP
PHP Mysql编程之高级技巧
Aug 27 PHP
PHP读取XML值的代码(推荐)
Jan 01 PHP
5种PHP创建数组的实例代码分享
Jan 17 PHP
php实现的漂亮分页方法
Apr 17 PHP
PHP实现图片裁剪、添加水印效果代码
Oct 01 PHP
PHP统计数值数组中出现频率最多的10个数字的方法
Apr 20 PHP
PHP合并discuz用户脚本的方法
Aug 04 PHP
PHP常用工具类大全附全部代码下载
Dec 07 PHP
thinkphp3.2实现上传图片的控制器方法
Apr 28 PHP
PHP中header函数的用法及其注意事项详解
Jun 13 PHP
php JWT在web端中的使用方法教程
Sep 06 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
PHP删除数组中特定元素的两种方法
2013/07/02 PHP
PHP验证码函数代码(简单实用)
2013/09/29 PHP
php实现复制移动文件的方法
2015/07/29 PHP
thinkPHP自定义类实现方法详解
2016/11/30 PHP
Laravel5.3+框架定义API路径取消CSRF保护方法详解
2020/04/06 PHP
ie和firefox中img对象区别的困惑
2006/12/27 Javascript
在IE模态窗口中自由查看HTML源码的方法
2007/03/08 Javascript
TinyMCE提交AjaxForm获取不到数据的解决方法
2015/03/05 Javascript
JS实现当前页居中分页效果的方法
2015/06/18 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
AngularJS监听ng-repeat渲染完成的方法
2018/03/20 Javascript
js实现二级菜单点击显示当前内容效果
2018/04/28 Javascript
vue2.0 实现导航守卫(路由守卫)
2018/05/21 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
Vue Promise的axios请求封装详解
2018/08/13 Javascript
layui table 参数设置方法
2018/08/14 Javascript
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
javascript实现切割轮播效果
2019/11/28 Javascript
typescript配置alias的详细步骤
2020/08/12 Javascript
详细解读tornado协程(coroutine)原理
2018/01/15 Python
使用Django和Python创建Json response的方法
2018/03/26 Python
《与孩子一起学编程》python自测题
2018/05/27 Python
pandas 小数位数 精度的处理方法
2018/06/09 Python
详解如何将python3.6软件的py文件打包成exe程序
2018/10/09 Python
python 生成图形验证码的方法示例
2018/11/11 Python
Python爬虫requests库多种用法实例
2020/05/28 Python
Python 操作SQLite数据库的示例
2020/10/16 Python
万得城电器土耳其网站:欧洲第一大电子产品零售商
2016/10/07 全球购物
护士实习自我鉴定
2013/10/22 职场文书
个人委托书范本
2014/04/02 职场文书
日语系毕业求职信
2014/07/27 职场文书
调研座谈会发言材料
2014/08/23 职场文书
2014党员四风对照检查材料思想汇报
2014/09/17 职场文书
2014年连锁店圣诞节活动方案
2014/12/09 职场文书
2015年青年志愿者协会工作总结
2015/04/27 职场文书