PHP event mechanism of 2

  • 2020-03-31 21:33:50
  • OfStack

 
<?php 
class Event extends stdClass{ 
public $target=null; 
public $type=null; 
 
public function __construct($type){ 
$this->type=trim($type); 
} 
 
public function __toString(){ 
return $this->type; 
} 
} 

abstract class EventDispatcher{ 
private $_callback_method; 
 
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; 
} 
 
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); 
} 
} 
} 
} 
 
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; 
} 
} 
 
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; 
} 
 
private function _check_method($class,$method){ 
if(!method_exists($class,$method)){ 
throw new Exception(get_class($class)." not exist ".$method." method",1); 
} 
} 
 
private function _check_function($function){ 
if(!function_exists($function)){ 
throw new Exception($function." function not exist ",2); 
} 
} 
 
private function _check_callback($eventstr){ 
if(isset($this->_callback_method[$eventstr]) 
&&is_array($this->_callback_method[$eventstr]) 
){ 
return true; 
} 
return false; 
} 
 
private function _create_listener_fn($eventstr,$function){ 
return array( 
"object"=>false, 
"function"=>$function, 
); 
} 
 
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(); 
} 

Related articles: