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里得到前天和昨天的日期的代码
Aug 16 PHP
php 前一天或后一天的日期
Jun 28 PHP
PHP 高级课程笔记 面向对象
Jun 21 PHP
PHP通过header实现文本文件下载的代码
Aug 08 PHP
php启动时候提示PHP startup的解决方法
May 07 PHP
PHP实现图片旋转效果实例代码
Oct 01 PHP
php实现excel中rank函数功能的方法
Jan 20 PHP
PHP 生成微信红包代码简单
Mar 25 PHP
ThinkPHP中Common/common.php文件常用函数功能分析
May 20 PHP
php版微信js-sdk支付接口类用法示例
Oct 12 PHP
php设计模式之装饰模式应用案例详解
Jun 17 PHP
TP5框架实现一次选择多张图片并预览的方法示例
Apr 04 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 如何向 MySQL 发送数据
2006/10/09 PHP
php 中文字符入库或显示乱码问题的解决方法
2010/04/12 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
PHP字符串比较函数strcmp()和strcasecmp()使用总结
2014/11/19 PHP
thinkPHP5 ACL用户权限模块用法详解
2017/05/10 PHP
[原创]用javascript实现检测指定目录是否存在的方法
2008/01/12 Javascript
jquery的颜色选择插件实例代码
2008/10/02 Javascript
理解Javascript_03_javascript全局观
2010/10/11 Javascript
基于JQuery 的消息提示框效果代码
2011/07/31 Javascript
JS实现在网页中弹出一个输入框的方法
2015/03/03 Javascript
JavaScript数组前面插入元素的方法
2015/04/06 Javascript
JavaScript实现自动切换图片代码
2016/10/11 Javascript
10道典型的JavaScript面试题
2017/03/22 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
Vue组件通信实践记录(推荐)
2017/08/15 Javascript
angularjs实现分页和搜索功能
2018/01/03 Javascript
React中this丢失的四种解决方法
2019/03/12 Javascript
浅谈一个webpack构建速度优化误区
2019/06/24 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
2020/08/07 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
[48:24]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第一场 12.09
2020/12/12 DOTA
Python isinstance判断对象类型
2008/09/06 Python
Python脚本实现格式化css文件
2015/04/08 Python
Python时间的精准正则匹配方法分析
2017/08/17 Python
Python设计模式之代理模式简单示例
2018/01/09 Python
Pycharm无法显示动态图片的解决方法
2018/10/28 Python
python数据爬下来保存的位置
2020/02/17 Python
PyQt5 QDockWidget控件应用详解
2020/08/12 Python
会计顶岗实习心得
2014/01/25 职场文书
蛋糕店的商业计划书范文
2014/01/27 职场文书
生产车间标语
2014/06/11 职场文书
小学生安全教育广播稿
2014/10/20 职场文书
2014年内勤工作总结
2014/11/24 职场文书
Python中Schedule模块使用详解 周期任务神器
2022/04/19 Python
Flutter Navigator 实现路由传递参数
2022/04/22 Java/Android