|
√ Google adsense申请技巧 √ 本站核心代理域名注册主机业务
√ 快速发布你的买卖域名买卖网站信息
√ 1元注册 cn域名
√ 站长每日新闻导读 √ ·推荐万网空间¥120元 150m √ 站长网:站长必上的网站 √ 网站联盟大全 √ 本站代理万网域名55空间120元 |
 方法(Method)
PHP对方法的支持比较简单,没有太多可以讨论的。值得一提的是,PHP从版本5开始支持类的静态方法(static method),这使得程序员再也不用无谓地增加许多全局函数了。
 事件(Event)
事件也许是PHP遇到的最复杂的问题。PHP并没有在语法层面提供对事件的支持,我们只能考虑通过别的途径来实现。因此,我们需要先对事件的概念和其他语言对事件的实现方式进行讨论。
事件模型可以简述如下:充当事件触发者的代码本身并不处理事件,而仅仅是在事件发生时,把程序控制权转交给事件的处理者,在事件处理完成后,再收回控制权。事件触发者本身并不知道事件将会被如何处理,在大多数情况下,事件触发者的代码要先于事件处理者的代码被完成。
在传统的面向过程的语言(例如C或者PASCAL)中,事件可以通过函数指针来实现。具体来说,事件触发者定义一个函数指针,这个函数指针可以在以后被指向某个处理事件的函数。在事件发生时,调用该函数指针指向的处理函数,并将事件的上下文作为参数传入。处理完成后,控制权再回到事件触发者。
在面向对象的语言中,方法指针(指向某个类的方法的指针)取代了函数指针。以Delphi为例,事件处理的例子如下:
type
TNotifyEvent = procedure(Sender: TObject) of object;
TMainForm = class(TForm)
procedure ButtonClick(Sender: TObject);
…
End;
Var
MainForm: TMainForm;
OnClick: TNotifyEvent;
…
可以看出,TNotifyEvent被定义为所谓的过程类型(Procedural Type),事实上就是一个方法指针。TMainForm的ButtonClick方法是一个事件处理者,符合TNotifyEvent的签名。OnClick是一个事件触发者。在实际使用时,通过如下代码:
OnClick := MainForm.ButtonClick;
将MainForm.ButtonClick方法绑定到了OnClick事件。当OnClick事件触发时,MainForm.ButtonClick方法将被调用,并且将Sender(触发事件的组件对象)作为参数传入。
回到PHP,由于PHP不支持指针,因此无法使用函数指针这一技术。但是,PHP支持所谓的“函数变量”,可以把函数赋予某个变量,其作用类似于函数指针。如下例:
function EventHandler($Sender) {
echo "Calling EventHandler(), arv = $Sendern";
}
$Func = 'EventHandler';
$Func('Sender Name');
由于PHP是一种动态语言,变量可以为任何类型,所以无须先定义函数指针的类型作为事件的签名。直接定义了一个函数EventHandler作为事件处理者,然后将它赋予变量$Func(注意直接使用了字符串形式的函数名),最后触发该事件,并将一个字符串“Sender Name”传给它作为参数。输出的结果是:
Calling EventHandler(), arv = Sender Name
同样地,PHP也提供了类似方法指针的机制。如下例:
Class EventHandler {
public function DoEvent($Sender) {
echo "Calling EventHandler.DoEvent(), arg = $Sendern";
}
}
$EventHanler = new EventHandler();
$HandlerObject = $EventHanler;
$Method = 'DoEvent';
$HandlerObject->$Method('Sender Name');
由于PHP中没有能够直接引用对象方法的变量,因此需要使用两个变量来间接实现:$HandlerObject指向对象,$Method指向对象方法。通过$HandlerObject->$Method方式的调用,可以动态地指向任何对象方法。
为了使代码更加优雅和更适合复用,可以定义一个专门的类NotifyEvent,并使用一段新的调用代码:
final class NotifyEvent {
private $HandlerObject;
private $Method;
public function __construct($HandlerObject, $Method) {
$this->HandlerObject = $HandlerObject;
$this->Method = $Method;
}
public function Call($Sender) {
$Method = $this->Method;
$this->HandlerObject->$Method($Sender);
}
}
$EventHanler = new EventHandler();
$NotifyEvent = new NotifyEvent($EventHanler, 'DoEvent');
$NotifyEvent->Call('Sender Name');
NotifyEvent类定义了两个私有变量$HandlerObject和$Method,分别指向事件处理者对象和处理方法。在构造函数中对这两个变量赋值,再通过Call方法来调用。
熟悉C#的读者可以发现,NotifyEvent类与C#中的Delegate十分类似。Delegate超过NotifyEvent的地方在于支持多播(Multicast),也就是一个事件可以绑定多个事件处理者。只要事件触发者自己维护一个NotifyEvent对象数组,支持多播也不是一件难事。