电信主站 网通分站
购买流程 付款方式 常见问题 在线提问 续租服务 购物车
用户名: 密 码: 忘记密码?
首 页
域名注册
虚拟主机
双线主机
服务器租用
VPS主机
企业邮局
代理专区
客服中心
虚拟主机行业资讯 虚拟主机评测对比 互联网最新动态 技术学院 站长资讯 在线教程 网站运营
搜索优化 服务器 网络编程 图形图象 站长之家 网页制作 操作系统
冲浪宝典 软件教学 视频通信 办公软件 邮件系统 网络安全 认证考试
您当前位置:西部数码->资讯中心-> 冲浪宝典-> 联络聊天
php强制对象类型之instanceof操作符_php技巧
作者:网友供稿 点击:0
  西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!虚拟主机可在线rar解压,自动数据恢复设置虚拟目录等.虚拟主机免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金!
文章页数:[1] 

  一、简介

  在PHP中实现强制对象类型有时可能非常重要。如果缺少了它,或是因为缺乏这方面的知识——基于不正确的编程假设,或者仅仅是由于懒惰,那么你会在特定的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;
 }
}

  如你所见,上面的(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();
}

  在这种情况中,如下面一行所显示的:

$pageGen->addHTMLElement($fakeobj)//把不存在的对象传递到这个方法

  一个并不存在的(X)HTML widget对象被传递到该页面生成器类,这样会导致一个致命性错误:

Fatal error: Call to a member function on a non-object in
path/to/file

  怎么样?这就是对传递到生成器类的对象的类型不进行检查的直接惩罚!因此在编写你的脚本时一定要记住这个问题。幸好,还有一个简单的方案来解决这些问题,而且这也正是"instanceof"操作符的威力所在。如果你想要看一下这个操作符是如何使用的,请继续往下读吧。

  三、 使用"instanceof"操作符

  如你所见,"instanceof"操作符的使用非常简单,它用两个参数来完成其功能。第一个参数是你想要检查的对象,第二个参数是类名(事实上是一个接口名),用于确定是否这个对象是相应类的一个实例。当然,我故意使用了上面的术语,这样你就可以看到这个操作符的使用是多么直观。它的基本语法如下:

if (object instanceof class name){
 //做一些有用的事情
}

  现在,既然你已经了解了这个操作符在PHP 5是如何使用的,那么,为了验证被传递到它的"addHTMLElement()"方法的对象的类型,让我们再定义相应的网页生成器类。下面是这个类的新的签名,我在前面已经提到,它使用了"instanceof"操作符:

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){
  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;
 }
}

  请注意,在上面的类中,为了确定所有传递的对象是早些时候定义的"HTMLElement"类的实例,"instanceof"操作符是如何包含在"addHTMLElement()"方法中的。现在,有可能重新构建你前面看到的网页,在这种情况下,请确保所有的传递到该网页生成器类的输入对象都是真正的(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);
 $teststr=This is not a HTML element;
 //实例化页面生成器类
 $pageGen=new Page生成器();
 $pageGen->doHeader();
 //添加HTMLElement对象
 $pageGen->addHTMLElement($teststr) //把简单的字符串传递到这个方法
 $pageGen->addHTMLElement($h1);
 $pageGen->addHTMLElement($div);
 $pageGen->addHTMLElement($par);
 $pageGen->doFooter();
 //显示网页
 echo $pageGen->fetchHTML();
}
catch(Exception $e){
 echo $e->getMessage();
 exit();
}

  正如你在上面的示例已经看到的,我把一个简单的测试用字符串(并不是一个"HTMLElement"对象)传递到该页面生成器类中,这将通过addHTMLElement()"方法抛出一个异常-为特定的"catch"块所捕获,如下所示:

Invalid (X)HTML element

  此时,为了确定输入对象的有效性,我使用了"instanceof"操作符,这样以来,可以把上面的网页生成器类转换成一部分更为有效的代码片断。我希望你能真正体会到,通过使用这个操作符,对你的类的方法的输入进行过滤的极端重要性,这样就可以免除外来的不正确的数据输入。

  在展示了"instanceof"操作符在网页生成器类内的正确实现后,还有更多的事情要做。类似于我在前面一篇文章中为PHP 4所编写的(X)HTML widget类,我想包含这个操作符作为它们的"getHTML()"方法的一部分,这样就可以允许创建生成嵌套的(X)HTML元素的网页。下面,让我们讨论这是如何实现的。

  四、 扩展"instanceof"操作符的使用:嵌套(X)HTML widget

  好。你已经看到了"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 5中的"instanceof"操作符来检查你的输入对象的类型;然而,我所向你展示的方法不是唯一的。在后面的一篇中,我将向你解释怎样实现PHP 5中的良好的"类型提示"特征,这是实现强制对象类型的另外一种方法。

作者:朱先忠编译出处:天极开发


文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
相关主题
文章页数:[1] 
Google
热门文章
·photoshop绘制五颜六色的圣诞彩灯_photoshop教程
·数码照片的photoshop清晰化处理漫谈_photoshop教程
·internet上的文件操作_autocad教程
·矩形阵列、圆角和倒角命令的使用_autocad教程
·php强制对象类型之instanceof操作符_php技巧
·另类玩法 打造个性化的windows xp声音_windows xp
·无敌进程终结法 鲜为人知的进程秘籍两招_windows xp
·ge在有线电视宽带城域网中的应用_视频通信
·教你用photoshop打造美丽龙纹玉佩_photoshop教程
·vb实现按钮浮动效果_visualbasic教程

最新文章
· 网站赚钱秘密
·导航的没落,Web2.0新时代谁将备受青睐?
·做网站是“体力活”?还是“脑力活”?
·不能病毒营销 有道如何占领搜索市场
·文件存储网站BIBIDU发起德与法签名活动
·雅虎邮箱:整合的野心有多大
·专家:08年将成iPhone攻击年 腾讯QQ仍很危险
·Google网络存储空间将达50G 比希捷更赚钱
·Google提示新浪博客含有恶意软件 原因尚不清楚
·微软的Office红旗还能扛多久?


 
 


版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
  打印  刷新  关闭
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 虚拟主机 | 资讯中心 | 友情链接 | 网站地图

版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2006 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86262244 86263048 86263408 86263960 86264018 86267838
售前咨询:总机转201 202 203 204 206 208
售后服务:总机转211 212 213 214
财务咨询:总机转224 223 传真:028-86264041 财务QQ:点击发送消息给对方635483282
售前咨询QQ:点击发送消息给对方2182518 点击发送消息给对方241975952 点击发送消息给对方275026793 点击发送消息给对方408235859
售后服务QQ:点击发送消息给对方17708515 点击发送消息给对方307742704 点击发送消息给对方287976517 点击发送消息给对方363783715
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号