instanceof操作符在被直接注入到页面生成器类的输入对象进行类型检查方面所表现出的良好功能。现在,再进一步来把一个检查例程添加到(x)html widget类的构造器和gethtml()方法中,这样它们可以接受其它的widget作为输入参数。请检查下面改进的类:
class div extends htmlelement{
 private $output='<div ';
 private $data;
 public function construct($attributes=array(),$data){
if(!$data instanceof htmlelement&&!is_string($data)){
 throw new exception('invalid parameter type');
}
parent::construct($attributes);
$this->data=$data;
 }
 //'gethtml()'方法的具体实现
 public function gethtml(){
foreach($this->attributes as $attribute=>$value){
 $this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=($this->data instanceof htmlelement)?
$this->data->gethtml():$this->data;
$this->output.='</div>';
return $this->output;
 }
}
class header1 extends htmlelement{
 private $output='<h1 ';
 private $data;
 public function construct($attributes=array(),$data){
if(!$data instanceof htmlelement&&!is_string($data)){
 throw new exception('invalid parameter type');
}
parent::construct($attributes);
$this->data=$data;
 }
 //'gethtml()'方法的具体实现
 public function gethtml(){
foreach($this->attributes as $attribute=>$value){
 $this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=($this->data instanceof htmlelement)?
$this->data->gethtml():$this->data;
$this->output.='</h1>';
return $this->output;
 }
}
class paragraph extends htmlelement{
 private $output='<p ';
 private $data;
 public function construct($attributes=array(),$data){
if(!$data instanceof htmlelement&&!is_string($data)){
 throw new exception('invalid parameter type');
}
parent::construct($attributes);
$this->data=$data;
 }
 //'gethtml()'方法的具体实现
 public function gethtml(){
foreach($this->attributes as $attribute=>$value){
 $this->output.=$attribute.'="'.$value.'" ';
}
$this->output=substr_replace($this->output,'>',-1);
$this->output.=($this->data instanceof htmlelement)?
$this->data->gethtml():$this->data;
$this->output.='</p>';
return $this->output;
 }
}
class unorderedlist extends htmlelement{
 private $output='<ul ';
 private $items=array();
 public function construct($attributes=array(),$items=array()){
parent::construct($attributes);
if(!is_array($items)){
 throw new exception('invalid parameter for list items');
 }
 $this->items=$items;
}
//'gethtml()'方法的具体实现
public function gethtml(){
 foreach($this->attributes as $attribute=>$value){
$this->output.=$attribute.'="'.$value.'" ';
 }
 $this->output=substr_replace($this->output,'>',-1);
 foreach($this->items as $item){
$this->output.=($item instanceof
htmlelement)?'<li>'.$item->gethtml().'</li>':'<li>'.$item.'</li>';
 }
 $this->output.='</ul>';
 return $this->output;
}
}
如上面的类所展示的,为了允许在生成相应的网页时实现嵌套的(x)html元素,分别重构了它们的构造器和"gethtml()"方法。请注意,在每一个类的构造器中包含了下面的条件块:
if(!$data instanceof htmlelement&&!is_string($data)){
throw new exception('invalid parameter type');
}
至此,实际做的是确保仅有字符串数据和"htmlelement"类型对象允许作为每一个类的输入参数。否则,将分别由各自方法抛出一个异常,并且有可能导致应用程序的停止执行。所以,这就是对输入数据的检查过程。现在,让我们看一下"gethtml()"方法的新的签名,其中也使用了"instanceof"操作符:
$this->output.=($this->data instanceof htmlelement)?$this->data-
>gethtml():$this->data;
如你所见,在这种情况下,对于利用(x)html widget类的多态性特征方面this操作符是非常有用的。如果$data属性也是一个widget,那么它的"gethtml()"方法将被正确调用,这会导致显示嵌套的网页元素。另一方面,如果它仅是一个字符串,那么它就被直接添加到当前类的所有输出上。
至此,为了确保某些对象属于一个特定的类型,你可能已经理解了php 5中"instanceof"操作符的用法。正如你在本文中所见,在php 5中强制对象类型其实是一个相当直接的工作。现在,你最好开发一个使用这个方法来过滤你的php应用程序中的对象的例子来加深自己的理解。
<?php
//定义一个抽像类htmlelement
abstract class htmlelement
{
    protected  $attributes;
    protected  function construct($_attributes)
    {
        if(!is_array($_attributes))
        {
           throw new exception("attributes not is array"); 
        }
        $this->attributes = $_attributes;
    }
    //定义一个虚函数
    abstract function gethtml();
}
 
 
//定义具体的类"div"扩展htmlelement
class div extends htmlelement
{
    private $_output = "<div";
    private $_data;
    public function construct($_attributes=array(), $data)
    {
        //扩展"instanceof"操作符的使用:嵌套(x)html widget
        if(!$data instanceof htmlelement && !is_string($data)) {
            throw new exception("data type error");
        }      
        parent::construct($_attributes);
        $this->_data = $data;
    }
    public function gethtml()
    {
        foreach ($this->attributes as $key=>$val)
        {
             $this->_output.=  " ".$key."='".$val."' ";
        }
        $this->_output =substr_replace($this->_output,">",-1);
        $this->_output .= $this->_data instanceof htmlelement ? $this->_data->gethtml()."</div>" : $this->_data."</div>";
        return $this->_output;
    }
}
 
//定义具体的类"h1"扩展
class h1 extends htmlelement
{
    private $_output="<h1";
    private $_data;
    public function construct($_attributes=array(), $data)
    {
        parent::construct($_attributes);
        $this->_data = $data;
    }
     
    public function gethtml()
    {
        foreach($this->attributes as $key=>$val)
        {
            $this->_output.=  " ".$key."='".$val."' ";
        }
        $this->_output = substr_replace($this->_output, ">", -1);
        $this->_output .= $this->_data."<h1>";
        return $this->_output;
    }
}
 
//定义具体的类"ul"
class ul extends htmlelement
{
    public $output = "<ul";
    private $ulitem=array();
    public function construct($_attributes=array(), $_ulitem=array())
    {  
        parent::construct($_attributes);
        $this->ulitem = $_ulitem;
    }
     
    public function gethtml()
    {
        foreach($this->attributes as $key=>$val)
        {
            $this->_output.=  " ".$key."='".$val."' ";
        }
        $this->output = substr_replace($this->output, ">",-1);
        foreach($this->ulitem as $ukey=>$uval){
            $this->output .="<li>".$uval."</li>";
        }
        $this->output.="</ul>";
        return $this->output;       
    }
}
 
 
//生成页面的类
class pagegenerator
{
    private $_output;
    private $_title;
    public function construct($title=" default page")
    {
        $this->_title = $title;
    }
     
    public function dohead()
    {
        $this->_output.="<html><head><title>".$this->_title."</title></head><body>";
    }
     
//  public function addhtmlelement($htmlelement)
//  {
//      $this->_output.= $htmlelement->gethtml();
//  }
    //对addhtmlelement进行改进
    //可以保证传入的不是htmlelement类对像直接报错
    public function addhtmlelement($htmlelement)
    {
         if(!$htmlelement instanceof htmlelement)
         {
            throw new exception('invalid (x)html element');
         }
         $this->_output.= $htmlelement->gethtml();
    }
 
    public function dofooter()
    {
        $this->_output.="</body></html>";
    }
     
    public function fetchhtml()
    {
        return $this->_output;
    }
}
 
try{   
    $attribute = array("class"=>"classname", "style"=>"color:#000");
    $h1 = new h1($attribute, "h1内容");
    $attribute = array("class"=>"classname", "style"=>"color:#000");
    $ul = new ul($attribute, array("li第一行内容","li第二行内容","li第三行内容"));
     
     
    $attribute = array("class"=>"classname", "style"=>"color:red");
    $div = new div($attribute, $ul);
    $page = new pagegenerator();
//  $str="我是个字符串";
//  $page->addhtmlelement($str);
    $page->addhtmlelement($h1);
    $page->addhtmlelement($div);
    //  $page->addhtmlelement($ul);
    echo $page->fetchhtml();    
}
catch(exception $e){
    echo $e->getmessage();
    die();
}
?>
以上就是php类型运算符"instanceof"操作符的扩展使用的详细内容。
   
 
   