The instanceof operator of PHP forced object type. Read the instanceof operator of PHP forced object type. 1. it may be very important to implement forced object type in PHP. If it is missing, or because it lacks this knowledge-based on incorrect programming assumptions, or just because of laziness, then you will see "> <LINKhref =" http: // w in a specific Web application
I. INTRODUCTION
It is sometimes important to implement a forced object type in PHP. If it is missing, or because it lacks this knowledge-based on incorrect programming assumptions, or just because of laziness, then you will see the desired results in a specific Web application. Especially when programming with PHP 4, it is very easy to use the "is_a ()" function (although there are other methods) to verify the type of the object you are using. There is no doubt that the forced object type can also be used to filter input objects (it needs to be passed as a parameter to other PHP classes in the same application ).
However, PHP 4 does not expose some weaknesses in its object model-it may occasionally require additional code to implement features that appear in mature object-oriented languages. This fact has been well known to the PHP community for a long time. However, with the release of PHP 5, many of these extremely valuable features are added as part of an improved object model. They will help you develop object-based code more closely-allowing you to use specific object features.
In the preceding case, pay special attention to object type forcing. In fact, during the execution of a Web application, PHP 5 provides developers with at least two methods to check the object type-they are the "instanceof" operator and the "type prompt" feature. Now go to the topic of this article. I will introduce the use of the "instanceof" operator in PHP 5. You will soon find that, it is very convenient to determine whether the object you are using belongs to a specific type.
This article uses some object-oriented examples to help you understand how to implement forced object types in PHP 5.
2. what should you do?
To demonstrate how to enforce object type in PHP 5, I will use the (X) HTML widget class and a simple page generator class, and made a simple modification to fit the PHP 5 development environment.
My first example lists some (X) HTML widget classes derived from an abstract base class "HTMLElement". it skips the check of their input object types. Take a look at the following classes:
// Define the abstract class 'htmlelement'
Abstract class HTMLElement {
Protected $ attributes;
Protected function _ construct ($ attributes ){
If (! Is_array ($ attributes )){
Throw new Exception ('invalidattribute type ');
}
$ This-> attributes = $ attributes;
}
// The abstract 'gethtml () 'method
Abstract protected function getHTML ();
}
// Define a specific class 'div '-extended HTMLElement
Class Div extends HTMLElement {
Private $ output = '<div ';
Private $ data;
Public function _ construct ($ attributes = array (), $ data ){
Parent: :__ construct ($ attributes );
$ This-> data = $ data;
}
// Specific implementation of the 'gethtml () 'method
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;
}
}
// Define the specific class 'header1'-extended HTMLElement
Class Header1 extends HTMLElement {
Private $ output = '
Private $ data;
Public function _ construct ($ attributes = array (), $ data ){
Parent: :__ construct ($ attributes );
$ This-> data = $ data;
}
// Specific implementation of the 'gethtml () 'method
Public function getHTML (){
Foreach ($ this-> attributes as $ attribute => $ value ){
$ This-> output. = $ attribute. '= "'. $ value .'"';
}
$ This-> output = substr_replace ($ this-> output, '>',-1 );
$ This-> output. = $ this-> data. 'Return $ this-> output;
}
}
// Define a specific class 'paragraph'-extended HTMLElement
Class Paragraph extends HTMLElement {
Private $ output = '<p ';
Private $ data;
Public function _ construct ($ attributes = array (), $ data ){
Parent: :__ construct ($ attributes );
$ This-> data = $ data;
}
// Specific implementation of the 'gethtml () 'method
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;
}
}
// Define the specific class 'unorderedlist'-extended 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 ('invalidparameter for list items ');
}
$ This-> items = $ items;
}
// Specific implementation of the 'gethtml () 'method
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;
}
}
As you can see, the above (X) HTML widget class is very useful when generating a specific element in the network, but I intentionally write the code of each class as this, in this way, they cannot verify the validity of the input parameters. You may have thought that the input parameter will be passed directly to the class constructor and assigned a value as an attribute. The problem arises: is there any error in doing so? Yes, yes. Now, I will define my simplest page generator class and use such widgets to populate it, in this way, you can see how the input of this class is mixed with incorrect objects. The following is the signature of the page generator class:
Class PageGenerator {
Private $ output = '';
Private $ title;
Public function _ construct ($ title = "Default Page "){
$ This-> title = $ title;
}
Public function doHeader (){
$ This-> output = '> Title. '</title> }
Public function addHTMLElement ($ htmlElement ){
$ This-> output. = $ htmlElement-> getHTML ();
}
Public function doFooter (){
$ This-> output. = '</body> }
Public function fetchHTML (){
Return $ this-> output;
}
}
Now, we start to instantiate some (X) HTML widget objects and pass them to the corresponding generator class, as shown in the following example:
Try {
// Generate some HTML elements
$ 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 '));
// Instantiate the page generator class
$ PageGen = new Page generator ();
$ PageGen-> doHeader ();
// Add the 'htmlelement 'object
$ PageGen-> addHTMLElement ($ h1 );
$ PageGen-> addHTMLElement ($ div );
$ PageGen-> addHTMLElement ($ par );
$ PageGen-> addHTMLElement ($ ul );
$ PageGen-> doFooter ();
// Display the network surface
Echo $ pageGen-> fetchHTML ();
}
Catch (Exception $ e ){
Echo $ e-> getMessage ();
Exit ();
}
After running the above PHP code, you get a simple webpage-it contains some previously created (X) HTML objects. In this case, if for some reason the web builder class receives an incorrect object and calls its "addHTML ()" method, you can easily understand what will happen. Here, I modified the conflict condition here-by using a nonexistent (X) HTML widget object. Please refer to the following code again:
Try {
// Generate some HTML elements
$ 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 '));
// Instantiate the page generator class
$ PageGen = new Page generator ();
$ PageGen-> doHeader ();
// Add the 'htmlelement 'object
$ PageGen-> addHTMLElement ($ fakeobj) // transmits nonexistent objects
To this method
$ PageGen-> addHTMLElement ($ div );
$ PageGen-> addHTMLElement ($ par );
$ PageGen-> addHTMLElement ($ ul );
$ PageGen-> doFooter ();
// Display the network surface
Echo $ pageGen-> fetchHTML ();
}
Catch (Exception $ e ){
Echo $ e-> getMessage ();
Exit ();
}
In this case, as shown in the following line:
$ PageGen-> addHTMLElement ($ fakeobj) // pass nonexistent objects to this method
An existing (X) HTML widget object is passed to the page generator class, which leads to a fatal error:
Fatal error: Call to a member function on a non-object in
Path/to/file
How is it? This is the direct punishment for not checking the type of objects passed to the generator class! Therefore, remember this question when writing your script. Fortunately, there is a simple solution to solve these problems, and this is also the power of the "instanceof" operator. If you want to see how this operator is used, continue reading it.
3. use the "instanceof" operator
As you can see, the "instanceof" operator is very simple to use. it uses two parameters to complete its functions. The first parameter is the object you want to check, and the second parameter is the class name (actually an interface name), used to determine whether the object is an instance of the corresponding class. Of course, I intentionally used the above term so that you can see how intuitive this operator is. Its basic syntax is as follows:
If (object instanceof class name ){
// Do something useful
}
Now that you know how this operator is used in PHP 5, to verify the type of the object passed to its "addHTMLElement ()" method, let's define the corresponding web page generator class. The following is a new signature for this class. As I mentioned earlier, it uses the "instanceof" operator:
Class PageGenerator {
Private $ output = '';
Private $ title;
Public function _ construct ($ title = "Default Page "){
$ This-> title = $ title;
}
Public function doHeader (){
$ This-> output = '}
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> }
Public function fetchHTML (){
Return $ this-> output;
}
}
Note that in the above class, to determine that all the objects passed are instances of the "HTMLElement" class defined earlier, how is the "instanceof" operator included in "addHTMLElement () "method. Now, it is possible to re-build the web page you see before. in this case, make sure that all input objects passed to the web page builder class are real (X) HTML widget objects. The following is an example:
Try {
// Generate some HTML elements
$ H1 = new Header1 (array ('name' => 'header1', 'class' => 'headerclass'), 'content for H1 element goes here ');
$ Div = new Div (array ('name' => 'did1', 'class' => 'didclass'), '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 ';
// Instantiate the page generator class
$ PageGen = new Page generator ();
$ PageGen-> doHeader ();
// Add the 'htmlelement 'object
$ PageGen-> addHTMLElement ($ teststr) // pass a simple string to this method
$ PageGen-> addHTMLElement ($ h1 );
$ PageGen-> addHTMLElement ($ div );
$ PageGen-> addHTMLElement ($ par );
$ PageGen-> doFooter ();
// Display the webpage
Echo $ pageGen-> fetchHTML ();
}
Catch (Exception $ e ){
Echo $ e-> getMessage ();
Exit ();
}
As you can see in the above example, I pass a simple test string (not an "HTMLElement" object) to the page generator class, which will be passed through addHTMLElement () "method throws an exception-caught by a specific" catch "block, as shown below:
Invalid (X) HTML element
In this case, I use the "instanceof" operator to determine the validity of the input object. in this way, the above web page builder class can be converted into some more effective code snippets. I hope you can truly understand the extreme importance of filtering input of methods of your class by using this operator, so that you can avoid external incorrect data input.
After displaying the correct implementation of the "instanceof" operator in the webpage generator class, there are more to be done. Similar to the (X) HTML widget class I wrote for PHP 4 in the previous article, I want to include this operator as part of their "getHTML ()" method, in this way, you can create webpages that generate nested (X) HTML elements. Next, let's discuss how this works.
IV. extended use of the "instanceof" operator: Nested (X) HTML widget
Okay. You have seen that the "instanceof" operator has good functions in checking the type of input objects directly injected into the page generator class. Now, I will further add a check routine to the constructor of the (X) HTML widget class and the "getHTML ()" method, in this way, other widgets can be used as input parameters. Check the following improved classes:
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 ('invalidparameter type ');
}
Parent: :__ construct ($ attributes );
$ This-> data = $ data;
}
// Specific implementation of the 'gethtml () 'method
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 = '
Private $ data;
Public function _ construct ($ attributes = array (), $ data ){
If (! $ Data instanceof HTMLElement &&! Is_string ($ data )){
Throw new Exception ('invalidparameter type ');
}
Parent: :__ construct ($ attributes );
$ This-> data = $ data;
}
// Specific implementation of the 'gethtml () 'method
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. = '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 ('invalidparameter type ');
}
Parent: :__ construct ($ attributes );
$ This-> data = $ data;
}
// Specific implementation of the 'gethtml () 'method
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 ('invalidparameter for list items ');
}
$ This-> items = $ items;
}
// Specific implementation of the 'gethtml () 'method
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 class, in order to allow nested (X) HTML elements to be implemented when a corresponding webpage is generated, I reconstructed their constructors and the "getHTML ()" methods respectively. Note that the constructor of each class contains the following condition blocks:
If (! $ Data instanceof HTMLElement &&! Is_string ($ data )){
Throw new Exception ('invalidparameter type ');
}
So far, what I actually do is ensure that only string data and "HTMLElement" type objects can be used as input parameters for each class. Otherwise, an exception is thrown by the respective methods, which may cause the application to stop running. Therefore, this is the process of checking the input data. Now, let's take a look at the new signature of the "getHTML ()" method. The "instanceof" operator is also used:
$ This-> output. = ($ this-> data instanceof HTMLElement )? $ This-> data-
> GetHTML (): $ this-> data;
As you can see, in this case, this operator is very useful in exploiting the polymorphism features of the (X) HTML widget class. If the $ data attribute is also a widget, its "getHTML ()" method will be called correctly, resulting in displaying nested web page elements. On the other hand, if it is only a string, it is directly added to all the outputs of the current class.
So far, to ensure that some objects belong to a specific type, you may have understood the usage of the "instanceof" operator in PHP 5. As you have seen in this article, it is quite straightforward to force the object type in PHP 5. Now, you 'd better develop an example that uses this method to filter objects in your PHP application to deepen your understanding.
V. Summary
In this article, you learned how to use the "instanceof" operator in PHP 5 to check the type of your input object. However, the method I show you is not unique. In the next article, I will explain how to implement the "type prompt" feature in PHP 5, which is another way to enforce the object type.
Author: Zhu Xianzhong compilation Source: Tianji development