色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

PHP強(qiáng)制對(duì)象類型之instanceof操作符

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

一、簡介

在PHP中實(shí)現(xiàn)強(qiáng)制對(duì)象類型有時(shí)可能非常重要。如果缺少了它,或是因?yàn)槿狈@方面的知識(shí)——基于不正確的編程假設(shè),或者僅僅是由于懶惰,那么你會(huì)在特定的Web應(yīng)用程序中看到你所不希望的結(jié)果。特別是當(dāng)用PHP 4進(jìn)行編程時(shí),使用'is_a()'函數(shù)(盡管還有其它方法)來驗(yàn)證你所使用的對(duì)象的類型是非常容易的事情。毫無疑問,強(qiáng)制對(duì)象類型還可以被用于過濾輸入對(duì)象(需要被作為參數(shù)傳遞到同一個(gè)應(yīng)用程序中的其它PHP類)。

不過,PHP 4并沒有暴露一些有關(guān)于它的對(duì)象模型的弱點(diǎn)-為了實(shí)現(xiàn)某些在成熟的面向?qū)ο蟮恼Z言中出現(xiàn)的特征,它偶而可能要求編寫另外的代碼。長時(shí)間以來,這一事實(shí)已經(jīng)為PHP社區(qū)眾所周知。然而,隨著PHP 5的發(fā)行,許多這些極有價(jià)值的特征作為改進(jìn)的對(duì)象模型的一部分被添加到其中。它們將有助于更為緊密地實(shí)現(xiàn)基于對(duì)象的代碼的開發(fā)-允許你使用特定的對(duì)象特征。

在上面的情況下,當(dāng)涉及到對(duì)象類型強(qiáng)制時(shí)應(yīng)該特別注意。實(shí)際上,在一個(gè)Web應(yīng)用程序的執(zhí)行期間,PHP 5提供給開發(fā)者至少兩種方法來檢查對(duì)象類型——它們分別是“instanceof”操作符和“類型提示”特征。現(xiàn)在轉(zhuǎn)到本文的主題,我將介紹PHP 5中'instanceof'操作符的使用;你很快就會(huì)發(fā)現(xiàn),它可以非常方便地用來確定是否你正在使用的對(duì)象屬于一個(gè)特定的類型。

本文將通過一些面向?qū)ο蟮氖纠齺韼椭憷斫馊绾卧赑HP 5中實(shí)現(xiàn)強(qiáng)制對(duì)象類型。

二、 你不該做什么

為了展示在PHP 5中如何實(shí)現(xiàn)對(duì)象類型強(qiáng)制,我將使用(X)HTML widget類,還有一個(gè)簡單的頁面生成器類,并作了簡單的修改以適合PHP 5開發(fā)環(huán)境。

我的第一個(gè)示例列舉了一些派生自一個(gè)抽象的基類'HTMLElement'的(X)HTML widget類,它跳過了到它們的輸入對(duì)象類型的檢查。請(qǐng)先看下面的類:

//定義抽象類'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'-擴(kuò)展HTMLElementclass Div extends HTMLElement{ private $output='<div '; private $data; public function __construct($attributes=array(),$data){parent::__construct($attributes);$this->data=$data; } //'getHTML()'方法的具體實(shí)現(xiàn) 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'-擴(kuò)展HTMLElementclass Header1 extends HTMLElement{ private $output='<h1 '; private $data; public function __construct($attributes=array(),$data){parent::__construct($attributes);$this->data=$data; } //'getHTML()'方法的具體的實(shí)現(xiàn) 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'-擴(kuò)展HTMLElementclass Paragraph extends HTMLElement{ private $output='<p '; private $data; public function __construct($attributes=array(),$data){parent::__construct($attributes);$this->data=$data; } //'getHTML()'方法的具體實(shí)現(xiàn) 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'-擴(kuò)展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()'方法的具體實(shí)現(xiàn) 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類在生成一個(gè)網(wǎng)面中特定的元素時(shí)是非常有用的,但是我有意地把每一個(gè)類的代碼寫成這樣,這樣它們就不能夠驗(yàn)證輸入?yún)?shù)的有效性。你可能已經(jīng)想到,輸入?yún)?shù)將直接被傳遞到類構(gòu)造器中并且作為屬性賦值。問題出現(xiàn)了:這樣做有什么錯(cuò)誤嗎?是的,有。現(xiàn)在,我將定義我的最簡單的頁面生成器類,并且用這樣一些widget來填充(feed)它,這樣你就可以看到這個(gè)類的輸入是如何與不正確的對(duì)象相混雜。下面是該頁面生成器類的簽名:

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

現(xiàn)在,我們開始實(shí)例化一些(X)HTML widget對(duì)象,并且把它們傳遞到相應(yīng)的生成器類,如下面的示例所示:

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'));//實(shí)例化頁面生成器類 $pageGen=new Page生成器(); $pageGen->doHeader(); // 添加'HTMLElement'對(duì)象 $pageGen->addHTMLElement($h1); $pageGen->addHTMLElement($div); $pageGen->addHTMLElement($par); $pageGen->addHTMLElement($ul); $pageGen->doFooter(); //顯示網(wǎng)面 echo $pageGen->fetchHTML();}catch(Exception $e){ echo $e->getMessage(); exit();}

在運(yùn)行上面的PHP代碼后,你所得到的結(jié)果是一個(gè)簡單的網(wǎng)頁-它包含一些前面創(chuàng)建的(X)HTML對(duì)象。這種情況下,如果因某些原因該網(wǎng)頁生成器類收到一個(gè)不正確的對(duì)象并調(diào)用它的'addHTML()'方法,那么你很容易理解將會(huì)發(fā)生的事情。在此,我重新修改了這里的沖突條件-通過使用一個(gè)不存在的(X)HTML widget對(duì)象。請(qǐng)?jiān)俅慰匆幌孪旅娴拇a:

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')); //實(shí)例化頁面生成器類 $pageGen=new Page生成器(); $pageGen->doHeader(); //添加'HTMLElement'對(duì)象 $pageGen->addHTMLElement($fakeobj) //把并不存在的對(duì)象傳遞到這個(gè)方法 $pageGen->addHTMLElement($div); $pageGen->addHTMLElement($par); $pageGen->addHTMLElement($ul); $pageGen->doFooter(); // 顯示網(wǎng)面 echo $pageGen->fetchHTML();}catch(Exception $e){ echo $e->getMessage(); exit();}

在這種情況中,如下面一行所顯示的:

$pageGen->addHTMLElement($fakeobj)//把不存在的對(duì)象傳遞到這個(gè)方法

一個(gè)并不存在的(X)HTML widget對(duì)象被傳遞到該頁面生成器類,這樣會(huì)導(dǎo)致一個(gè)致命性錯(cuò)誤:

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

怎么樣?這就是對(duì)傳遞到生成器類的對(duì)象的類型不進(jìn)行檢查的直接懲罰!因此在編寫你的腳本時(shí)一定要記住這個(gè)問題。幸好,還有一個(gè)簡單的方案來解決這些問題,而且這也正是'instanceof'操作符的威力所在。如果你想要看一下這個(gè)操作符是如何使用的,請(qǐng)繼續(xù)往下讀吧。

三、 使用'instanceof'操作符

如你所見,'instanceof'操作符的使用非常簡單,它用兩個(gè)參數(shù)來完成其功能。第一個(gè)參數(shù)是你想要檢查的對(duì)象,第二個(gè)參數(shù)是類名(事實(shí)上是一個(gè)接口名),用于確定是否這個(gè)對(duì)象是相應(yīng)類的一個(gè)實(shí)例。當(dāng)然,我故意使用了上面的術(shù)語,這樣你就可以看到這個(gè)操作符的使用是多么直觀。它的基本語法如下:

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

現(xiàn)在,既然你已經(jīng)了解了這個(gè)操作符在PHP 5是如何使用的,那么,為了驗(yàn)證被傳遞到它的'addHTMLElement()'方法的對(duì)象的類型,讓我們?cè)俣x相應(yīng)的網(wǎng)頁生成器類。下面是這個(gè)類的新的簽名,我在前面已經(jīng)提到,它使用了'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; }}

請(qǐng)注意,在上面的類中,為了確定所有傳遞的對(duì)象是早些時(shí)候定義的'HTMLElement'類的實(shí)例,'instanceof'操作符是如何包含在'addHTMLElement()'方法中的。現(xiàn)在,有可能重新構(gòu)建你前面看到的網(wǎng)頁,在這種情況下,請(qǐng)確保所有的傳遞到該網(wǎng)頁生成器類的輸入對(duì)象都是真正的(X)HTML widget對(duì)象。下面是相應(yīng)示例:

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'; //實(shí)例化頁面生成器類 $pageGen=new Page生成器(); $pageGen->doHeader(); //添加'HTMLElement'對(duì)象 $pageGen->addHTMLElement($teststr) //把簡單的字符串傳遞到這個(gè)方法 $pageGen->addHTMLElement($h1); $pageGen->addHTMLElement($div); $pageGen->addHTMLElement($par); $pageGen->doFooter(); //顯示網(wǎng)頁 echo $pageGen->fetchHTML();}catch(Exception $e){ echo $e->getMessage(); exit();}

正如你在上面的示例已經(jīng)看到的,我把一個(gè)簡單的測試用字符串(并不是一個(gè)'HTMLElement'對(duì)象)傳遞到該頁面生成器類中,這將通過addHTMLElement()'方法拋出一個(gè)異常-為特定的'catch'塊所捕獲,如下所示:

Invalid (X)HTML element

此時(shí),為了確定輸入對(duì)象的有效性,我使用了'instanceof'操作符,這樣以來,可以把上面的網(wǎng)頁生成器類轉(zhuǎn)換成一部分更為有效的代碼片斷。我希望你能真正體會(huì)到,通過使用這個(gè)操作符,對(duì)你的類的方法的輸入進(jìn)行過濾的極端重要性,這樣就可以免除外來的不正確的數(shù)據(jù)輸入。

在展示了'instanceof'操作符在網(wǎng)頁生成器類內(nèi)的正確實(shí)現(xiàn)后,還有更多的事情要做。類似于我在前面一篇文章中為PHP 4所編寫的(X)HTML widget類,我想包含這個(gè)操作符作為它們的'getHTML()'方法的一部分,這樣就可以允許創(chuàng)建生成嵌套的(X)HTML元素的網(wǎng)頁。下面,讓我們討論這是如何實(shí)現(xiàn)的。

四、 擴(kuò)展'instanceof'操作符的使用:嵌套(X)HTML widget

好。你已經(jīng)看到了'instanceof'操作符在被直接注入到頁面生成器類的輸入對(duì)象進(jìn)行類型檢查方面所表現(xiàn)出的良好功能。現(xiàn)在,我將再進(jìn)一步來把一個(gè)檢查例程添加到(X)HTML widget類的構(gòu)造器和'getHTML()'方法中,這樣它們可以接受其它的widget作為輸入?yún)?shù)。請(qǐng)檢查下面改進(jìn)的類:

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()'方法的具體實(shí)現(xiàn) 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()'方法的具體實(shí)現(xiàn) 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()'方法的具體實(shí)現(xiàn) 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()'方法的具體實(shí)現(xiàn)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;}}

如上面的類所展示的,為了允許在生成相應(yīng)的網(wǎng)頁時(shí)實(shí)現(xiàn)嵌套的(X)HTML元素,我分別重構(gòu)了它們的構(gòu)造器和'getHTML()'方法。請(qǐng)注意,我在每一個(gè)類的構(gòu)造器中包含了下面的條件塊:

if(!$data instanceof HTMLElement&&!is_string($data)){throw new Exception('Invalid parameter type');}

至此,我實(shí)際做的是確保僅有字符串?dāng)?shù)據(jù)和'HTMLElement'類型對(duì)象允許作為每一個(gè)類的輸入?yún)?shù)。否則,將分別由各自方法拋出一個(gè)異常,并且有可能導(dǎo)致應(yīng)用程序的停止執(zhí)行。所以,這就是對(duì)輸入數(shù)據(jù)的檢查過程。現(xiàn)在,讓我們看一下'getHTML()'方法的新的簽名,其中也使用了'instanceof'操作符:

$this->output.=($this->data instanceof HTMLElement)?$this->data->getHTML():$this->data;

如你所見,在這種情況下,對(duì)于利用(X)HTML widget類的多態(tài)性特征方面this操作符是非常有用的。如果$data屬性也是一個(gè)widget,那么它的'getHTML()'方法將被正確調(diào)用,這會(huì)導(dǎo)致顯示嵌套的網(wǎng)頁元素。另一方面,如果它僅是一個(gè)字符串,那么它就被直接添加到當(dāng)前類的所有輸出上。

至此,為了確保某些對(duì)象屬于一個(gè)特定的類型,你可能已經(jīng)理解了PHP 5中'instanceof'操作符的用法。正如你在本文中所見,在PHP 5中強(qiáng)制對(duì)象類型其實(shí)是一個(gè)相當(dāng)直接的工作。現(xiàn)在,你最好開發(fā)一個(gè)使用這個(gè)方法來過濾你的PHP應(yīng)用程序中的對(duì)象的例子來加深自己的理解。

五、小結(jié)

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

作者:朱先忠編譯出處:天極開發(fā)

標(biāo)簽: PHP
主站蜘蛛池模板: 日本加勒比高清一本大道 | 色爽爽爽爽爽爽爽爽 | 亚洲日本中文字幕在线 | 欧美日韩精品国产一区在线 | 一级做a爰片性色毛片视频图片 | 黄男人和女人色一级 | 色www亚洲 | 性欧美精品孕妇 | 国产一区日韩二区欧美三 | 香蕉久久久久久狠狠色 | 国产原创系列在线 | 男女在线免费视频 | 中文欧美一级强 | 国产午夜精品理论片小yo奈 | 国内精品久久久久影院不卡 | 国产精品免费视频一区二区三区 | 亚洲一级毛片欧美一级说乱 | 亚洲 欧美 日韩 在线 中文字幕 | 亚洲国产精品久久久久久网站 | 中国大陆一级毛片 | 久久久国产一区二区三区 | 亚洲精品一区最新 | 玖玖国产在线观看 | 韩国日本一级毛片免费视频 | 成人精品一区二区三区中文字幕 | 亚洲免费在线播放 | 看全色黄大色黄大片毛片 | 久久精品免视国产 | 亚洲人妖女同在线播放 | 亚洲悠悠色综合中文字幕 | 久久国产精品永久免费网站 | 久久久久久久久久免免费精品 | 国产精品亚洲片在线不卡 | 精品国产三级a在线观看 | 日美三级 | 国内精品一区二区2021在线 | 99r8这是只有精品视频9 | 手机在线国产精品 | 私人毛片免费高清影视院丶 | 美女的让男人桶到爽软件 | 一级视频在线免费观看 |