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 相关文章推荐
Classes and Objects in PHP5-面向对象编程 [1]
Oct 09 PHP
PHP中的超全局变量
Oct 09 PHP
PHP insert语法详解
Jun 07 PHP
浅析PHP编程中10个最常见的错误
Aug 08 PHP
php使用正则表达式获取图片url的方法
Jan 16 PHP
php自定义urlencode,urldecode函数实例
Mar 24 PHP
详解php的socket通信
Aug 11 PHP
PHP实现HTML页面静态化的方法
Nov 04 PHP
PHP使用FFmpeg获取视频播放总时长与码率等信息
Sep 13 PHP
Ubuntu中支持PHP5与PHP7双版本的简单实现
Aug 19 PHP
tp5(thinkPHP5)框架数据库Db增删改查常见操作总结
Jan 10 PHP
Yii框架连表查询操作示例
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 分页类 扩展代码
2009/06/11 PHP
浅析php中常量,变量的作用域和生存周期
2013/08/10 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
thinkPHP框架实现图像裁剪、缩放、加水印的方法
2017/03/14 PHP
浅谈PHP中new self()和new static()的区别
2017/08/11 PHP
php实现图片压缩处理
2020/09/09 PHP
Javascript实现的分页函数
2006/12/22 Javascript
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
2007/03/06 Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
2010/11/05 Javascript
javascript分页代码实例分享(js分页)
2013/12/13 Javascript
js实现完全自定义可带多级目录的网页鼠标右键菜单方法
2015/02/28 Javascript
原生js实现模拟滚动条
2015/06/15 Javascript
Highcharts学习之数据列
2016/08/03 Javascript
PHP抓取HTTPS内容和错误处理的方法
2016/09/30 Javascript
详解JavaScript中的属性和特性
2016/12/08 Javascript
使用jQuery实现动态添加小广告
2017/07/11 jQuery
Angular Material Icon使用详解
2018/11/07 Javascript
vue前后分离调起微信支付
2019/07/29 Javascript
jquery ajax 请求小技巧实例分析
2019/11/11 jQuery
JS中多层次排序算法的实现代码
2021/01/06 Javascript
[15:20]DOTA2亚洲邀请赛总决赛开幕式表演:羽泉献唱
2017/04/05 DOTA
python实现去除下载电影和电视剧文件名中的多余字符的方法
2014/09/23 Python
使用Tensorflow实现可视化中间层和卷积层
2020/01/24 Python
python图形开发GUI库wxpython使用方法详解
2020/02/14 Python
Python selenium自动化测试模型图解
2020/04/15 Python
Anaconda配置pytorch-gpu虚拟环境的图文教程
2020/04/16 Python
Jupyter安装链接aconda实现过程图解
2020/11/02 Python
西班牙网上书店:Casa del Libro
2016/11/01 全球购物
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
软件生产职位结构化面试主要考察要素及面试题库
2015/06/12 面试题
庆八一活动方案
2014/01/25 职场文书
北京大学自荐信范文
2014/01/28 职场文书
网络管理专业求职信
2014/03/15 职场文书
党员四风问题个人对照检查材料
2014/10/26 职场文书
2015年学校少先队工作总结
2015/07/20 职场文书
为什么RedisCluster设计成16384个槽
2021/09/25 Redis