//定义抽象类'htmlelement' abstract class htmlelement{ protected $attributes; protected function __construct($attributes){ if(!is_array($attributes)){ throw new exception('invalid attribute type'); } $this->attributes=$attributes; } // 抽象的'gethtml()'方法 abstract protected function gethtml(); } //定义具体的类'div'-扩展htmlelement class div extends htmlelement{ private $output='<div '; private $data; public function __construct($attributes=array(),$data){ 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.'</div>'; return $this->output; } } //定义具体类'header1'-扩展htmlelement class header1 extends htmlelement{ private $output='<h1 '; private $data; public function __construct($attributes=array(),$data){ 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.'</h1>'; return $this->output; } } //定义具体类'paragraph'-扩展htmlelement class paragraph extends htmlelement{ private $output='<p '; private $data; public function __construct($attributes=array(),$data){ 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.'</p>'; return $this->output; } } //定义具体类'unorderedlist'-扩展htmlelement 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.='<li>'.$item.'</li>'; } $this->output.='</ul>'; return $this->output; } } 如你所见,上面的(x)html widget类在生成一个网面中特定的元素时是非常有用的,但是我有意地把每一个类的代码写成这样,这样它们就不能够验证输入参数的有效性。你可能已经想到,输入参数将直接被传递到类构造器中并且作为属性赋值。问题出现了:这样做有什么错误吗?是的,有。现在,我将定义我的最简单的页面生成器类,并且用这样一些widget来填充(feed)它,这样你就可以看到这个类的输入是如何与不正确的对象相混杂。下面是该页面生成器类的签名:
class pagegenerator{ private $output=''; private $title; public function __construct($title='default page'){ $this->title=$title; } public function doheader(){ $this->output='<html><head><title>'.$this- >title.'</title></head><body>'; } public function addhtmlelement($htmlelement){ $this->output.=$htmlelement->gethtml(); } public function dofooter(){ $this->output.='</body></html>'; } public function fetchhtml(){ return $this->output; } } 现在,我们开始实例化一些(x)html widget对象,并且把它们传递到相应的生成器类,如下面的示例所示:
try{ //生成一些html元素 $h1=new header1(array('name'=>'header1','class'=>'headerclass'),'content for h1 element goes here'); $div=new div(array('name'=>'div1','class'=>'divclass'),'content for div element goes here'); $par=new paragraph(array('name'=>'par1','class'=>'parclass'),'content for paragraph element goes here'); $ul=new unorderedlist(array ('name'=>'list1','class'=>'listclass'),array ('item1'=>'value1','item2'=>'value2','item3'=>'value3')); //实例化页面生成器类 $pagegen=new page生成器(); $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)html widget对象。请再次看一下下面的代码:
try{ //生成一些html元素 $h1=new header1(array('name'=>'header1','class'=>'headerclass'),'content for h1 element goes here'); $div=new div(array('name'=>'div1','class'=>'divclass'),'content for div element goes here'); $par=new paragraph(array('name'=>'par1','class'=>'parclass'),'content for paragraph element goes here'); $ul=new unorderedlist(array ('name'=>'list1','class'=>'listclass'),array ('item1'=>'value1','item2'=>'value2','item3'=>'value3')); //实例化页面生成器类 $pagegen=new page生成器(); $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(); } 在这种情况中,如下面一行所显示的: