分类:
2008-04-14 16:23:09
一、简介
在中实现强制类型有时可能非常重要。如果缺少了它,或是因为缺乏这方面的知识——基于不正确的编程假设,或者仅仅是由于懒惰,那么你会在特定的Web应用程序中看到你所不希望的结果。特别是当用PHP 4进行编程时,使用"is_a()"函数(尽管还有其它方法)来验证你所使用的对象的类型是非常容易的事情。毫无疑问,强制对象类型还可以被用于过滤输入对象(需要被作为参数传递到同一个应用程序中的其它PHP类)。
不过,PHP 4并没有暴露一些有关于它的对象模型的弱点-为了实现某些在成熟的面向对象的语言中出现的特征,它偶而可能要求编写另外的代码。长时间以来,这一事实已经为PHP社区众所周知。然而,随着PHP 5的发行,许多这些极有价值的特征作为改进的对象模型的一部分被添加到其中。它们将有助于更为紧密地实现基于对象的代码的开发-允许你使用特定的对象特征。
在上面的情况下,当涉及到对象类型强制时应该特别注意。实际上,在一个Web应用程序的执行期间,PHP 5提供给开发者至少两种方法来检查对象类型——它们分别是“instanceof”操作符和“类型提示”特征。现在转到本文的主题,我将介绍PHP 5中"instanceof"操作符的使用;你很快就会发现,它可以非常方便地用来确定是否你正在使用的对象属于一个特定的类型。
本文将通过一些面向对象的示例来帮助你理解如何在PHP 5中实现强制对象类型。
二、 你不该做什么
为了展示在PHP 5中如何实现对象类型强制,我将使用(X)HTML widget类,还有一个简单的页面生成器类,并作了简单的修改以适合PHP 5开发环境。
我的第一个示例列举了一些派生自一个抽象的基类"HTMLElement"的(X)HTML widget类,它跳过了到它们的输入对象类型的检查。请先看下面的类:
//定义抽象类'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; } } |
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; } } |
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(); } |
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(); } |
$pageGen->addHTMLElement($fakeobj)//把不存在的对象传递到这个方法 |
Fatal error: Call to a member function on a non-object in path/to/file |