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 相关文章推荐
一次编写,随处运行
Oct 09 PHP
在IIS上安装PHP4.0正式版
Oct 09 PHP
php防盗链的常用方法小结
Jul 02 PHP
php调用Google translate_tts api实现代码
Aug 07 PHP
php数组编码转换示例详解
Mar 11 PHP
php中使用getimagesize获取图片、flash等文件的尺寸信息实例
Apr 29 PHP
php中ltrim()、rtrim()与trim()删除字符空格实例
Nov 25 PHP
php去除字符串中空字符的常用方法小结
Mar 17 PHP
适用于初学者的简易PHP文件上传类
Oct 29 PHP
简单解析PHP程序的运行流程
Jun 23 PHP
PHP的mysqli_stat()函数讲解
Jan 23 PHP
微信小程序结合ThinkPHP5授权登陆后获取手机号
Nov 23 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
2021年最新CPU天梯图
2021/03/04 数码科技
一步一步学习PHP(6) 面向对象
2010/02/16 PHP
PHP中文件上传的一个问题
2010/09/04 PHP
PHP简单处理表单输入的特殊字符的方法
2016/02/03 PHP
jquery 学习之二 属性相关
2010/11/23 Javascript
JS执行删除前的判断代码
2014/02/18 Javascript
封装好的js判断操作系统与浏览器代码分享
2015/01/09 Javascript
js实现仿阿里巴巴城市选择框效果实例
2015/06/24 Javascript
JavaScript实现输入框(密码框)出现提示语
2016/01/12 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
初识NodeJS服务端开发入门(Express+MySQL)
2017/04/07 NodeJs
vue.js实现单选框、复选框和下拉框示例
2017/07/18 Javascript
Vue Element使用icon图标教程详解(第三方)
2018/02/07 Javascript
使用react实现手机号的数据同步显示功能的示例代码
2018/04/03 Javascript
[00:53]TI3正赛第三天 DK怒破A队不败金身 现场国旗飘扬热血激昂
2013/08/10 DOTA
[00:32]2018DOTA2亚洲邀请赛Mineski出场
2018/04/04 DOTA
python在命令行下使用google翻译(带语音)
2014/01/16 Python
跟老齐学Python之网站的结构
2014/10/24 Python
基于python OpenCV实现动态人脸检测
2018/05/25 Python
python获取微信小程序手机号并绑定遇到的坑
2018/11/19 Python
浅谈Python接口对json串的处理方法
2018/12/19 Python
Python实现连接MySql数据库及增删改查操作详解
2019/04/16 Python
django删除表重建的实现方法
2019/08/28 Python
Python如何根据时间序列数据作图
2020/05/12 Python
Django如何在不停机的情况下创建索引
2020/08/02 Python
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
迟到检讨书300字
2014/02/14 职场文书
贺卡寄语大全
2014/04/11 职场文书
数学兴趣小组活动总结
2014/07/08 职场文书
部门群众路线教育实践活动对照检查材料思想汇报
2014/10/07 职场文书
民政局离婚协议书范本
2014/10/20 职场文书
趵突泉导游词
2015/02/03 职场文书
自我工作评价范文
2015/03/06 职场文书
MySQL中VARCHAR与CHAR格式数据的区别
2021/05/26 MySQL
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL
《战锤40K:暗潮》跳票至9月 公布新宣传片
2022/04/03 其他游戏