A detailed explanation of PHP's 16 magic methods

Source: Internet
Author: User
Tags export class numeric ming numeric value shallow copy

PHP is called the Magic Method (Magic methods), which starts with two underscores, and these methods play an important role in PHP. Magic methods include:

__construct (), constructor for class
__destruct (), Destructor of class
__call () Called when an inaccessible method is invoked in an object
__callstatic (), called when an inaccessible method is invoked in a static manner
__get (), which is called when a member variable of a class is obtained
__set (), which is called when a member variable of a class is set
__isset () Called when isset () or empty () is invoked on an inaccessible property.
__unset () Called when unset () is invoked on an inaccessible property.
__sleep (), when executing serialize (), this function is called first
__wakeup (), when executing unserialize (), this function is called first
__tostring (), the response method when a class is treated as a string
__invoke () The response method when calling an object in the way that a function is called
__set_state (), this static method is invoked when you call the Var_export () export class.
__clone () Called when the object copy completes
__autoload (), attempting to load an undefined class
__debuginfo (), printing the required debugging information
Example
Let us explain how to use these magic methods in the form of examples.

One, __construct (), constructor of class
The constructor method in PHP is the first method that is automatically invoked by an object after the object creation is completed. There is a construction method in each class, and if it is not shown, there is a default constructor in the class that has no parameters and is empty.

1, the role of the construction method

Typically, a constructed method is used to perform some useful initialization tasks, such as assigning an initial value to a member property when an object is created.

2, the declaration format of the constructor method in the class


function __constrct ([argument list]) {
Method body//is typically used to initialize a member property to an assignment
}
3. The matters needing attention in declaring the construction method in the class

1. Only one construction method can be declared in the same class, because PHP does not support constructor overloading.

2. The constructor method name is the __construct () that starts with a two bottom line.
Here is an example of it:

Class Person
{
Public $name;
Public $age;
Public $sex;

/**
* Display declares a construction method with parameters
*/
Public function __construct ($name = "", $sex = "Male", $age =22)
{
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}

/**
* Say method
*/
Public function Say ()
{
echo "My name is:". $this->name. ", Sex:". $this->sex. ", Age:". $this->age;
}

}
Create an object $person1 without any arguments

$Person 1 = new person ();
echo $Person 1->say (); Output: My name:, Sex: Male, Age: 27
Create object $person2 with parameter "Xiaoming"


$Person 2 = new Person ("xiaoming");
echo $Person 2->say (); Output: My name: John, Sex: Male, Age: 27
Create an object $person3 with three parameters

$Person 3 = new Person ("Dick", "male", 25);
echo $Person 3->say (); Output: My name: Dick, Sex: Male, Age: 25
Ii. __destruct (), Destructor of class
Through the above explanation, now we know what is called the construction method. Then the structure method corresponds to the Destructor method.

A destructor allows you to perform some operations or perform some functions before destroying a class, such as closing a file, releasing a result set, and so on.

The Deconstruction method is a new content introduced by PHP5.

The declarative format of the method is similar to that of the construction method __construct (), and is a method __destruct () that starts with a two underscore, which is also a fixed name.

1. Declaration format of the destructor method


function __destruct ()
{
Method body
}
Note: Destructors cannot have any arguments.

2, the role of the destructor method

In general, the destructor is not commonly used in PHP, which is an optional part of the class, and is usually used to accomplish some cleanup tasks before the object is destroyed.
Examples are shown below:


Class person{

Public $name;
Public $age;
Public $sex;

Public function __construct ($name = "", $sex = "Male", $age =22)
{
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}

/**
* Say speaking method
*/
Public function Say ()
{
echo "My Name:" $this->name. ", Sex:". $this->sex. ", Age:". $this->age;
}

/**
* Declaring a method of destructor
*/
Public Function __destruct ()
{
echo "I think I can salvage it again, my name is". $this->name;
}
}

$Person = new Person ("xiaoming");
Unset ($Person); Destroy the object created above $person
The above program runs with the output:

I think I can salvage it again, my name is Xiao Ming
Third, __call (), called when an inaccessible method is invoked in an object.
The method has two parameters, the first argument $function _name automatically receives the method name that does not exist, and the second $arguments receives multiple arguments of the method that do not exist as an array.
1, __call () method format:

1
2
3
4
function __call (string $function _name, array $arguments)
{
Method body
}
2, __call () The role of the method:

To avoid errors that occur when the invoked method does not exist, and unexpected causes the program to abort, you can use the __call () method to avoid it.

The method is invoked automatically when the method invoked does not exist, and the program continues to execute.
Please refer to the following code:


Class Person
{
function Say ()
{

echo "Hello, world!
";
}

/**
* Declares that this method is used to handle a method that does not exist in the calling object
*/
function __call ($funName, $arguments)
{
echo "The function you called:". $funName.  "(Parameter:"; The output call does not exist for a method name
Print_r ($arguments); Parameter list when the output calls a method that does not exist
echo ") does not exist!
\ n "; End Line Wrap
}
}
$Person = new Person ();
$Person->run ("Teacher"); Invokes a method that does not exist in the object, the __call () method in the object is automatically called
$Person->eat ("Xiaoming", "Apple");
$Person->say ();
Run Result:

The function you are calling: Run (parameter: Array ([0] => teacher)) does not exist!

The function you are calling: Eat (parameter: Array ([0] => xiaoming [1] => Apple)) does not exist!

Hello, world!.
This method is the same as the __call () feature described above except that the __callstatic () is prepared by an non-static method.

Take a look at the following code:


Class person
{
    function say ()
    {
 
  & nbsp;     echo "Hello, world!
";
   }
 
   /**
     * Declares that this method is used to handle methods that do not exist in the calling object
      */
    public static function __callstatic ($funName, $arguments)
    {
        echo "The static method you called:". $funName. "(Parameter:"; //Output calls a method name that does not exist
        Print_r ($arguments);//output parameter list when calling methods that do not exist
        Echo) does not exist!
\ n;//End Wrap
   }
}
$Person = new Person ();
$Person:: Run ("Teacher");//calling methods that do not exist in the object, then The __call () method
$Person:: Eat ("Xiaoming", "apple") is automatically invoked,
$Person->say (),
Run as follows:

The static method you invoked: run (parameter: Array ([0] => teacher)) does not exist!
The static method you call: Eat (parameter: Array ([0] => xiaoming [1] => Apple)) does not exist!
Hello, world!.
Five, __get (), when you get a member variable of a class, call
In PHP object-oriented programming, the member property of a class is set to private, and if we try to call it outside, there is a "no access to a private property" error. So in order to solve this problem, we can use Magic Method __get ().

The function of Magic Method __get ()
It allows you to get the value of a private member property outside of an object while the program is running.
Let's connect it further through the example of __get () below:


Class Person
{
Private $name;
Private $age;

function __construct ($name = "", $age =1)
{
$this->name = $name;
$this->age = $age;
}

/**
* Add the __get () method to the class, which is called once when the property value is obtained directly, and is passed in and processed as a parameter by the property name
* @param $propertyName
*
* @return int
*/
Public Function __get ($propertyName)
{
if ($propertyName = = "Age") {
if ($this->age > 30) {
return $this->age-10;
} else {
return $this-> $propertyName;
}
} else {
return $this-> $propertyName;
}
}
}
$Person = new Person ("Xiaoming", 60); An object that is instantiated from the person class and assigns an initial value to the property by constructing the method
echo "Name:". $Person->name. "
"; Direct access to private property name, automatically calls the __get () method to indirectly obtain
echo "Age:". $Person->age. "
"; The __get () method is automatically invoked, which returns different values depending on the object itself
Run Result:

Name: Xiao Ming
Age: 50
__set (), which is called when a member variable of a class is set
The role of __set ():
The __set ($property, $value) ' method is used to set the private property, and when assigning a value to an undefined property, the method is triggered and the passed parameter is the property name and value that is set.

Take a look at the following demo code:


Class Person
{
Private $name;
Private $age;

Public function __construct ($name = "", $age =25)
{
$this->name = $name;
$this->age = $age;
}

/**
* Declaring the Magic method requires two parameters, which are automatically invoked when assigning values to private properties, and can mask some illegal assignments
* @param $property
* @param $value
*/
Public Function __set ($property, $value) {
if ($property = = "Age")
{
if ($value > | | $value < 0) {
Return
}
}
$this-> $property = $value;
}

/**
* Declare the method of speaking in the class, and say all the private properties
*/
Public function say () {
echo "My Name" $this->name. ", this year". $this->age. " Years old ";
}
}

$Person =new person ("xiaoming", 25); Note that the initial value will be changed by the following
The __set () function is automatically invoked, the property name name is passed to the first argument, and the property value "Dick" is passed to the second argument
$Person->name = "Little Red"; The assignment was successful. If there is no __set (), an error occurs.
The __set () function is automatically invoked, passing the attribute name age to the first argument, passing the property value of 26 to the second argument
$Person->age = 16; Assignment succeeded
$Person->age = 160; 160 is an illegal value, the assignment is invalid
$Person->say (); Output: My name is Xiao Hong, 16 years old this year.
Run Result:

My name is Xiao Hong, 16 years old this year.
Vii. __isset () called when isset () or empty () is invoked on an inaccessible property.
Before we look at this method, let's look at the application of the Isset () function, Isset () is a function to determine whether a variable is set, pass in a variable as a parameter, return TRUE if the passed variable exists, or return false.

So if you use the Isset () function outside of an object to determine if the members of the object are set, can you use it?

In two cases, if the object inside the member is public, we can use this function to determine the member property, if it is a private member property, this function does not work, because the private is encapsulated, not visible outside. So we can't use the Isset () function outside the object to determine if the private member property is set? Of course it's OK, but it's not static. You just add a __isset () method to the class, and when you use the Isset () function outside the class to determine whether the private member inside the object is set, the __isset () method inside the class is automatically invoked to help us do so.

The role of __isset (): __isset () is invoked when isset () or empty () is invoked on an inaccessible property.
Please see the following code demo:


Class Person
{
Public $sex;
Private $name;
Private $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

/**
* @param $content
*
* @return BOOL
*/
Public Function __isset ($content) {
echo "When using the Isset () function to determine the private member {$content} outside the class, automatically invokes the
";
Echo isset ($this-> $content);
}
}

$person = new Person ("xiaoming", 25); Initial assignment
Echo isset ($person->sex), "
";
Echo isset ($person->name), "
";
Echo isset ($person->age), "
";
The results of the operation are as follows:

1//Public can be isset ()
When the private member name is measured outside the class using the Isset () function, the first echo in the automatic call//__isset ()
1//__isset () Second Echo
When the private member age is measured outside the class using the Isset () function, the first echo in the automatic call//__isset ()
1//__isset () Second Echo
__unset (), called when unset () is called on an inaccessible property.
Before we look at this method, let's take a look at the unset () function, unset () function is to delete the specified variable and return True, the argument is the variable to be deleted.

So what if you delete the member properties inside an object outside of an object with the unset () function?

Naturally, there are two situations:

1, if the member attribute inside an object is public, you can use this function to delete the public attribute of the object outside the object.

2, if the object's member property is private, I use this function does not have permission to delete.

Although there are two situations, I would like to say that if you add the __unset () method to an object, you can delete the object's private member properties outside of the object. After adding the __unset () method to the object, the object automatically calls the __unset () function to help us delete the private member properties inside the object by using the "unset ()" function outside the object to delete the private member properties inside the object.

Please see the following code:


Class Person
{
Public $sex;
Private $name;
Private $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

/**
* @param $content
*
* @return BOOL
*/
Public Function __unset ($content) {
Echo is invoked automatically when the unset () function is used outside of a class to delete a private member.
";
Echo isset ($this-> $content);
}
}

$person = new Person ("xiaoming", 25); Initial assignment
unset ($person->sex);
unset ($person->name);
unset ($person->age);
Run Result:

Called automatically when the unset () function is used outside of a class to delete a private member.
1 automatically invoked when the unset () function is used outside of a class to delete a private member
1
__sleep (), when executing serialize (), this function is called first
The serialize () function checks whether a magic method __sleep () exists in the class. If present, the method is called first and then the serialization operation is performed.

This feature can be used to clean up objects and return an array containing all the names of the variables that should be serialized in the object.

If the method does not return any content, NULL is serialized and a E_notice level error is generated.

Attention:

__sleep () cannot return the name of the private member of the parent class. Doing so will result in a E_notice level error. You can use the Serializable interface instead.
Role:

The __sleep () method is often used to submit uncommitted data, or similar cleanup operations. At the same time, if there are some large objects, but do not need to save all, this function is very useful.
Please refer to the following code:
Class Person
{
Public $sex;
Public $name;
Public $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

/**
* @return Array
*/
Public Function __sleep () {
Echo calls the __sleep () method here when using serialize () outside the class
";
$this->name = Base64_encode ($this->name);
Return Array (' name ', ' age '); This must return a numeric value, where the element represents the returned property name
}
}

$person = new Person (' xiaoming '); Initial assignment
Echo Serialize ($person);
Echo '
';
Code Run Results:

The __sleep () method here is invoked when serialize () is used outside the class
O:6: "Person": 2:{s:4: "Name", S:8: "5bcp5pio"; s:3: "Age"; i:25;
__wakeup (), when executing unserialize (), this function is called first
If __sleep () is white, then __wakeup () is black.

So why?

Because:

By contrast, ' unserialize () ' checks for the existence of a ' __wakeup () ' method. If present, the ' __wakeup ' method is called before the resource required by the object is prepared beforehand.
Role:

__wakeup () is often used in deserialization operations, such as the re-establishing a database connection, or performing other initialization operations.
Or look at the code:

Class Person
{
Public $sex;
Public $name;
Public $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

/**
* @return Array
*/
Public Function __sleep () {
Echo calls the __sleep () method here when using serialize () outside the class
";
$this->name = Base64_encode ($this->name);
Return Array (' name ', ' age '); This must return a numeric value, where the element represents the returned property name
}

/**
* __wakeup
*/
Public Function __wakeup () {
Echo calls the __wakeup () method here when using Unserialize () outside the class
";
$this->name = 2;
$this->sex = ' male ';
There is no need to return an array
}
}

$person = new Person (' xiaoming '); Initial assignment
Var_dump (Serialize ($person));
Var_dump (Unserialize (Serialize ($person)));
Run Result:

The __sleep () method here is invoked when serialize () is used outside the class
String (o:6): "Person": 2:{s:4: "Name"; S:8: "5bcp5pio", S:3: "Age; i:25;" The Serialize () method here is invoked when using __sleep () outside the class
The __wakeup () method here is invoked when Unserialize () is used outside the class
Object (person) #2 (3) {[Sex]=> string (3) ' Man ' [' Name ']=> int (2) [' Age ']=> int (25)}
Xi. __tostring (), the response method when a class is treated as a string
Role:

The __tostring () method is used to respond when a class is treated as a string. For example, ' echo $obj; ' What should be shown.
Attention:

This method must return a string, or it will emit a fatal error of ' E_recoverable_error ' level.
Warning:

You cannot throw an exception in the __tostring () method. Doing so can lead to fatal errors.
Code:

Class Person
{
Public $sex;
Public $name;
Public $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

Public Function __tostring ()
{
Return to ' go to go ';
}
}

$person = new Person (' xiaoming '); Initial assignment
Echo $person;
Results:

Go Go Go
So what happens if the Magic method runs without __tostring () in the class? Let's test the following:

Code:

Class Person
{
Public $sex;
Public $name;
Public $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

}

$person = new Person (' xiaoming '); Initial assignment
Echo $person;
Results:

Catchable fatal error:object of class person could not is converted to string into D:\phpStudy\WWW\test\index.php on line 1 8
Obviously, the page reported a fatal error, which is not allowed by the grammar.
12, __invoke (), call the function of the way to call an object when the response method
Role:

The __invoke () method is invoked automatically when an attempt is made to call an object in the form of a calling function.
Attention:

This feature is available only in PHP 5.3.0 and above.
Directly on the code:


Class Person
{
Public $sex;
Public $name;
Public $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

Public Function __invoke () {
Echo ' This is an object oh ';
}

}

$person = new Person (' xiaoming '); Initial assignment
$person ();
To view the results of a run:

It's an object.
Of course, if you are determined to use the object as a function method, you will get the following result:

1
Fatal error:function Name must is a string in D:\phpStudy\WWW\test\index.php on line 18
13, __set_state (), this static method is invoked when the Var_export () export class is invoked.
Role:

Since PHP 5.1.0, this static method is invoked automatically when the Var_export () export class is invoked.
Parameters:

The unique parameter of this method is an array that contains class attributes arranged by array (' property ' => value, ...).
Let's take a look at the code and the results of the run without adding __set_state ():

Code on:

Class Person
{
Public $sex;
Public $name;
Public $age;

Public function __construct ($name = "", $age =25, $sex = ' male ')
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}

}

$person = new Person (' xiaoming '); Initial assignment
Var_export ($person);
Look at the results:

Person::__set_state (' Sex ' => ' man ', ' name ' => ' xiaoming ', ' age ' => 25,))
Obviously, the attributes in the object are printed.

After adding the __set_state ():

To continue with the code:

Class person
{
    public $sex;
    public $name;
    Public $age;
 
    public Function __construct ($name = "",  $age =25, $sex = ' male ')
     {
        $this->name = $name;
         $this->age  = $age;
        $this->sex  = $sex;
   }
 
    public static function __set_state ($an _array)
    {
 & nbsp;      $a = new person ();
        $a->name = $an _array[' name ';
        return $a;
   }
 
}
 
$person = new Person (' xiaoming ');///Initial assignment
$person->name = ' Little Red ';
Var_export ($person);
continue to see results:

Person::__set_state (' Sex ' => ' man ', ' name ' => ' Little Red ', ' age ' => 25,))
14, __clone (), when the object is copied to complete the call
In most cases, we don't need to replicate exactly one object to get the properties. But there's a case that really needs to be: If you have a GTK window object, the object holds the window-related resources. You might want to copy a new window and keep all the properties the same as the original window, but it must be a new object (because if it's not a new object, the changes in one window will affect the other). Another situation: If object A is holding a reference to object B, when you copy object A, you want to use the object is no longer object B but a copy of B, then you have to get a copy of object A.

Role:

Object replication can be done through the Clone keyword (which, if possible, calls the object's __clone () method). The __clone () method in the object cannot be called directly.
Grammar:

1
$copy _of_object = Clone $object;
Attention:

When the object is replicated, PHP 5 performs a shallow copy of all properties of the object (shallow copy). All reference properties will still be a reference to the original variable.

When replication completes, if the __clone () method is defined, the __clone () method in the newly created object (the copied generated object) is invoked and can be used to modify the value of the property, if necessary.
Look at the code:

Class person
{
    public $sex;
    public $name;
    Public $age;
 
    public Function __construct ($name = "",  $age =25, $sex = ' male ')
     {
        $this->name = $name;
         $this->age  = $age;
        $this->sex  = $sex;
   }
 
    public Function __clone ()
    {
         echo __method__. " You are cloning the object
;
   }
 

$person = new Person (' xiaoming ');///Initial assignment
$person 2 = clone $person;
&NBSP
Var_dump (' persion1: ');
Var_dump ($person);
Echo '
';
Var_dump (' persion2: ');
Var_dump ($ Person2);
See results:


Person::__clone, you're cloning the object.
String (9) "Persion1:" Object (Person) #1 (3) {["Sex"]=> string (3) "Man" ["Name"]=> string (6) "Xiaoming" ["Age"]=> Int (25) }
String (9) "Persion2:" Object (Person) #2 (3) {["Sex"]=> string (3) "Man" ["Name"]=> string (6) "Xiaoming" ["Age"]=> Int (25) }
Clone succeeded.
XV, __autoload (), trying to load undefined classes
Role:

You can enable automatic loading of classes by defining this function.
Before the Magic function __autoload () method appears, if you want to instantiate 100 objects in a program file, you must include 100 class files with include or require, or you could define these 100 classes in the same class file-- Believe this file will be very big, and then you will suffer.

But with the __autoload () method, you don't have to worry about it later, this class will automatically load the file before you instantiate the object.

Let's take a look at it by example:

Let's take a look at the way it used to be:


/**
* File non_autoload.php
*/

Require_once (' project/class/a.php ');
Require_once (' project/class/b.php ');
Require_once (' project/class/c.php ');

if (condition a) {
$a = new A ();
$b = new B ();
$c = new C ();
... Business logic
else if (condition b) {
$a = Newa ();
$b = new B ();
... Business logic
}
Did you see it? No 100, just 3 looks a little annoying. And there's a problem: if the script executes the branch of condition B, c.php This file is not necessarily included. Because any of the included files, whether they are used or not, are compiled by the PHP engine. If not used, it is compiled, which can be regarded as a waste of resources. Further, if the c.php contains a d.php,d.php containing e.php. And most of the time the "conditional B" branch is executed, a portion of the resources is wasted to compile c.php,d.php,e.php three "useless" files.

So what if you use the __autoload () method?


/**
* File autoload_demo.php
*/
function __autoload ($className) {
$filePath = "project/class/{$className}.php";
if (is_readable ($filePath)) {
Require ($filePath);
}
}

if (condition a) {
$a = new A ();
$b = new B ();
$c = new C ();
... Business logic
else if (condition b) {
$a = Newa ();
$b = new B ();
... Business logic
}
OK, no matter how efficient, the minimum interface looks more comfortable, not too many redundant generation.

Let's take a look at the efficiency here, we analyze the following:

When the PHP engine uses class A for the first time, but cannot find it, it automatically invokes the __autoload method and passes the class name "A" as a parameter. So, what we need to do in __autoload () is based on the class name, find the appropriate file, and included, if our method can not find, then the PHP engine will be an error.

Attention:

This can be used only with require, because once included, the PHP engine encounters Class A when it does not call __autoload, but instead uses the in-memory class A without causing multiple inclusions.
Extended:
In fact, the development of PHP today, there will be ' spl_autoload_register '-register a given function as a __autoload of the implementation, but this is not ah in this article to explain, interested in the manual can be read.
16, __debuginfo (), printing the required debugging information
Attention:

This method can be used in PHP 5.6.0 and above, if you find the use of invalid or error, please check your version.
Look at the code:


Class C {
Private $prop;

Public function __construct ($val) {
$this->prop = $val;
}

/**
* @return Array
*/
Public Function __debuginfo () {
return [
' propsquared ' => $this->prop * * 2,
];
}
}

Var_dump (New C (42));
Results:

1
Object (C) #1 (1) {["propsquared"]=> int (1764)}
Note again:

"* *" here is the meaning of the powers, but also in the PHP5.6.0 and above can be used, for more information please check the PHP manual
Summarize
The above is PHP I learned the Magic method, commonly used including __set () __get () __autoload () and so should be familiar with, other understanding also has no relationship, after all, knowledge is not afraid of much.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.