电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

PHP強制對象類型之instanceof操作符

瀏覽:115日期:2024-02-07 15:48:52

一、簡介

在PHP中實現強制對象類型有時可能非常重要。如果缺少了它,或是因為缺乏這方面的知識——基于不正確的編程假設,或者僅僅是由于懶惰,那么你會在特定的Web應用程序中看到你所不希望的結果。特別是當用PHP 4進行編程時,使用'is_a()'函數(盡管還有其它方法)來驗證你所使用的對象的類型是非常容易的事情。毫無疑問,強制對象類型還可以被用于過濾輸入對象(需要被作為參數傳遞到同一個應用程序中的其它PHP類)。

不過,PHP 4并沒有暴露一些有關于它的對象模型的弱點-為了實現某些在成熟的面向對象的語言中出現的特征,它偶而可能要求編寫另外的代碼。長時間以來,這一事實已經為PHP社區眾所周知。然而,隨著PHP 5的發行,許多這些極有價值的特征作為改進的對象模型的一部分被添加到其中。它們將有助于更為緊密地實現基于對象的代碼的開發-允許你使用特定的對象特征。

在上面的情況下,當涉及到對象類型強制時應該特別注意。實際上,在一個Web應用程序的執行期間,PHP 5提供給開發者至少兩種方法來檢查對象類型——它們分別是“instanceof”操作符和“類型提示”特征?,F在轉到本文的主題,我將介紹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'-擴展HTMLElementclass 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'-擴展HTMLElementclass 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'-擴展HTMLElementclass 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'-擴展HTMLElementclass 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類在生成一個網面中特定的元素時是非常有用的,但是我有意地把每一個類的代碼寫成這樣,這樣它們就不能夠驗證輸入參數的有效性。你可能已經想到,輸入參數將直接被傳遞到類構造器中并且作為屬性賦值。問題出現了:這樣做有什么錯誤嗎?是的,有?,F在,我將定義我的最簡單的頁面生成器類,并且用這樣一些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 H1element goes here'); $div=new Div(array('name'=>'div1','class'=>'divclass'),'Content for Div elementgoes here'); $par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraphelement 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 H1element goes here'); $div=new Div(array('name'=>'div1','class'=>'divclass'),'Content for Div elementgoes here'); $par=new Paragraph(array('name'=>'par1','class'=>'parclass'),'Content for Paragraphelement 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 inpath/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'操作符在被直接注入到頁面生成器類的輸入對象進行類型檢查方面所表現出的良好功能?,F在,我將再進一步來把一個檢查例程添加到(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 instanceofHTMLElement)?'<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'類型對象允許作為每一個類的輸入參數。否則,將分別由各自方法拋出一個異常,并且有可能導致應用程序的停止執行。所以,這就是對輸入數據的檢查過程?,F在,讓我們看一下'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中強制對象類型其實是一個相當直接的工作?,F在,你最好開發一個使用這個方法來過濾你的PHP應用程序中的對象的例子來加深自己的理解。

五、小結

在本文中,你學習了如何使用PHP 5中的'instanceof'操作符來檢查你的輸入對象的類型;然而,我所向你展示的方法不是唯一的。在后面的一篇中,我將向你解釋怎樣實現PHP 5中的良好的'類型提示'特征,這是實現強制對象類型的另外一種方法。

作者:朱先忠編譯出處:天極開發

標簽: PHP
主站蜘蛛池模板: 截齿|煤截齿|采煤机截齿|掘进机截齿|旋挖截齿-山东卓力截齿厂家报价 | 校园气象站_超声波气象站_农业气象站_雨量监测站_风途科技 | 礼仪庆典公司,礼仪策划公司,庆典公司,演出公司,演艺公司,年会酒会,生日寿宴,动工仪式,开工仪式,奠基典礼,商务会议,竣工落成,乔迁揭牌,签约启动-东莞市开门红文化传媒有限公司 | 深圳市源和塑胶电子有限公司-首页| 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 企业微信scrm管理系统_客户关系管理平台_私域流量运营工具_CRM、ERP、OA软件-腾辉网络 | 盘式曝气器-微孔曝气器-管式曝气器-曝气盘-斜管填料 | 郑州市前程水处理有限公司 | 中医中药治疗血小板减少-石家庄血液病肿瘤门诊部 | 3D全息投影_地面互动投影_360度立体投影_水幕灯光秀 | 广东银虎 蜂窝块状沸石分子筛-吸附脱硫分子筛-萍乡市捷龙环保科技有限公司 | 贴板式电磁阀-不锈钢-气动上展式放料阀-上海弗雷西阀门有限公司 工业机械三维动画制作 环保设备原理三维演示动画 自动化装配产线三维动画制作公司-南京燃动数字 | 刺绳_刀片刺网_刺丝滚笼_不锈钢刺绳生产厂家_安平县浩荣金属丝网制品有限公司-安平县浩荣金属丝网制品有限公司 | PAS糖原染色-CBA流式多因子-明胶酶谱MMP-上海研谨生物科技有限公司 | 通信天线厂家_室分八木天线_对数周期天线_天线加工厂_林创天线源头厂家 | SDG吸附剂,SDG酸气吸附剂,干式酸性气体吸收剂生产厂家,超过20年生产使用经验。 - 富莱尔环保设备公司(原名天津市武清县环保设备厂) | 化工ERP软件_化工新材料ERP系统_化工新材料MES软件_MES系统-广东顺景软件科技有限公司 | 仪器仪表网 - 永久免费的b2b电子商务平台 | 依维柯自动挡房车,自行式国产改装房车,小型房车价格,中国十大房车品牌_南京拓锐斯特房车 - 南京拓锐斯特房车 | 全自动实验室洗瓶机,移液管|培养皿|进样瓶清洗机,清洗剂-广州摩特伟希尔机械设备有限责任公司 | 砍排机-锯骨机-冻肉切丁机-熟肉切片机-预制菜生产线一站式服务厂商 - 广州市祥九瑞盈机械设备有限公司 | 517瓜水果特产网|一个专注特产好物的网站 | 小型手持气象站-空气负氧离子监测站-多要素微气象传感器-山东天合环境科技有限公司 | led全彩屏-室内|学校|展厅|p3|户外|会议室|圆柱|p2.5LED显示屏-LED显示屏价格-LED互动地砖屏_蕙宇屏科技 | uv固化机-丝印uv机-工业烤箱-五金蚀刻机-分拣输送机 - 保定市丰辉机械设备制造有限公司 | 广州中央空调回收,二手中央空调回收,旧空调回收,制冷设备回收,冷气机组回收公司-广州益夫制冷设备回收公司 | Magnescale探规,Magnescale磁栅尺,Magnescale传感器,Magnescale测厚仪,Mitutoyo光栅尺,笔式位移传感器-苏州连达精密量仪有限公司 | 皮带机_移动皮带机_大倾角皮带机_皮带机厂家 - 新乡市国盛机械设备有限公司 | 立式_复合式_壁挂式智能化电伴热洗眼器-上海达傲洗眼器生产厂家 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 中空玻璃生产线,玻璃加工设备,全自动封胶线,铝条折弯机,双组份打胶机,丁基胶/卧式/立式全自动涂布机,玻璃设备-山东昌盛数控设备有限公司 | 卓能JOINTLEAN端子连接器厂家-专业提供PCB接线端子|轨道式端子|重载连接器|欧式连接器等电气连接产品和服务 | 聚合甘油__盐城市飞龙油脂有限公司| 金联宇电缆|广东金联宇电缆厂家_广东金联宇电缆实业有限公司 | 99文库_实习生实用的范文资料文库站| 噪声治理公司-噪音治理专业隔音降噪公司 | 精雕机-火花机-精雕机 cnc-高速精雕机-电火花机-广东鼎拓机械科技有限公司 | 钛合金标准件-钛合金螺丝-钛管件-钛合金棒-钛合金板-钛合金锻件-宝鸡远航钛业有限公司 | 无锡不干胶标签,卷筒标签,无锡瑞彩包装材料有限公司 | 扒渣机厂家_扒渣机价格_矿用扒渣机_铣挖机_撬毛台车_襄阳永力通扒渣机公司 | 纸塑分离机-纸塑分离清洗机设备-压力筛-碎浆机厂家金双联环保 | 闭端端子|弹簧螺式接线头|防水接线头|插线式接线头|端子台|电源线扣+护线套|印刷电路板型端子台|金笔电子代理商-上海拓胜电气有限公司 | 不锈钢散热器,冷却翅片管散热器厂家-无锡市烨晟化工装备科技有限公司 | 电机铸铝配件_汽车压铸铝合金件_发动机压铸件_青岛颖圣赫机械有限公司 |