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 相关文章推荐
phpwind中的数据库操作类
Jan 02 PHP
php miniBB中文乱码问题解决方法
Nov 25 PHP
thinkphp四种url访问方式详解
Nov 28 PHP
对PHP PDO的一些认识小结
Jan 23 PHP
使用图灵api创建微信聊天机器人
Jul 23 PHP
[原创]php简单隔行变色功能实现代码
Jul 09 PHP
详解PHP实现定时任务的五种方法
Jul 25 PHP
PHP实现的曲线统计图表示例
Nov 10 PHP
php实现socket推送技术的示例
Dec 20 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
Feb 07 PHP
PHP设计模式之模板方法模式定义与用法详解
Apr 02 PHP
PHP如何防止XSS攻击与XSS攻击原理的讲解
Mar 22 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数组中删除元素之重新索引的方法
2014/09/16 PHP
php发送html格式文本邮件的方法
2015/06/10 PHP
PHP页面输出时js设置input框的选中值
2016/09/30 PHP
Yii遍历行下每列数据的方法
2016/10/17 PHP
php unicode编码和字符串互转的方法
2020/08/12 PHP
PHP实现负载均衡session共享redis缓存操作示例
2018/08/22 PHP
了解jQuery技巧来提高你的代码
2010/01/08 Javascript
js实现简单登录功能的实例代码
2013/11/09 Javascript
javascript 寻找错误方法整理
2014/06/15 Javascript
textarea不能通过maxlength属性来限制字数的解决方法
2014/09/01 Javascript
页面get请求 中文参数方法乱码问题的快速解决方法
2016/05/31 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
基于JavaScript实现全选、不选和反选效果
2017/02/15 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
2017/04/25 Javascript
浅谈Angular 的变化检测的方法
2018/03/01 Javascript
vue实现裁切图片同时实现放大、缩小、旋转功能
2018/03/02 Javascript
vue-router判断页面未登录自动跳转到登录页的方法示例
2018/11/04 Javascript
100行代码实现一个vue分页组功能
2018/11/06 Javascript
JS实现计算小于非负数n的素数的数量算法示例
2019/02/26 Javascript
ES6的异步终极解决方案分享
2019/07/11 Javascript
跟老齐学Python之关于类的初步认识
2014/10/11 Python
Python实现控制台进度条功能
2016/01/04 Python
python 字典(dict)按键和值排序
2016/06/28 Python
使用python实现滑动验证码功能
2019/08/05 Python
Python shelve模块实现解析
2019/08/28 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
2019/10/30 Python
绘儿乐产品官方在线商店:Crayola.com
2019/09/07 全球购物
介绍一下SQL中union,intersect和minus
2012/04/05 面试题
能否解释一下XSS cookie盗窃是什么意思
2012/06/02 面试题
清扬洗发水广告词
2014/03/14 职场文书
2014年生产部工作总结
2014/12/17 职场文书
2016年全国爱眼日宣传教育活动总结
2016/04/05 职场文书
HAM-2000摩机图
2021/04/22 无线电
JS中如何优雅的使用async await详解
2021/10/05 Javascript
Java无向树分析 实现最小高度树
2022/04/09 Javascript