- ·上一篇文章:PHPUnit袖珍指南之安装PHPUnit
- ·下一篇文章:在PHP中开发XML应用程序之基础篇
PHP强制对象类型之instanceof操作符
');
$par=newParagraph(array('name'=>'par1','class'=>'parclass'),'ContentforParagraph
elementgoeshere');
$ul=newUnorderedList(array('name'=>'list1','class'=>'listclass'),array
('item1'=>'value1','item2'=>'value2','item3'=>'value3'));
//实例化页面生成器类
$pageGen=newPage生成器();
$pageGen->doHeader();
//添加'HTMLElement'对象
$pageGen->addHTMLElement($h1);
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->addHTMLElement($ul);
$pageGen->doFooter();
//显示网面
echo$pageGen->fetchHTML();
}
catch(Exception$e){
echo$e->getMessage();
exit();
}
在运行上面的PHP代码后,你所得到的结果是一个简单的网页-它包含一些前面创建的(X)HTML对象。这种情况下,如果因某些原因该网页生成器类收到一个不正确的对象并调用它的"addHTML()"方法,那么你很容易理解将会发生的事情。在此,我重新修改了这里的冲突条件-通过使用一个不存在的(X)HTMLwidget对象。请再次看一下下面的代码:
try{
//生成一些HTML元素
$h1=newHeader1(array('name'=>'header1','class'=>'headerclass'),'ContentforH1
elementgoeshere');
$div=newDiv(array('name'=>'div1','class'=>'divclass'),'ContentforDivelement
goeshere');
$par=newParagraph(array('name'=>'par1','class'=>'parclass'),'ContentforParagraph
elementgoeshere');
$ul=newUnorderedList(array('name'=>'list1','class'=>'listclass'),array
('item1'=>'value1','item2'=>'value2','item3'=>'value3'));
//实例化页面生成器类
$pageGen=newPage生成器();
$pageGen->doHeader();
//添加'HTMLElement'对象
$pageGen->addHTMLElement($fakeobj)//把并不存在的对象传递
到这个方法
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->addHTMLElement($ul);
$pageGen->doFooter();
//显示网面
echo$pageGen->fetchHTML();
}
catch(Exception$e){
echo$e->getMessage();
exit();
}
在这种情况中,如下面一行所显示的:
$pageGen->addHTMLElement($fakeobj)//把不存在的对象传递到这个方法
一个并不存在的(X)HTMLwidget对象被传递到该页面生成器类,这样会导致一个致命性错误:
Fatalerror:Calltoamemberfunctionalign=centerbgColor=#e3e3e3border=1> if(objectinstanceofclassname){
//做一些有用的事情
}
现在,既然你已经了解了这个操作符在PHP5是如何使用的,那么,为了验证被传递到它的"addHTMLElement()"方法的对象的类型,让我们再定义相应的网页生成器类。下面是这个类的新的签名,我在前面已经提到,它使用了"instanceof"操作符:
classPageGenerator{
private$output='';
private$title;
publicfunction__construct($title='DefaultPage'){
$this->title=$title;
}
publicfunctiondoHeader(){
$this->output='<html><head><title>'.$this->title.'</title></head><body>';
}
publicfunctionaddHTMLElement($htmlElement){
if(!$htmlElementinstanceofHTMLElement){
thrownewException('Invalid(X)HTMLelement');
}
$this->output.=$htmlElement->getHTML();
}
publicfunctiondoFooter(){
$this->output.='</body></html>';
}
publicfunctionfetchHTML(){
return$this->output;
}
}
请注意,在上面的类中,为了确定所有传递的对象是早些时候定义的"HTMLElement"类的实例,"instanceof"操作符是如何包含在"addHTMLElement()"方法中的。现在,有可能重新构建你前面看到的网页,在这种情况下,请确保所有的传递到该网页生成器类的输入对象都是真正的(X)HTMLwidget对象。下面是相应示例:
try{
//生成一些HTML元素
$h1=newHeader1(array('name'=>'header1','class'=>'headerclass'),'ContentforH1elementgoeshere');
$div=newDiv(array('name'=>'div1','class'=>'divclass'),'ContentforDivelementgoeshere');
$par=newParagraph(array('name'=>'par1','class'=>'parclass'),'ContentforParagraphelementgoeshere');
$teststr='ThisisnotaHTMLelement';
//实例化页面生成器类
$pageGen=newPage生成器();
$pageGen->doHeader();
//添加'HTMLElement'对象
$pageGen->addHTMLElement($teststr)//把简单的字符串传递到这个方法
$pageGen->addHTMLElement($h1);
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->doFooter();
//显示网页
echo$pageGen->fetchHTML();
}
catch(Exception$e){
echo$e->getMessage();
exit();
}
正如你在上面的示例已经看到的,我把一个简单的测试用字符串(并不是一个"HTMLElement"对象)传递到该页面生成器类中,这将通过addHTMLElement()"方法抛出一个异常-为特定的"catch"块所捕获,如下所示:
Invalid(X)HTMLelement
好。你已经看到了"instanceof"操作符在被直接注入到页面生成器类的输入对象进行类型检查方面所表现出的良好功能。现在,我将再进一步来把一个检查例程添加到(X)HTMLwidget类的构造器和"getHTML()"方法中,这样它们可以接受其它的widget作为输入参数。请检查下面改进的类:
classDivextendsHTMLElement{
private$output='<div';
private$data;
publicfunction__construct($attributes=array(),$data){
if(!$datainstanceofHTMLElement&&!is_string($data)){
thrownewException(
$par=newParagraph(array('name'=>'par1','class'=>'parclass'),'ContentforParagraph
elementgoeshere');
$ul=newUnorderedList(array('name'=>'list1','class'=>'listclass'),array
('item1'=>'value1','item2'=>'value2','item3'=>'value3'));
//实例化页面生成器类
$pageGen=newPage生成器();
$pageGen->doHeader();
//添加'HTMLElement'对象
$pageGen->addHTMLElement($h1);
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->addHTMLElement($ul);
$pageGen->doFooter();
//显示网面
echo$pageGen->fetchHTML();
}
catch(Exception$e){
echo$e->getMessage();
exit();
}
在运行上面的PHP代码后,你所得到的结果是一个简单的网页-它包含一些前面创建的(X)HTML对象。这种情况下,如果因某些原因该网页生成器类收到一个不正确的对象并调用它的"addHTML()"方法,那么你很容易理解将会发生的事情。在此,我重新修改了这里的冲突条件-通过使用一个不存在的(X)HTMLwidget对象。请再次看一下下面的代码:
//生成一些HTML元素
$h1=newHeader1(array('name'=>'header1','class'=>'headerclass'),'ContentforH1
elementgoeshere');
$div=newDiv(array('name'=>'div1','class'=>'divclass'),'ContentforDivelement
goeshere');
$par=newParagraph(array('name'=>'par1','class'=>'parclass'),'ContentforParagraph
elementgoeshere');
$ul=newUnorderedList(array('name'=>'list1','class'=>'listclass'),array
('item1'=>'value1','item2'=>'value2','item3'=>'value3'));
//实例化页面生成器类
$pageGen=newPage生成器();
$pageGen->doHeader();
//添加'HTMLElement'对象
$pageGen->addHTMLElement($fakeobj)//把并不存在的对象传递
到这个方法
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->addHTMLElement($ul);
$pageGen->doFooter();
//显示网面
echo$pageGen->fetchHTML();
}
catch(Exception$e){
echo$e->getMessage();
exit();
}
在这种情况中,如下面一行所显示的:
一个并不存在的(X)HTMLwidget对象被传递到该页面生成器类,这样会导致一个致命性错误:
//做一些有用的事情
}
现在,既然你已经了解了这个操作符在PHP5是如何使用的,那么,为了验证被传递到它的"addHTMLElement()"方法的对象的类型,让我们再定义相应的网页生成器类。下面是这个类的新的签名,我在前面已经提到,它使用了"instanceof"操作符:
private$output='';
private$title;
publicfunction__construct($title='DefaultPage'){
$this->title=$title;
}
publicfunctiondoHeader(){
$this->output='<html><head><title>'.$this->title.'</title></head><body>';
}
publicfunctionaddHTMLElement($htmlElement){
if(!$htmlElementinstanceofHTMLElement){
thrownewException('Invalid(X)HTMLelement');
}
$this->output.=$htmlElement->getHTML();
}
publicfunctiondoFooter(){
$this->output.='</body></html>';
}
publicfunctionfetchHTML(){
return$this->output;
}
}
请注意,在上面的类中,为了确定所有传递的对象是早些时候定义的"HTMLElement"类的实例,"instanceof"操作符是如何包含在"addHTMLElement()"方法中的。现在,有可能重新构建你前面看到的网页,在这种情况下,请确保所有的传递到该网页生成器类的输入对象都是真正的(X)HTMLwidget对象。下面是相应示例:
//生成一些HTML元素
$h1=newHeader1(array('name'=>'header1','class'=>'headerclass'),'ContentforH1elementgoeshere');
$div=newDiv(array('name'=>'div1','class'=>'divclass'),'ContentforDivelementgoeshere');
$par=newParagraph(array('name'=>'par1','class'=>'parclass'),'ContentforParagraphelementgoeshere');
$teststr='ThisisnotaHTMLelement';
//实例化页面生成器类
$pageGen=newPage生成器();
$pageGen->doHeader();
//添加'HTMLElement'对象
$pageGen->addHTMLElement($teststr)//把简单的字符串传递到这个方法
$pageGen->addHTMLElement($h1);
$pageGen->addHTMLElement($div);
$pageGen->addHTMLElement($par);
$pageGen->doFooter();
//显示网页
echo$pageGen->fetchHTML();
}
catch(Exception$e){
echo$e->getMessage();
exit();
}
正如你在上面的示例已经看到的,我把一个简单的测试用字符串(并不是一个"HTMLElement"对象)传递到该页面生成器类中,这将通过addHTMLElement()"方法抛出一个异常-为特定的"catch"块所捕获,如下所示:
此时,为了确定输入对象的有效性,我使用了"instanceof"操作符,这样以来,可以把上面的网页生成器类转换成一部分更为有效的代码片断。我希望你能真正体会到,通过使用这个操作符,对你的类的方法的输入进行过滤的极端重要性,这样就可以免除外来的不正确的数据输入。
在展示了"instanceof"操作符在网页生成器类内的正确实现后,还有更多的事情要做。类似于我在前面一篇文章中为PHP4所编写的(X)HTMLwidget类,我想包含这个操作符作为它们的"getHTML()"方法的一部分,这样就可以允许创建生成嵌套的(X)HTML元素的网页。下面,让我们讨论这是如何实现的。
好。你已经看到了"instanceof"操作符在被直接注入到页面生成器类的输入对象进行类型检查方面所表现出的良好功能。现在,我将再进一步来把一个检查例程添加到(X)HTMLwidget类的构造器和"getHTML()"方法中,这样它们可以接受其它的widget作为输入参数。请检查下面改进的类:
private$output='<div';
private$data;
publicfunction__construct($attributes=array(),$data){
if(!$datainstanceofHTMLElement&&!is_string($data)){
thrownewException(
