//界说笼统类'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();
}
在这类情形中,以下面一行所显示的:
Fatal error: Call to a member function on a non-object in
path/to/file
怎样?这就是对传递到生成器类的对象的类型不停止反省的直接处分!因而在编写你的剧本时必定要记住这个成绩。幸亏,还有一个复杂的计划来处理这些成绩,并且这也恰是"instanceof"操作符的威力地点。假如你想要看一下这个操作符是若何利用的,请持续往下读吧。