PHP强制对象类型之instanceof操作符
对象
一、简介
在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"操作符的威力所在。如果你想要看一下这个操作符是如何使用的,请继续往下读吧。
[1] [2] 下一页

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Function means function. It is a reusable code block with specific functions. It is one of the basic components of a program. It can accept input parameters, perform specific operations, and return results. Its purpose is to encapsulate a reusable block of code. code to improve code reusability and maintainability.

How to use Attributes to manage code annotations in PHP8? With the release of PHP8, an exciting new feature was introduced, namely Attributes. Attributes is a method of code annotation that allows us to add metadata to classes, methods, and attributes in a structured way. In this article, we will explore how to use Attributes to manage code annotations in PHP8 and provide some specific code examples. 1. What is Attrib?

Detailed explanation of the role and function of the MySQL.proc table. MySQL is a popular relational database management system. When developers use MySQL, they often involve the creation and management of stored procedures (StoredProcedure). The MySQL.proc table is a very important system table. It stores information related to all stored procedures in the database, including the name, definition, parameters, etc. of the stored procedures. In this article, we will explain in detail the role and functionality of the MySQL.proc table

In this article, we will learn about enumerate() function and the purpose of “enumerate()” function in Python. What is the enumerate() function? Python's enumerate() function accepts a data collection as a parameter and returns an enumeration object. Enumeration objects are returned as key-value pairs. The key is the index corresponding to each item, and the value is the items. Syntax enumerate(iterable,start) Parameters iterable - The passed in data collection can be returned as an enumeration object, called iterablestart - As the name suggests, the starting index of the enumeration object is defined by start. if we ignore

How to use Attributes to add custom annotations to classes in PHP8? Custom annotations are a way to add metadata to a class or method, which can help us obtain and process additional information on a specific class or method at runtime. In PHP8, the concept of Attributes was introduced, which allows us to easily add custom annotations to classes. This article will introduce how to use Attributes to implement custom annotations for classes in PHP8 and provide specific code examples. In PHP8, since

Front-end output configuration requires specific code examples. In front-end development, output configuration is a very important configuration. It is used to define the file path, file name and related resource paths generated after the project is packaged. This article will introduce the role of front-end output configuration, common configuration options, and give specific code examples. The role of output configuration: The output configuration item is used to specify the file path and file name generated after the project is packaged. It determines the final output of the project. Packaged in webpack etc.

Usage and Function of Vue.use Function Vue is a popular front-end framework that provides many useful features and functions. One of them is the Vue.use function, which allows us to use plugins in Vue applications. This article will introduce the usage and function of the Vue.use function and provide some code examples. The basic usage of the Vue.use function is very simple, just call it before Vue is instantiated, passing in the plugin you want to use as a parameter. Here is a simple example: //Introduce and use the plug-in

The file_exists method checks whether a file or directory exists. It accepts as argument the path of the file or directory to be checked. Here's what it's used for - it's useful when you need to know if a file exists before processing it. This way, when creating a new file, you can use this function to know if the file already exists. Syntax file_exists($file_path) Parameters file_path - Set the path of the file or directory to be checked for existence. Required. Return file_exists() method returns. Returns TrueFalse if the file or directory exists, if the file or directory does not exist Example let us see a check for "candidate.txt" file and even if the file
