The "instanceof" operator performs well in type-checking input objects that are injected directly into the page's generator class. Now, let's go one step further and add a check routine to the constructor and "getHTML()" method of the (X)HTML widget class so that they can accept other widgets as input parameters. Please check out the improved classes below:
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; } }
As shown in the above classes, each was refactored in order to allow nested (X)HTML elements to be implemented when generating the corresponding web page. Their constructor and "getHTML()" method. Please note that the following conditional block is included in the constructor of each class:
if(!$data instanceof HTMLElement&&!is_string($data)){ throw new Exception('Invalid parameter type'); }
At this point, what is actually done is to ensure that only string data and "HTMLElement" type objects are allowed as each Input parameters of the class. Otherwise, an exception will be thrown by the respective method and may cause the application to stop executing. So, this is the process of checking the input data. Now, let's look at the new signature of the "getHTML()" method, which also uses the "instanceof" operator:
$this->output.=($this->data instanceof HTMLElement)?$this->data- >getHTML():$this->data;
As you can see, in this case, for the exploit This operator is very useful in terms of the polymorphic nature of the (X)HTML widget class. If the $data attribute is also a widget, then its "getHTML()" method will be called correctly, which will cause the nested web element to be displayed. On the other hand, if it is just a string, then it is added directly to all outputs of the current class.
At this point, in order to ensure that certain objects belong to a specific type, you may have understood the usage of the "instanceof" operator in PHP 5. As you can see in this article, coercing object types in PHP 5 is actually a fairly straightforward task. For now, you'd better develop an example of using this method to filter objects in your PHP application to deepen your understanding.
<?php //定义一个抽像类HTMLElement abstract class HTMLElement { protected $attributes; protected function construct($_attributes) { if(!is_array($_attributes)) { throw new Exception("attributes not is array"); } $this->attributes = $_attributes; } //定义一个虚函数 abstract function getHTML(); } //定义具体的类"Div"扩展HTMLElement class Div extends HTMLElement { private $_output = "<div"; private $_data; public function construct($_attributes=array(), $data) { //扩展"instanceof"操作符的使用:嵌套(X)HTML widget if(!$data instanceof HTMLElement && !is_string($data)) { throw new Exception("data type error"); } parent::construct($_attributes); $this->_data = $data; } public function getHTML() { foreach ($this->attributes as $key=>$val) { $this->_output.= " ".$key."='".$val."' "; } $this->_output =substr_replace($this->_output,">",-1); $this->_output .= $this->_data instanceof HTMLElement ? $this->_data->getHTML()."</div>" : $this->_data."</div>"; return $this->_output; } } //定义具体的类"H1"扩展 class h1 extends HTMLElement { private $_output="<h1"; private $_data; public function construct($_attributes=array(), $data) { parent::construct($_attributes); $this->_data = $data; } public function getHTML() { foreach($this->attributes as $key=>$val) { $this->_output.= " ".$key."='".$val."' "; } $this->_output = substr_replace($this->_output, ">", -1); $this->_output .= $this->_data."<h1>"; return $this->_output; } } //定义具体的类"ul" class ul extends HTMLElement { public $output = "<ul"; private $ulitem=array(); public function construct($_attributes=array(), $_ulitem=array()) { parent::construct($_attributes); $this->ulitem = $_ulitem; } public function getHTML() { foreach($this->attributes as $key=>$val) { $this->_output.= " ".$key."='".$val."' "; } $this->output = substr_replace($this->output, ">",-1); foreach($this->ulitem as $ukey=>$uval){ $this->output .="<li>".$uval."</li>"; } $this->output.="</ul>"; return $this->output; } } //生成页面的类 class PageGenerator { private $_output; private $_title; public function construct($title=" Default page") { $this->_title = $title; } public function doHead() { $this->_output.="<html><head><title>".$this->_title."</title></head><body>"; } // public function addHTMLElement($HTMLElement) // { // $this->_output.= $HTMLElement->getHTML(); // } //对addHTMLElement进行改进 //可以保证传入的不是HTMLElement类对像直接报错 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; } } try{ $attribute = array("class"=>"className", "style"=>"color:#000"); $h1 = new H1($attribute, "h1内容"); $attribute = array("class"=>"className", "style"=>"color:#000"); $ul = new ul($attribute, array("li第一行内容","li第二行内容","li第三行内容")); $attribute = array("class"=>"className", "style"=>"color:red"); $div = new Div($attribute, $ul); $page = new PageGenerator(); // $str="我是个字符串"; // $page->addHTMLElement($str); $page->addHTMLElement($h1); $page->addHTMLElement($div); // $page->addHTMLElement($ul); echo $page->fetchHTML(); } catch(Exception $e){ echo $e->getMessage(); die(); } ?>
The above is the detailed content of Extended use of PHP type operator 'instanceof' operator. For more information, please follow other related articles on the PHP Chinese website!