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 相关文章推荐
PHP4 与 MySQL 数据库操作函数详解
Oct 09 PHP
php中的一些数组排序方法分享
Jul 20 PHP
php简单开启gzip压缩方法(zlib.output_compression)
Apr 13 PHP
深入掌握include_once与require_once的区别
Jun 17 PHP
PHP 输出URL的快捷方式示例代码
Sep 22 PHP
可以保证单词完整性的PHP英文字符串截取代码分享
Jul 15 PHP
set_exception_handler函数在ThinkPHP中的用法
Oct 31 PHP
php日期操作技巧小结
Jun 25 PHP
浅谈php fopen下载远程文件的函数
Nov 18 PHP
PHP+Ajax实现的检测用户名功能简单示例
Feb 12 PHP
ThinkPHP框架结合Ajax实现用户名校验功能示例
Jul 03 PHP
PhpStorm 2020.3:新增开箱即用的PHP 8属性(推荐)
Oct 30 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中DOMElement操作xml文档实例演示
2013/03/26 PHP
php三维数组去重(示例代码)
2013/11/26 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
2017/11/17 PHP
用JavaScript实现类似于ListBox功能示例代码
2014/03/09 Javascript
jquery获得同源iframe内body下标签的值的方法
2014/09/25 Javascript
Nodejs极简入门教程(一):模块机制
2014/10/25 NodeJs
jQueryMobile之Helloworld与页面切换的方法
2015/02/04 Javascript
javascript实时显示当天日期的方法
2015/05/20 Javascript
Javascript函数式编程语言
2015/10/11 Javascript
JS实现按比例缩放图片的方法(附C#版代码)
2015/12/08 Javascript
jQuery 3.0十大新特性
2016/07/06 Javascript
jQuery实现的无缝广告图片左右滚动功能详解
2016/12/24 Javascript
对于Javascript 执行上下文的全面了解
2017/09/05 Javascript
利用JavaScript缓存远程窃取Wi-Fi密码的思路详解
2018/11/05 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
Vue如何基于es6导入外部js文件
2020/05/15 Javascript
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
Python zip()函数用法实例分析
2018/03/17 Python
python 获取list特定元素下标的实例讲解
2018/04/09 Python
python 求一个列表中所有元素的乘积实例
2019/06/11 Python
Python创建数字列表的示例
2019/11/28 Python
Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签
2019/12/04 Python
Pandas实现DataFrame按行求百分数(比例数)
2019/12/27 Python
Python实现点云投影到平面显示
2020/01/18 Python
tensorflow tf.train.batch之数据批量读取方式
2020/01/20 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
django使用channels实现通信的示例
2020/10/19 Python
matplotlib更改窗口图标的方法示例
2021/02/03 Python
中国医药集团国药在线:国药网
2017/02/06 全球购物
俄罗斯第一家多品牌在线奢侈品精品店:Aizel.ru
2020/09/06 全球购物
开学典礼感言
2014/02/16 职场文书
审计局班子四风对照检查材料思想汇报
2014/10/07 职场文书
刑事上诉状范文
2015/05/22 职场文书
JDBC连接的六步实例代码(与mysql连接)
2021/05/12 MySQL
Golang原生rpc(rpc服务端源码解读)
2022/04/07 Golang
SQL Server中搜索特定的对象
2022/05/25 SQL Server