PHP 事件机制

项目中需要事件机制,仿AS3实现,所以就下了个,代码如下:

代码
<?php
/**
 * 事件异常
 *
 * @author        lonely
 * @create            2010-10-21
 * @version        0.1
 * @lastupdate     lonely
 * @package     Event
*/
class Exception_Event extends Exception {}
/**
 * 事件对象
 *
 * @author        lonely
 * @create            2010-10-21
 * @version        0.1
 * @lastupdate     lonely
 * @package     Event
*/
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;
    }
}
/**
 * 事件派发
 *
 * @author        lonely
 * @create            2010-10-21
 * @version        0.1
 * @lastupdate     lonely
 * @package     Event
*/
class EventDispatcher{
    
private $_callback_method;
    
/**
     * 添加事件
     * @param Event $event
     * @param string $method
     * @param string||object $class
     * @return boolean true
     
*/
    
public function attach(Event $event,$method,$class=null){
        
$event->target=$this;
        
$eventstr=$this->_create_event_str($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){
        
$eventstr=$this->_create_event_str($event);
        
if($this->_check_callback($eventstr)){
            
foreach ($this->_callback_method[$eventstras $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 $event,$method,$class=null){
        
$eventstr=$this->_create_event_str($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[$eventstras $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[$eventstras $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 $event,$method,$class=null){
        
$eventstr=$this->_create_event_str($event);
        
if(($class!=null)){
            
$this->_check_method($class,$method);
            
if($this->_check_callback($eventstr)){
                
foreach($this->_callback_method[$eventstras $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[$eventstras $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_Event(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_Event($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,
        );
    }
    
/**
     * 创建事件字符串
     * @param Event $event
     * @return string 
     
*/
    
private function _create_event_str(Event $event){
        
$classstr=strtolower(get_class($event));
        
$eventstr=(string)$event;
        
return $classstr.$eventstr;
    }
}
class test extends EventDispatcher{
    
}
function t($e){
    
print_r($e->a);
}
$v=new test();
$e=new Event("test");
$v->attach($e,"t");
$v->detact($e,"t");
echo $v->has($e,"t");
$e->a="dd";
$v->dispatch($e);
原文地址:https://www.cnblogs.com/liushannet/p/1921028.html