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 相关文章推荐
smarty中先strip_tags过滤html标签后truncate截取文章运用
Oct 25 PHP
解析php中获取系统信息的方法
Jun 25 PHP
php生成图形(Libchart)实例
Nov 06 PHP
Laravel与CI框架中截取字符串函数
May 08 PHP
PHP使用xpath解析XML的方法详解
May 20 PHP
laravel如何开启跨域功能示例详解
Aug 31 PHP
php单元测试phpunit入门实例教程
Nov 17 PHP
Laravel多域名下字段验证的方法
Apr 04 PHP
Laravel 数据库加密及数据库表前缀配置方法
Oct 10 PHP
Thinkphp 在api开发中异常返回依然是html的解决方式
Oct 16 PHP
PHP与Web页面交互操作实例分析
Jun 02 PHP
PHP基于进程控制函数实现多线程
Dec 09 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数组操作实例分析【添加,删除,计算,反转,排序,查找等】
2016/12/24 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
php微信公众号开发之音乐信息
2018/10/20 PHP
js 处理URL实用技巧
2010/11/23 Javascript
jquery插件制作 自增长输入框实现代码
2012/08/17 jQuery
JQuery入门—JQuery程序的代码风格详细介绍
2013/01/03 Javascript
js 字符串转换成数字的三种方法
2013/03/23 Javascript
js 一个关于图片onload加载的事
2013/11/10 Javascript
iframe子页面与父页面在同域或不同域下的js通信
2014/05/07 Javascript
AngularJS中处理多个promise的方式
2016/02/02 Javascript
JS弹性运动实现方法分析
2016/12/15 Javascript
使用vue如何构建一个自动建站项目
2018/02/05 Javascript
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
解决vue组件销毁之后计时器继续执行的问题
2020/07/21 Javascript
[02:27]2014DOTA2国际邀请赛 VG赛后采访:更大的挑战在等着我们
2014/07/13 DOTA
python实现分页效果
2017/10/25 Python
使用Python 统计高频字数的方法
2019/01/31 Python
使用PyQtGraph绘制精美的股票行情K线图的示例代码
2019/03/14 Python
Python切图九宫格的实现方法
2019/10/10 Python
Python中常用的高阶函数实例详解
2020/02/21 Python
Python正则表达式学习小例子
2020/03/03 Python
python实现简单坦克大战
2020/03/27 Python
python 操作mysql数据中fetchone()和fetchall()方式
2020/05/15 Python
浅谈Python程序的错误:变量未定义
2020/06/02 Python
python 发送邮件的四种方法汇总
2020/12/02 Python
雅诗兰黛旗下专业男士保养领导品牌:Lab Series
2017/05/15 全球购物
南京某软件公司的.net面试题
2015/11/30 面试题
Linux如何命名文件--使用文件名时应注意
2014/05/29 面试题
医科学校毕业生自荐信
2013/11/09 职场文书
先进集体事迹材料范文
2014/12/25 职场文书
毕业生党员个人总结
2015/02/14 职场文书
使用 JavaScript 制作页面效果
2021/04/21 Javascript
DjangoRestFramework 使用 simpleJWT 登陆认证完整记录
2021/06/22 Python
总结Pyinstaller打包的高级用法
2021/06/28 Python
windows server2012 R2下安装PaddleOCR服务的的详细步骤
2022/09/23 Servers