linux社区爱心援助Linux认证系列教程业界动态站务新闻公司招聘建议留言网址大全LPI专题CISCO专题
设为首页
加入收藏
管理团队
JSP  
JAVA  
PERL  
 您的位置:首页 > 开发语言 > php >
栏目导栏
  php
  JSP
  ASP
  asp.net
  JAVA
  c/c++/c#
  perl
  JavaScript
  Basic
  Delphi
资料搜索
热门文章
·PHP生成静态页面的一些经验
·PHP无限分类与树型论坛的实现方
·php5学习笔记
·入门级PHP程序员面试题
·PHP 和 MySQL初学入门
·PHP入门速成
·vim的代码折叠
·文件下载统计php编程代码
·如何建立自己的新闻发布系统
·织梦CMS中文转换拼音函数研究
·Windows下Apache+Tomcat+MySQL
·PHP初学者头疼问题总结
·Cookie及其使用详细介绍
·生成sessionid和随机密码的例子
·使用无限生命期Session的方法
最新文章
·PHP入门速成
·用php实现广告轮播
·Zend Optimizer 问题浅析
·功能强大的CGI语言----PHP3
·用Session对Web页面进行保护
·PHP--进行模块化设计
·如何将PHP的结果输出到非PHP页
·如何开发一个虚拟域名系统
·PHP4调用自己编写的COM组件
·简单的页面缓冲技术(三)
·简单的页面缓冲技术(二)
·简单的页面缓冲技术(一)
·用Socket发送电子邮件(二)
·用Socket发送电子邮件(一)
·PHP/MySQL 购物车
Google
 
PHP强制对象类型之instanceof操作符(1)
[ 作者:  加入时间:2008-02-14 12:45:19  来自:Linux联盟收集整理 ]
一、简介 tELLinux联盟
   tELLinux联盟
    在PHP中实现强制对象类型有时可能非常重要。如果缺少了它,或是因为缺乏这方面的知识——基于不正确的编程假设,或者仅仅是由于懒惰,那么你会在特定的Web应用程序中看到你所不希望的结果。特别是当用PHP 4进行编程时,使用"is_a()"函数(尽管还有其它方法)来验证你所使用的对象的类型是非常容易的事情。毫无疑问,强制对象类型还可以被用于过滤输入对象(需要被作为参数传递到同一个应用程序中的其它PHP类)。 tELLinux联盟
   tELLinux联盟
    不过,PHP 4并没有暴露一些有关于它的对象模型的弱点-为了实现某些在成熟的面向对象的语言中出现的特征,它偶而可能要求编写另外的代码。长时间以来,这一事实已经为PHP社区众所周知。然而,随着PHP 5的发行,许多这些极有价值的特征作为改进的对象模型的一部分被添加到其中。它们将有助于更为紧密地实现基于对象的代码的开发-允许你使用特定的对象特征。 tELLinux联盟
   tELLinux联盟
    在上面的情况下,当涉及到对象类型强制时应该特别注意。实际上,在一个Web应用程序的执行期间,PHP 5提供给开发者至少两种方法来检查对象类型——它们分别是“instanceof”操作符和“类型提示”特征。现在转到本文的主题,我将介绍PHP 5中"instanceof"操作符的使用;你很快就会发现,它可以非常方便地用来确定是否你正在使用的对象属于一个特定的类型。 tELLinux联盟
   tELLinux联盟
    本文将通过一些面向对象的示例来帮助你理解如何在PHP 5中实现强制对象类型。 tELLinux联盟
   tELLinux联盟
    二、 你不该做什么 tELLinux联盟
   tELLinux联盟
    为了展示在PHP 5中如何实现对象类型强制,我将使用(X)HTML widget类,还有一个简单的页面生成器类,并作了简单的修改以适合PHP 5开发环境。 tELLinux联盟
   tELLinux联盟
    我的第一个示例列举了一些派生自一个抽象的基类"HTMLElement"的(X)HTML widget类,它跳过了到它们的输入对象类型的检查。请先看下面的类: tELLinux联盟
   tELLinux联盟
  //定义抽象类'HTMLElement' tELLinux联盟
  abstract class HTMLElement{ tELLinux联盟
   protected $attributes; tELLinux联盟
   protected function __construct($attributes){ tELLinux联盟
    if(!is_array($attributes)){ tELLinux联盟
     throw new Exception('Invalid attribute type'); tELLinux联盟
    } tELLinux联盟
    $this->attributes=$attributes; tELLinux联盟
   } tELLinux联盟
   // 抽象的'getHTML()'方法 tELLinux联盟
   abstract protected function getHTML(); tELLinux联盟
  } tELLinux联盟
  //定义具体的类'Div'-扩展HTMLElement tELLinux联盟
  class Div extends HTMLElement{ tELLinux联盟
   private $output='<div '; tELLinux联盟
   private $data; tELLinux联盟
   public function __construct($attributes=array(),$data){ tELLinux联盟
    parent::__construct($attributes); tELLinux联盟
    $this->data=$data; tELLinux联盟
   } tELLinux联盟
   //'getHTML()'方法的具体实现 tELLinux联盟
   public function getHTML(){ tELLinux联盟
    foreach($this->attributes as $attribute=>$value){ tELLinux联盟
     $this->output.=$attribute.'="'.$value.'" '; tELLinux联盟
    } tELLinux联盟
    $this->output=substr_replace($this->output,'>',-1); tELLinux联盟
    $this->output.=$this->data.'</div>'; tELLinux联盟
    return $this->output; tELLinux联盟
   } tELLinux联盟
  } tELLinux联盟
  //定义具体类'Header1'-扩展HTMLElement tELLinux联盟
  class Header1 extends HTMLElement{ tELLinux联盟
   private $output='<h1 '; tELLinux联盟
   private $data; tELLinux联盟
   public function __construct($attributes=array(),$data){ tELLinux联盟
    parent::__construct($attributes); tELLinux联盟
    $this->data=$data; tELLinux联盟
   } tELLinux联盟
   //'getHTML()'方法的具体的实现 tELLinux联盟
   public function getHTML(){ tELLinux联盟
    foreach($this->attributes as $attribute=>$value){ tELLinux联盟
     $this->output.=$attribute.'="'.$value.'" '; tELLinux联盟
    } tELLinux联盟
    $this->output=substr_replace($this->output,'>',-1); tELLinux联盟
    $this->output.=$this->data.'</h1>'; tELLinux联盟
    return $this->output; tELLinux联盟
   } tELLinux联盟
  } tELLinux联盟
  //定义具体类'Paragraph'-扩展HTMLElement tELLinux联盟
  class Paragraph extends HTMLElement{ tELLinux联盟
   private $output='<p '; tELLinux联盟
   private $data; tELLinux联盟
   public function __construct($attributes=array(),$data){ tELLinux联盟
    parent::__construct($attributes); tELLinux联盟
    $this->data=$data; tELLinux联盟
   } tELLinux联盟
   //'getHTML()'方法的具体实现 tELLinux联盟
   public function getHTML(){ tELLinux联盟
    foreach($this->attributes as $attribute=>$value){ tELLinux联盟
    $this->output.=$attribute.'="'.$value.'" '; tELLinux联盟
   } tELLinux联盟
   $this->output=substr_replace($this->output,'>',-1); tELLinux联盟
   $this->output.=$this->data.'</p>'; tELLinux联盟
   return $this->output; tELLinux联盟
  } tELLinux联盟
  } tELLinux联盟
  //定义具体类'UnorderedList'-扩展HTMLElement tELLinux联盟
  class UnorderedList extends HTMLElement{ tELLinux联盟
   private $output='<ul '; tELLinux联盟
   private $items=array(); tELLinux联盟
   public function __construct($attributes=array(),$items=array()){ tELLinux联盟
    parent::__construct($attributes); tELLinux联盟
    if(!is_array($items)){ tELLinux联盟
     throw new Exception('Invalid parameter for list items'); tELLinux联盟
    } tELLinux联盟
    $this->items=$items; tELLinux联盟
   } tELLinux联盟
   //'getHTML()'方法的具体实现 tELLinux联盟
   public function getHTML(){ tELLinux联盟
    foreach($this->attributes as $attribute=>$value){ tELLinux联盟
     $this->output.=$attribute.'="'.$value.'" '; tELLinux联盟
    } tELLinux联盟
    $this->output=substr_replace($this->output,'>',-1); tELLinux联盟
    foreach($this->items as $item){ tELLinux联盟
     $this->output.='<li>'.$item.'</li>'; tELLinux联盟
    }  tELLinux联盟
    $this->output.='</ul>'; tELLinux联盟
    return $this->output; tELLinux联盟
   } tELLinux联盟
  } tELLinux联盟
   tELLinux联盟
    如你所见,上面的(X)HTML widget类在生成一个网面中特定的元素时是非常有用的,但是我有意地把每一个类的代码写成这样,这样它们就不能够验证输入参数的有效性。你可能已经想到,输入参数将直接被传递到类构造器中并且作为属性赋值。问题出现了:这样做有什么错误吗?是的,有。现在,我将定义我的最简单的页面生成器类,并且用这样一些widget来填充(feed)它,这样你就可以看到这个类的输入是如何与不正确的对象相混杂。下面是该页面生成器类的签名: tELLinux联盟
   tELLinux联盟
  class PageGenerator{ tELLinux联盟
   private $output=''; tELLinux联盟
   private $title; tELLinux联盟
   public function __construct($title='Default Page'){ tELLinux联盟
    $this->title=$title; tELLinux联盟
   } tELLinux联盟
   public function doHeader(){ tELLinux联盟
    $this->output='<html><head><title>'.$this- tELLinux联盟
    >title.'</title></head><body>'; tELLinux联盟
   } tELLinux联盟
   public function addHTMLElement($htmlElement){ tELLinux联盟
    $this->output.=$htmlElement->getHTML(); tELLinux联盟
   } tELLinux联盟
   public function doFooter(){ tELLinux联盟
    $this->output.='</body></html>'; tELLinux联盟
   } tELLinux联盟
   public function fetchHTML(){ tELLinux联盟
    return $this->output; tELLinux联盟
   } tELLinux联盟
  } tELLinux联盟
   tELLinux联盟
    现在,我们开始实例化一些(X)HTML widget对象,并且把它们传递到相应的生成器类,如下面的示例所示: tELLinux联盟
   tELLinux联盟
  try{ tELLinux联盟
   //生成一些HTML元素 tELLinux联盟
   $h1=new Header1(array('name'=>'header1','class'=>'headerclass'),'Content for H1 tELLinux联盟
  element goes here'); tELLinux联盟
   $div=new Div(array('name'=>'div1','class'=>'diVClass'),'Content for Div element tELLinux联盟
  goes here'); tELLinux联盟
   $par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraph tELLinux联盟
  element goes here'); tELLinux联盟
   $ul=new UnorderedList(array ('name'=>'list1','class'=>'listclass'),array tELLinux联盟
  ('item1'=>'value1','item2'=>'value2','item3'=>'value3')); tELLinux联盟
  //实例化页面生成器类 tELLinux联盟
   $pageGen=new Page生成器(); tELLinux联盟
   $pageGen->doHeader(); tELLinux联盟
   // 添加'HTMLElement'对象 tELLinux联盟
   $pageGen->addHTMLElement($h1); tELLinux联盟
   $pageGen->addHTMLElement($div); tELLinux联盟
   $pageGen->addHTMLElement($par); tELLinux联盟
   $pageGen->addHTMLElement($ul); tELLinux联盟
   $pageGen->doFooter(); tELLinux联盟
   //显示网面 tELLinux联盟
   echo $pageGen->fetchHTML(); tELLinux联盟
  } tELLinux联盟
  catch(Exception $e){ tELLinux联盟
   echo $e->getMessage(); tELLinux联盟
   exit(); tELLinux联盟
  } tELLinux联盟
   tELLinux联盟
    在运行上面的PHP代码后,你所得到的结果是一个简单的网页-它包含一些前面创建的(X)HTML对象。这种情况下,如果因某些原因该网页生成器类收到一个不正确的对象并调用它的"addHTML()"方法,那么你很容易理解将会发生的事情。在此,我重新修改了这里的冲突条件-通过使用一个不存在的(X)HTML widget对象。请再次看一下下面的代码: tELLinux联盟
   tELLinux联盟
  try{ tELLinux联盟
   //生成一些HTML元素 tELLinux联盟
   $h1=new Header1(array('name'=>'header1','class'=>'headerclass'),'Content for H1 tELLinux联盟
  element goes here'); tELLinux联盟
   $div=new Div(array('name'=>'div1','class'=>'divclass'),'Content for Div element tELLinux联盟
  goes here'); tELLinux联盟
   $par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraph tELLinux联盟
  element goes here'); tELLinux联盟
   $ul=new UnorderedList(array ('name'=>'list1','class'=>'listclass'),array tELLinux联盟
  ('item1'=>'value1','item2'=>'value2','item3'=>'value3')); tELLinux联盟
   //实例化页面生成器类 tELLinux联盟
   $pageGen=new Page生成器(); tELLinux联盟
   $pageGen->doHeader(); tELLinux联盟
   //添加'HTMLElement'对象 tELLinux联盟
   $pageGen->addHTMLElement($fakeobj) //把并不存在的对象传递 tELLinux联盟
  到这个方法 tELLinux联盟
   $pageGen->addHTMLElement($div); tELLinux联盟
   $pageGen->addHTMLElement($par); tELLinux联盟
   $pageGen->addHTMLElement($ul); tELLinux联盟
   $pageGen->doFooter(); tELLinux联盟
   // 显示网面 tELLinux联盟
   echo $pageGen->fetchHTML(); tELLinux联盟
  } tELLinux联盟
  catch(Exception $e){ tELLinux联盟
   echo $e->getMessage(); tELLinux联盟
   exit(); tELLinux联盟
  } tELLinux联盟
   tELLinux联盟
    在这种情况中,如下面一行所显示的: tELLinux联盟
   tELLinux联盟
  $pageGen->addHTMLElement($fakeobj)//把不存在的对象传递到这个方法 tELLinux联盟
   tELLinux联盟
    一个并不存在的(X)HTML widget对象被传递到该页面生成器类,这样会导致一个致命性错误: tELLinux联盟
   tELLinux联盟
  Fatal error: Call to a member function on a non-object in tELLinux联盟
  path/to/file tELLinux联盟
   tELLinux联盟
    怎么样?这就是对传递到生成器类的对象的类型不进行检查的直接惩罚!因此在编写你的脚本时一定要记住这个问题。幸好,还有一个简单的方案来解决这些问题,而且这也正是"instanceof"操作符的威力所在。如果你想要看一下这个操作符是如何使用的,请继续往下读吧。 tELLinux联盟
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·让你的PHP引擎全速运转的三个绝招  (2008-02-13 14:25:01)
 ·理解PHP中的MVC编程之控制器  (2008-02-13 11:36:39)
 ·利用PHP编程防范XSS跨站脚本攻击  (2008-02-13 11:35:44)
 ·使用 PHP 5.0创建图形的巧妙方法(5)  (2008-02-13 11:31:15)
 ·使用 PHP 5.0创建图形的巧妙方法(4)  (2008-02-13 11:30:01)
 ·使用 PHP 5.0创建图形的巧妙方法(3)  (2008-02-13 11:26:43)
 ·使用 PHP 5.0创建图形的巧妙方法 (2)  (2008-02-13 11:25:14)
 ·使用 PHP 5.0创建图形的巧妙方法 (1)  (2008-02-13 11:23:14)
 ·PHP程序加速探索之代码优化  (2008-02-13 11:22:09)
 ·PHPUnit袖珍指南之PHPUnit的目的  (2008-02-13 11:21:25)