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 得到根目录的 __FILE__ 常量
Jul 23 PHP
php 批量生成html,txt文件的实现代码
Jun 26 PHP
Thinkphp模板中截取字符串函数简介
Jun 17 PHP
浅析php单例模式
Nov 25 PHP
php curl登陆qq后获取用户信息时证书错误
Feb 03 PHP
全面解析PHP操作Memcache基本函数
Jul 14 PHP
Yii框架表单提交验证功能分析
Jan 07 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
Apr 19 PHP
PHP实现Unicode编码相互转换的方法示例
Nov 17 PHP
php将html转为图片的实现方法
May 19 PHP
laravel5使用freetds连接sql server的方法
Dec 07 PHP
thinkphp5框架API token身份验证功能示例
May 21 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编实现程动态图像的创建代码
2008/09/28 PHP
php中模拟POST传递数据的两种方法分享
2011/09/16 PHP
基于Discuz security.inc.php代码的深入分析
2013/06/03 PHP
基于PHP对XML的操作详解
2013/06/07 PHP
php中heredoc与nowdoc介绍
2014/12/25 PHP
jQuery使用手册之一
2007/03/24 Javascript
jQuery判断iframe中元素是否存在的方法
2013/05/11 Javascript
利用try-catch判断变量是已声明未声明还是未赋值
2014/03/12 Javascript
JQuery调用WebServices的方法和4个实例
2014/05/06 Javascript
我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环
2014/07/06 Javascript
jQuery隐藏和显示效果实现
2016/04/06 Javascript
canvas实现钟表效果
2017/02/13 Javascript
AngularJS之ionic 框架下实现 Localstorage本地存储
2017/04/22 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
微信小程序图片选择区域裁剪实现方法
2017/12/02 Javascript
vue项目部署上线遇到的问题及解决方法
2018/06/10 Javascript
javascript实现移动端触屏拖拽功能
2020/07/29 Javascript
ant-design-vue中tree增删改的操作方法
2020/11/03 Javascript
python开发中module模块用法实例分析
2015/11/12 Python
Python处理JSON数据并生成条形图
2016/08/05 Python
Python随机生成手机号、数字的方法详解
2017/07/21 Python
python2.7和NLTK安装详细教程
2018/09/19 Python
对Python3使运行暂停的方法详解
2019/02/18 Python
python tkinter库实现气泡屏保和锁屏
2019/07/29 Python
python+selenium实现12306模拟登录的步骤
2021/01/21 Python
发现两个有趣的CSS3动画效果
2013/08/14 HTML / CSS
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
巴西网上药房:onofre
2016/11/21 全球购物
美国马匹用品和骑马配件购物网站:Horse.com
2018/01/08 全球购物
回馈慈善的设计师太阳镜:DIFF eyewear
2019/10/17 全球购物
实现strstr功能,即在父串中寻找子串首次出现的位置
2016/08/05 面试题
中文专业毕业生自荐信
2013/10/28 职场文书
消防应急演练方案
2014/02/12 职场文书
人资专员岗位职责
2014/04/04 职场文书
物联网工程专业推荐信
2014/09/08 职场文书
挂职锻炼工作总结2015
2015/05/28 职场文书