PHP 事件机制(2)

于上一个版本的区别,把事件处理简化:

<?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[$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,$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[$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,$method,$class=null){
        
$eventstr=(string)$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(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();
}
原文地址:https://www.cnblogs.com/liushannet/p/1991551.html