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.MVC的模板标签系统(五)
Sep 05 PHP
PHP 一个随机字符串生成代码
May 26 PHP
全局记录程序片段的运行时间 正确找到程序逻辑耗时多的断点
Jan 06 PHP
php正则取img标记中任意属性(正则替换去掉或改变图片img标记中的任意属性)
Aug 13 PHP
PHP 输出URL的快捷方式示例代码
Sep 22 PHP
PHP根据IP地址获取所在城市具体实现
Nov 27 PHP
PHP+ajaxfileupload+jcrop插件完美实现头像上传剪裁
Jun 09 PHP
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
Jul 15 PHP
PHP中array_keys和array_unique函数源码的分析
Feb 26 PHP
深入浅析Yii admin的权限控制
Aug 31 PHP
PHP 实现页面静态化的几种方法
Jul 23 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
Jun 08 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 ss7.5的数据调用 (笔记)
2010/03/08 PHP
PHP使用php-resque库配合Redis实现MQ消息队列的教程
2016/06/29 PHP
Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
2010/06/11 Javascript
Extjs Gird 支持中文拼音排序实现代码
2013/04/15 Javascript
js计算任意值之间随机数的方法
2015/01/16 Javascript
详解Javascript中的Object对象
2016/02/28 Javascript
移动端横屏的JS代码(beta)
2016/05/16 Javascript
bootstrap table之通用方法( 时间控件,导出,动态下拉框, 表单验证 ,选中与获取信息)代码分享
2017/01/24 Javascript
js轮播图的插件化封装详解
2017/07/17 Javascript
实例详解JSON取值(key是中文或者数字)方式
2017/08/24 Javascript
JS运动特效之任意值添加运动的方法分析
2018/01/24 Javascript
Vue2.0 http请求以及loading展示实例
2018/03/06 Javascript
JS实现图片切换效果
2018/11/17 Javascript
微信小程序点击顶部导航栏切换样式代码实例
2019/11/12 Javascript
Vue引入Stylus知识点总结
2020/01/16 Javascript
原生js实现html手机端城市列表索引选择城市
2020/06/24 Javascript
vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件
2021/02/20 Vue.js
Python爬取网易云音乐上评论火爆的歌曲
2017/01/19 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
利用python实现汉字转拼音的2种方法
2019/08/12 Python
Python+OpenCV实现实时眼动追踪的示例代码
2019/11/11 Python
基于Python批量生成指定尺寸缩略图代码实例
2019/11/20 Python
python itsdangerous模块的具体使用方法
2020/02/17 Python
Python关键字及可变参数*args,**kw原理解析
2020/04/04 Python
详解html5页面 rem 布局适配方法
2018/01/12 HTML / CSS
美国知名日用品连锁超市:Dollar General(多来店)
2017/01/14 全球购物
海滩咖啡馆:Beach Cafe
2018/02/02 全球购物
意大利奢侈品多品牌集合店:TheDoubleF
2019/08/24 全球购物
三好学生自我鉴定
2013/12/17 职场文书
业务员工作态度散漫检讨书
2014/11/02 职场文书
党员“一帮一”活动总结
2015/05/07 职场文书
推销搭讪开场白
2015/05/28 职场文书
导游词之徐州云龙湖
2019/11/19 职场文书
Python使用OpenCV和K-Means聚类对毕业照进行图像分割
2021/06/11 Python
Pandas实现DataFrame的简单运算、统计与排序
2022/03/31 Python
Java实现HTML转为Word的示例代码
2022/06/28 Java/Android