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 adodb操作mysql数据库
Mar 19 PHP
php 函数使用方法与函数定义方法
May 09 PHP
关于使用coreseek并为其做分页的介绍
Jun 21 PHP
PHP采集类Snoopy抓取图片实例
Jun 19 PHP
PHP解码unicode编码的中文字符代码分享
Aug 13 PHP
Opcache导致php-fpm崩溃nginx返回502
Mar 02 PHP
PHP正则表达式入门教程(推荐)
May 18 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
Jun 05 PHP
php PDO判断连接是否可用的实现方法
Apr 03 PHP
浅析PHP中的闭包和匿名函数
Dec 25 PHP
php用户名的密码加密更安全的方法
Jun 21 PHP
Laravel 修改验证异常的响应格式实例代码详解
May 25 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调用三种数据库的方法(1)
2006/10/09 PHP
php小偷相关截取函数备忘
2010/11/28 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
firefox中JS读取XML文件
2006/12/21 Javascript
一个可绑定数据源的jQuery数据表格插件
2010/07/17 Javascript
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
JS小游戏之宇宙战机源码详解
2014/09/25 Javascript
js实现二代身份证号码验证详解
2014/11/20 Javascript
浅谈Javascript如何实现匀速运动
2014/12/19 Javascript
JavaScript生成SQL查询表单的方法
2015/08/13 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
2015/08/24 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记8)
2015/12/24 Javascript
Javascript中的对象和原型(二)
2016/08/12 Javascript
Angular2监听页面大小变化的解决方法
2017/10/09 Javascript
AngularJs用户输入动态模板XSS攻击示例详解
2018/04/21 Javascript
在 Vue 中使用 JSX 及使用它的原因浅析
2020/02/10 Javascript
浅谈vue 组件中的setInterval方法和window的不同
2020/07/30 Javascript
[03:55]显微镜下的DOTA2特别篇——430灰烬之灵神级操作
2014/06/24 DOTA
Python写的创建文件夹自定义函数mkdir()
2014/08/25 Python
Python中多线程及程序锁浅析
2015/01/21 Python
Python常见异常分类与处理方法
2017/06/04 Python
tensorflow更改变量的值实例
2018/07/30 Python
解决安装pycharm后不能执行python脚本的问题
2019/01/19 Python
解决项目pycharm能运行,在终端却无法运行的问题
2019/01/19 Python
使用WingPro 7 设置Python路径的方法
2019/07/24 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
2020/08/11 Python
Python实现淘宝秒杀功能的示例代码
2021/01/19 Python
Django中的DateTimeField和DateField实现
2021/02/24 Python
苹果Mac升级:MacSales.com
2017/11/20 全球购物
TripAdvisor台湾:全球最大旅游网站
2018/08/26 全球购物
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
致百米运动员广播稿
2014/01/29 职场文书
狼和鹿教学反思
2014/02/05 职场文书
仓库统计员岗位职责
2015/04/14 职场文书
员工担保书范本
2015/09/22 职场文书
python周期任务调度工具Schedule使用详解
2021/11/23 Python