仿AS3实现PHP 事件机制
<?php
002 /**
003 * 事件异常
004 *
005 * @author lonely
006 * @create 2010-10-21
007 * @version 0.1
008 * @lastupdate lonely
009 * @package Event
010 */
011 class Exception_Event extends Exception {}
012 /**
013 * 事件对象
014 *
015 * @author lonely
016 * @create 2010-10-21
017 * @version 0.1
018 * @lastupdate lonely
019 * @package Event
020 */
021 class Event extends stdClass{
022 public $target=null;
023 public $type=null;
024 /**
025 * 创建事件
026 * @param string $type
027 */
028 public function __construct($type){
029 $this->type=trim($type);
030 }
031 /**
032 * 得到事件字符串
033 */
034 public function __toString(){
035 return $this->type;
036 }
037 }
038 /**
039 * 事件派发
040 *
041 * @author lonely
042 * @create 2010-10-21
043 * @version 0.1
044 * @lastupdate lonely
045 * @package Event
046 */
047 class EventDispatcher{
048 private $_callback_method;
049 /**
050 * 添加事件
051 * @param Event $event
052 * @param string $method
053 * @param string||object $class
054 * @return boolean true
055 */
056 public function attach(Event $event,$method,$class=null){
057 $event->target=$this;
058 $eventstr=$this->_create_event_str($event);
059 if($this->has($event,$method,$class))
060 return true;
061 if($class!=null){
062 $this->_check_method($class,$method);
063 $this->_callback_method[$eventstr][]=$this->_create_listener_method($eventstr,$class,$method);
064 }else{
065 $this->_check_function($method);
066 $this->_callback_method[$eventstr][]=$this->_create_listener_fn($eventstr,$method);
067 }
068 return true;
069 }
070 /**
071 * 派发事件
072 * @param Event $event
073 * @param string $method
074 * @param string||object $class
075 * @return void
076 */
077 public function dispatch(Event $event){
078 $eventstr=$this->_create_event_str($event);
079 if($this->_check_callback($eventstr)){
080 foreach ($this->_callback_method[$eventstr] as $v){
081 if($v['object']){
082 if(is_object($v['class'])){
083 $v['class']->$v['method']($event);
084 }else{
085 call_user_func(array($v['class'], $v['method']),$event);
086 }
087 }else{
088 $v['function']($event);
089 }
090 }
091 }
092 }
093 /**
094 * 删除事件
095 * @param Event $event
096 * @param string $method
097 * @param string $class
098 * @return boolean true
099 */
100 public function detact(Event $event,$method,$class=null){
101 $eventstr=$this->_create_event_str($event);
102 if(!$this->_check_callback($eventstr))
103 return true;
104 if(!$this->has($event,$method,$class))
105 return true;
106 if($class!=null){
107 $this->_check_method($class,$method);
108 foreach ($this->_callback_method[$eventstr] as $k=>$v) {
109 if(($v==$this->_create_listener_method($eventstr,$class,$method))){
110 unset($this->_callback_method[$eventstr][$k]);
111 return true;
112 }
113 }
114 return true;
115 }else{
116 $this->_check_function($method);
117 foreach ($this->_callback_method[$eventstr] as $k=>$v) {
118 if(($v==$this->_create_listener_fn($eventstr,$method))){
119 unset($this->_callback_method[$eventstr][$k]);
120 return true;
121 }
122 }
123 return true;
124 }
125 }
126 /**
127 * 检测事件是否监听
128 * @param Event $event
129 * @param string $method
130 * @param string $class
131 * @return boolean
132 */
133 public function has(Event $event,$method,$class=null){
134 $eventstr=$this->_create_event_str($event);
135 if(($class!=null)){
136 $this->_check_method($class,$method);
137 if($this->_check_callback($eventstr)){
138 foreach($this->_callback_method[$eventstr] as $v){
139 if(is_object($v['class'])){
140 $v_class=get_class($v['class']);
141 }else{
142 $v_class=$v['class'];
143 }
144 if(is_object($class)){
145 $s_class=get_class($class);
146 }else{
147 $s_class=$class;
148 }
149 $temp_v=array(
150 "class"=>$v_class,
151 "method"=>$method,
152 );
153 $temp_s=array(
154 "class"=>$s_class,
155 "method"=>$method,
156 );
157 if(