国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home 類庫(kù)下載 PHP類庫(kù) Detailed explanation of sixteen magic methods in PHP

Detailed explanation of sixteen magic methods in PHP

Oct 31, 2016 pm 01:40 PM
php

Foreword

In PHP, methods starting with two underscores __ are called magic methods. These methods play a pivotal role in PHP. Magic methods include:

__construct(), class constructor

__destruct(), class destructor

__call(), when calling an inaccessible method in an object, call

__callStatic() in a static way When calling an inaccessible method, call

__get(), when obtaining a member variable of a class, call

__set(), when setting a member variable of a class, call

__isset(), when calling isset() on an inaccessible property ) or empty(), is called when unset() is called on an inaccessible property.

__sleep(), when executing serialize(), this function will be called first

__wakeup(), when unserialize() is executed, this function will be called first

__toString(), the response method when the class is treated as a string

__invoke(), the response method when calling an object by calling a function

__set_state(), this static method will be called when var_export() is called to export a class.

__clone(), call

__autoload() when the object copy is completed, try to load an undefined class

__debugInfo(), print the required debugging information

Example

Let us explain it to you in the form of an example How to use these magic methods below.

1. __construct(), the constructor function of the class

The constructor method in PHP is the first method automatically called by the object after the object is created. There is a constructor in every class. If it is not explicitly declared, there will be a constructor with no parameters and empty content in the class by default.

1. The role of constructor method

Usually constructor methods are used to perform some useful initialization tasks, such as assigning initial values ??to member properties when creating objects.

2. Declaration format of constructor method in class

function __constrct([參數(shù)列表]){ 
 
  方法體 //通常用來(lái)對(duì)成員屬性進(jìn)行初始化賦值 
 
}

3. Things to note when declaring constructor method in class

Only one constructor can be declared in the same class because PHP does not support constructors Overload.

The name of the constructor method starts with two underscores __construct()

The following is an example:

<?php 
    class Person 
    {                                                                       
            public $name;         
            public $age;         
            public $sex;         
                                                                  
        /** 
         * 顯示聲明一個(gè)構(gòu)造方法且?guī)?shù) 
         */                                                                                        
        public function __construct($name="", $sex="男", $age=22) 
        {       
            $this->name = $name; 
            $this->sex = $sex; 
            $this->age = $age; 
        } 
         
        /** 
         * say 方法 
         */ 
        public function say() 
        {  
            echo "我叫:" . $this->name . ",性別:" . $this->sex . ",年齡:" . $this->age; 
        }    
                                                                                            
    }

Create object $Person1 without any parameters

$Person1 = new Person(); 
 
echo $Person1->say(); //輸出:我叫:,性別:男,年齡:27

Create object $Person2 with parameter "Xiao Ming" ”

$Person2 = new Person("小明"); 
 
echo $Person2->say(); //輸出:我叫:張三,性別:男,年齡:27

Create the object $Person3 with three parameters

$Person3 = new Person("李四","男",25); 
 
echo $Person3->say(); //輸出:我叫:李四,性別:男,年齡:25

2. __destruct(), the destructor of the class

Through the above explanation, now we already know what a constructor is. Then the counterpart to the construction method is the destructor method.

The destructor method allows you to perform some operations or complete some functions before destroying a class, such as closing files, releasing result sets, etc.

The destructor method is a new content introduced in PHP5.

The declaration format of the destructor method is similar to the construction method __construct(). It is also a method __destruct() starting with two underscores. The name of this destructor method is also fixed.

1. Declaration format of destructor method

function __destruct() 
 
{ 
 
  //方法體 
 
}

Note: The destructor cannot have any parameters.

2. The role of the destructor method

Generally speaking, the destructor method is not very commonly used in PHP. It is an optional part of the class and is usually used to complete some cleanup tasks before the object is destroyed.

An example is as follows:

<?php 
class Person{      
                                                         
    public $name;          
    public $age;          
    public $sex;          
                                                                     
    public function __construct($name="", $sex="男", $age=22) 
    {    
        $this->name = $name; 
        $this->sex  = $sex; 
        $this->age  = $age; 
    } 
     
    /** 
     * say 說(shuō)話方法 
     */ 
    public function say() 
    {   
        echo "我叫:".$this->name.",性別:".$this->sex.",年齡:".$this->age; 
    }     
     
    /** 
     * 聲明一個(gè)析構(gòu)方法 
     */ 
    public function __destruct() 
    { 
            echo "我覺得我還可以再搶救一下,我的名字叫".$this->name; 
    } 
} 
 
$Person = new Person("小明"); 
unset($Person); //銷毀上面創(chuàng)建的對(duì)象$Person

The above program output when running:

I think I can save it a little more, my name is Xiao Ming

3. __call(), when calling an inaccessible method in an object transfer.

This method has two parameters. The first parameter $function_name will automatically receive the non-existing method name, and the second $arguments will receive multiple parameters of the non-existing method in the form of an array.

1. The format of the __call() method:

function __call(string $function_name, array $arguments) 
 
{ 
 
  // 方法體 
 
}

2. The function of the __call() method:

In order to avoid an error when the called method does not exist and accidentally cause the program to terminate, you can use __call() ways to avoid it.

This method will be automatically called when the called method does not exist, and the program will continue to execute.

Please refer to the following code:

<?php 
class Person 
{                              
    function say() 
    {   
                               
           echo "Hello, world!<br>";  
    }       
         
    /** 
     * 聲明此方法用來(lái)處理調(diào)用對(duì)象中不存在的方法 
     */ 
    function __call($funName, $arguments) 
    {  
          echo "你所調(diào)用的函數(shù):" . $funName . "(參數(shù):" ;  // 輸出調(diào)用不存在的方法名 
          print_r($arguments); // 輸出調(diào)用不存在的方法時(shí)的參數(shù)列表 
          echo ")不存在!<br>\n"; // 結(jié)束換行                       
    }                                           
} 
$Person = new Person();             
$Person->run("teacher"); // 調(diào)用對(duì)象中不存在的方法,則自動(dòng)調(diào)用了對(duì)象中的__call()方法 
$Person->eat("小明", "蘋果");              
$Person->say();

Run result:

你所調(diào)用的函數(shù):run(參數(shù):Array ( [0] => teacher ) )不存在! 
 
你所調(diào)用的函數(shù):eat(參數(shù):Array ( [0] => 小明 [1] => 蘋果 ) )不存在! 
 
Hello, world!

4. __callStatic(), called when calling an inaccessible method in static mode

This method is the same as the __call() function mentioned above except __callStatic Except that () is not prepared by static methods, everything else is the same.

Please look at the code below:

<?php 
class Person 
{ 
    function say() 
    { 
 
        echo "Hello, world!<br>"; 
    } 
 
    /** 
     * 聲明此方法用來(lái)處理調(diào)用對(duì)象中不存在的方法 
     */ 
    public static function __callStatic($funName, $arguments) 
    { 
        echo "你所調(diào)用的靜態(tài)方法:" . $funName . "(參數(shù):" ;  // 輸出調(diào)用不存在的方法名 
        print_r($arguments); // 輸出調(diào)用不存在的方法時(shí)的參數(shù)列表 
        echo ")不存在!<br>\n"; // 結(jié)束換行 
    } 
} 
$Person = new Person(); 
$Person::run("teacher"); // 調(diào)用對(duì)象中不存在的方法,則自動(dòng)調(diào)用了對(duì)象中的__call()方法 
$Person::eat("小明", "蘋果"); 
$Person->say();

The running results are as follows:

你所調(diào)用的靜態(tài)方法:run(參數(shù):Array ( [0] => teacher ) )不存在! 
 
你所調(diào)用的靜態(tài)方法:eat(參數(shù):Array ( [0] => 小明 [1] => 蘋果 ) )不存在! 
 
Hello, world!

5. __get(), called when obtaining the member variables of a class

In PHP object-oriented programming, after the member attributes of the class are set to private , if we try to call it outside, an error of "cannot access a private property" will occur. So to solve this problem, we can use the magic method __get().

The role of the magic method __get()

During the running of the program, you can use it to obtain the value of the private member attribute outside the object.

Let’s connect it further through the following __get() instance:

<?php 
class Person 
{ 
    private $name; 
    private $age; 
 
    function __construct($name="", $age=1) 
    { 
        $this->name = $name; 
        $this->age = $age; 
    } 
 
    /** 
     * 在類中添加__get()方法,在直接獲取屬性值時(shí)自動(dòng)調(diào)用一次,以屬性名作為參數(shù)傳入并處理 
     * @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("小明", 60);   // 通過(guò)Person類實(shí)例化的對(duì)象,并通過(guò)構(gòu)造方法為屬性賦初值 
echo "姓名:" . $Person->name . "<br>";   // 直接訪問(wèn)私有屬性name,自動(dòng)調(diào)用了__get()方法可以間接獲取 
echo "年齡:" . $Person->age . "<br>";    // 自動(dòng)調(diào)用了__get()方法,根據(jù)對(duì)象本身的情況會(huì)返回不同的值

Running result:

姓名:小明 
 
年齡:50

6. __set(), the function of calling

__set() when setting a member variable of a class :

__set( $property, $value )` method is used to set private properties. When assigning a value to an undefined property, this method will be triggered. The parameters passed are the property name and value to be set.

請(qǐng)看下面的演示代碼:

<?php 
class Person 
{ 
    private $name; 
    private $age; 
 
    public function __construct($name="",  $age=25) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
    } 
 
    /** 
     * 聲明魔術(shù)方法需要兩個(gè)參數(shù),真接為私有屬性賦值時(shí)自動(dòng)調(diào)用,并可以屏蔽一些非法賦值 
     * @param $property 
     * @param $value 
     */ 
    public function __set($property, $value) { 
        if ($property=="age") 
        { 
            if ($value > 150 || $value < 0) { 
                return; 
            } 
        } 
        $this->$property = $value; 
    } 
 
    /** 
     * 在類中聲明說(shuō)話的方法,將所有的私有屬性說(shuō)出 
     */ 
    public function say(){ 
        echo "我叫".$this->name.",今年".$this->age."歲了"; 
    } 
} 
 
$Person=new Person("小明", 25); //注意,初始值將被下面所改變 
//自動(dòng)調(diào)用了__set()函數(shù),將屬性名name傳給第一個(gè)參數(shù),將屬性值”李四”傳給第二個(gè)參數(shù) 
$Person->name = "小紅";     //賦值成功。如果沒(méi)有__set(),則出錯(cuò)。 
//自動(dòng)調(diào)用了__set()函數(shù),將屬性名age傳給第一個(gè)參數(shù),將屬性值26傳給第二個(gè)參數(shù) 
$Person->age = 16; //賦值成功 
$Person->age = 160; //160是一個(gè)非法值,賦值失效 
$Person->say();  //輸出:我叫小紅,今年16歲了

運(yùn)行結(jié)果:

我叫小紅,今年16歲了

七、 __isset(),當(dāng)對(duì)不可訪問(wèn)屬性調(diào)用isset()或empty()時(shí)調(diào)用

在看這個(gè)方法之前我們看一下isset()函數(shù)的應(yīng)用,isset()是測(cè)定變量是否設(shè)定用的函數(shù),傳入一個(gè)變量作為參數(shù),如果傳入的變量存在則傳回true,否則傳回false。

那么如果在一個(gè)對(duì)象外面使用isset()這個(gè)函數(shù)去測(cè)定對(duì)象里面的成員是否被設(shè)定可不可以用它呢?

分兩種情況,如果對(duì)象里面成員是公有的,我們就可以使用這個(gè)函數(shù)來(lái)測(cè)定成員屬性,如果是私有的成員屬性,這個(gè)函數(shù)就不起作用了,原因就是因?yàn)樗接械谋环庋b了,在外部不可見。那么我們就不可以在對(duì)象的外部使用isset()函數(shù)來(lái)測(cè)定私有成員屬性是否被設(shè)定了呢?當(dāng)然是可以的,但不是一成不變。你只要在類里面加上一個(gè)__isset()方法就可以了,當(dāng)在類外部使用isset()函數(shù)來(lái)測(cè)定對(duì)象里面的私有成員是否被設(shè)定時(shí),就會(huì)自動(dòng)調(diào)用類里面的__isset()方法了幫我們完成這樣的操作。

__isset()的作用:當(dāng)對(duì)不可訪問(wèn)屬性調(diào)用 isset() 或 empty() 時(shí),__isset() 會(huì)被調(diào)用。

請(qǐng)看下面代碼演示:

<?php 
class Person 
{ 
    public $sex; 
    private $name; 
    private $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    /** 
     * @param $content 
     * 
     * @return bool 
     */ 
    public function __isset($content) { 
        echo "當(dāng)在類外部使用isset()函數(shù)測(cè)定私有成員{$content}時(shí),自動(dòng)調(diào)用<br>"; 
        echo  isset($this->$content); 
    } 
} 
 
$person = new Person("小明", 25); // 初始賦值 
echo isset($person->sex),"<br>"; 
echo isset($person->name),"<br>"; 
echo isset($person->age),"<br>";

運(yùn)行結(jié)果如下:

1 // public 可以 isset() 
 
當(dāng)在類外部使用isset()函數(shù)測(cè)定私有成員name時(shí),自動(dòng)調(diào)用 // __isset() 內(nèi) 第一個(gè)echo 
 
1 // __isset() 內(nèi)第二個(gè)echo 
 
當(dāng)在類外部使用isset()函數(shù)測(cè)定私有成員age時(shí),自動(dòng)調(diào)用 // __isset() 內(nèi) 第一個(gè)echo 
 
1 // __isset() 內(nèi)第二個(gè)echo

八、 __unset(),當(dāng)對(duì)不可訪問(wèn)屬性調(diào)用unset()時(shí)被調(diào)用。

看這個(gè)方法之前呢,我們也先來(lái)看一下 unset() 函數(shù),unset()這個(gè)函數(shù)的作用是刪除指定的變量且傳回true,參數(shù)為要?jiǎng)h除的變量。

那么如果在一個(gè)對(duì)象外部去刪除對(duì)象內(nèi)部的成員屬性用unset()函數(shù)可以嗎?

這里自然也是分兩種情況:

1、 如果一個(gè)對(duì)象里面的成員屬性是公有的,就可以使用這個(gè)函數(shù)在對(duì)象外面刪除對(duì)象的公有屬性。

2、 如果對(duì)象的成員屬性是私有的,我使用這個(gè)函數(shù)就沒(méi)有權(quán)限去刪除。

雖然有以上兩種情況,但我想說(shuō)的是同樣如果你在一個(gè)對(duì)象里面加上__unset()這個(gè)方法,就可以在對(duì)象的外部去刪除對(duì)象的私有成員屬性了。在對(duì)象里面加上了__unset()這個(gè)方法之后,在對(duì)象外部使用“unset()”函數(shù)刪除對(duì)象內(nèi)部的私有成員屬性時(shí),對(duì)象會(huì)自動(dòng)調(diào)用__unset()函數(shù)來(lái)幫我們刪除對(duì)象內(nèi)部的私有成員屬性。

請(qǐng)看如下代碼:

<?php 
class Person 
{ 
    public $sex; 
    private $name; 
    private $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    /** 
     * @param $content 
     * 
     * @return bool 
     */ 
    public function __unset($content) { 
        echo "當(dāng)在類外部使用unset()函數(shù)來(lái)刪除私有成員時(shí)自動(dòng)調(diào)用的<br>"; 
        echo  isset($this->$content); 
    } 
} 
 
$person = new Person("小明", 25); // 初始賦值 
unset($person->sex); 
unset($person->name); 
unset($person->age);

運(yùn)行結(jié)果:

當(dāng)在類外部使用unset()函數(shù)來(lái)刪除私有成員時(shí)自動(dòng)調(diào)用的 
 
1當(dāng)在類外部使用unset()函數(shù)來(lái)刪除私有成員時(shí)自動(dòng)調(diào)用的 
 
1

九、 __sleep(),執(zhí)行serialize()時(shí),先會(huì)調(diào)用這個(gè)函數(shù)

serialize() 函數(shù)會(huì)檢查類中是否存在一個(gè)魔術(shù)方法 __sleep()。如果存在,則該方法會(huì)優(yōu)先被調(diào)用,然后才執(zhí)行序列化操作。

此功能可以用于清理對(duì)象,并返回一個(gè)包含對(duì)象中所有應(yīng)被序列化的變量名稱的數(shù)組。

如果該方法未返回任何內(nèi)容,則 NULL 被序列化,并產(chǎn)生一個(gè) E_NOTICE 級(jí)別的錯(cuò)誤。

注意:

__sleep() 不能返回父類的私有成員的名字。這樣做會(huì)產(chǎn)生一個(gè) E_NOTICE 級(jí)別的錯(cuò)誤??梢杂?Serializable 接口來(lái)替代。

作用:

__sleep() 方法常用于提交未提交的數(shù)據(jù),或類似的清理操作。同時(shí),如果有一些很大的對(duì)象,但不需要全部保存,這個(gè)功能就很好用。

具體請(qǐng)參考如下代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    /** 
     * @return array 
     */ 
    public function __sleep() { 
        echo "當(dāng)在類外部使用serialize()時(shí)會(huì)調(diào)用這里的__sleep()方法<br>"; 
        $this->name = base64_encode($this->name); 
        return array(&#39;name&#39;, &#39;age&#39;); // 這里必須返回一個(gè)數(shù)值,里邊的元素表示返回的屬性名稱 
    } 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
echo serialize($person); 
echo &#39;<br/>&#39;;

代碼運(yùn)行結(jié)果:

當(dāng)在類外部使用serialize()時(shí)會(huì)調(diào)用這里的__sleep()方法 
 
O:6:"Person":2:{s:4:"name";s:8:"5bCP5piO";s:3:"age";i:25;}

十、 __wakeup(),執(zhí)行unserialize()時(shí),先會(huì)調(diào)用這個(gè)函數(shù)

如果說(shuō) __sleep() 是白的,那么 __wakeup() 就是黑的了。

那么為什么呢?

因?yàn)椋?/p>

與之相反,`unserialize()` 會(huì)檢查是否存在一個(gè) `__wakeup()` 方法。如果存在,則會(huì)先調(diào)用 `__wakeup` 方法,預(yù)先準(zhǔn)備對(duì)象需要的資源。

作用:

__wakeup() 經(jīng)常用在反序列化操作中,例如重新建立數(shù)據(jù)庫(kù)連接,或執(zhí)行其它初始化操作。

還是看代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    /** 
     * @return array 
     */ 
    public function __sleep() { 
        echo "當(dāng)在類外部使用serialize()時(shí)會(huì)調(diào)用這里的__sleep()方法<br>"; 
        $this->name = base64_encode($this->name); 
        return array(&#39;name&#39;, &#39;age&#39;); // 這里必須返回一個(gè)數(shù)值,里邊的元素表示返回的屬性名稱 
    } 
 
    /** 
     * __wakeup 
     */ 
    public function __wakeup() { 
        echo "當(dāng)在類外部使用unserialize()時(shí)會(huì)調(diào)用這里的__wakeup()方法<br>"; 
        $this->name = 2; 
        $this->sex = &#39;男&#39;; 
        // 這里不需要返回?cái)?shù)組 
    } 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
var_dump(serialize($person)); 
var_dump(unserialize(serialize($person)));

運(yùn)行結(jié)果:

當(dāng)在類外部使用serialize()時(shí)會(huì)調(diào)用這里的__sleep()方法 
 
string(58) "O:6:"Person":2:{s:4:"name";s:8:"5bCP5piO";s:3:"age";i:25;}" 當(dāng)在類外部使用serialize()時(shí)會(huì)調(diào)用這里的__sleep()方法 
 
當(dāng)在類外部使用unserialize()時(shí)會(huì)調(diào)用這里的__wakeup()方法 
 
object(Person)#2 (3) { ["sex"]=> string(3) "男" ["name"]=> int(2) ["age"]=> int(25) }

十一、 __toString(),類被當(dāng)成字符串時(shí)的回應(yīng)方法

作用:

__toString() 方法用于一個(gè)類被當(dāng)成字符串時(shí)應(yīng)怎樣回應(yīng)。例如 `echo $obj;` 應(yīng)該顯示些什么。

注意:

此方法必須返回一個(gè)字符串,否則將發(fā)出一條 `E_RECOVERABLE_ERROR` 級(jí)別的致命錯(cuò)誤。

警告:

不能在 __toString() 方法中拋出異常。這么做會(huì)導(dǎo)致致命錯(cuò)誤。

代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    public function __toString() 
    { 
        return  &#39;go go go&#39;; 
    } 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值

結(jié)果:

go go go

那么如果類中沒(méi)有 __toString() 這個(gè)魔術(shù)方法運(yùn)行會(huì)發(fā)生什么呢?讓我們來(lái)測(cè)試下:

代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
     
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
echo $person;

結(jié)果:

Catchable fatal error: Object of class Person could not be converted to string in D:\phpStudy\WWW\test\index.phpon line 18

很明顯,頁(yè)面報(bào)了一個(gè)致命錯(cuò)誤,這是語(yǔ)法所不允許的。

十二、 __invoke(),調(diào)用函數(shù)的方式調(diào)用一個(gè)對(duì)象時(shí)的回應(yīng)方法

作用:

當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個(gè)對(duì)象時(shí),__invoke() 方法會(huì)被自動(dòng)調(diào)用。

注意:

本特性只在 PHP 5.3.0 及以上版本有效。

直接上代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    public function __invoke() { 
        echo &#39;這可是一個(gè)對(duì)象哦&#39;; 
    } 
 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
$person();

查看運(yùn)行結(jié)果:

這可是一個(gè)對(duì)象哦

當(dāng)然,如果你執(zhí)意要將對(duì)象當(dāng)函數(shù)方法使用,那么會(huì)得到下面結(jié)果:

Fatal error: Function name must be a string in D:\phpStudy\WWW\test\index.php on line 18

十三、 __set_state(),調(diào)用var_export()導(dǎo)出類時(shí),此靜態(tài)方法會(huì)被調(diào)用。

作用:

自 PHP 5.1.0 起,當(dāng)調(diào)用 var_export() 導(dǎo)出類時(shí),此靜態(tài)方法會(huì)被自動(dòng)調(diào)用。

參數(shù):

本方法的唯一參數(shù)是一個(gè)數(shù)組,其中包含按 array('property' => value, ...) 格式排列的類屬性。

下面我們先來(lái)看看在沒(méi)有加 __set_state() 情況按下,代碼及運(yùn)行結(jié)果如何:

上代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
var_export($person);

看結(jié)果:

Person::__set_state(array( &#39;sex&#39; => &#39;男&#39;, &#39;name&#39; => &#39;小明&#39;, &#39;age&#39; => 25, ))

很明顯,將對(duì)象中的屬性都打印出來(lái)了

加了 __set_state() 之后:

繼續(xù)上代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    public static function __set_state($an_array) 
    { 
        $a = new Person(); 
        $a->name = $an_array[&#39;name&#39;]; 
        return $a; 
    } 
 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
$person->name = &#39;小紅&#39;; 
var_export($person);

繼續(xù)看結(jié)果:

Person::__set_state(array( &#39;sex&#39; => &#39;男&#39;, &#39;name&#39; => &#39;小紅&#39;, &#39;age&#39; => 25, ))

十四、 __clone(),當(dāng)對(duì)象復(fù)制完成時(shí)調(diào)用

在多數(shù)情況下,我們并不需要完全復(fù)制一個(gè)對(duì)象來(lái)獲得其中屬性。但有一個(gè)情況下確實(shí)需要:如果你有一個(gè) GTK 窗口對(duì)象,該對(duì)象持有窗口相關(guān)的資源。你可能會(huì)想復(fù)制一個(gè)新的窗口,保持所有屬性與原來(lái)的窗口相同,但必須是一個(gè)新的對(duì)象(因?yàn)槿绻皇切碌膶?duì)象,那么一個(gè)窗口中的改變就會(huì)影響到另一個(gè)窗口)。還有一種情況:如果對(duì)象 A 中保存著對(duì)象 B 的引用,當(dāng)你復(fù)制對(duì)象 A 時(shí),你想其中使用的對(duì)象不再是對(duì)象 B 而是 B 的一個(gè)副本,那么你必須得到對(duì)象 A 的一個(gè)副本。

作用:

對(duì)象復(fù)制可以通過(guò) clone 關(guān)鍵字來(lái)完成(如果可能,這將調(diào)用對(duì)象的 __clone() 方法)。對(duì)象中的 __clone() 方法不能被直接調(diào)用。

語(yǔ)法:

$copy_of_object = clone $object;

注意:

當(dāng)對(duì)象被復(fù)制后,PHP 5 會(huì)對(duì)對(duì)象的所有屬性執(zhí)行一個(gè)淺復(fù)制(shallow copy)。所有的引用屬性 仍然會(huì)是一個(gè)指向原來(lái)的變量的引用。

當(dāng)復(fù)制完成時(shí),如果定義了 __clone() 方法,則新創(chuàng)建的對(duì)象(復(fù)制生成的對(duì)象)中的 __clone() 方法會(huì)被調(diào)用,可用于修改屬性的值(如果有必要的話)。

看代碼:

<?php 
class Person 
{ 
    public $sex; 
    public $name; 
    public $age; 
 
    public function __construct($name="",  $age=25, $sex=&#39;男&#39;) 
    { 
        $this->name = $name; 
        $this->age  = $age; 
        $this->sex  = $sex; 
    } 
 
    public function __clone() 
    { 
        echo __METHOD__."你正在克隆對(duì)象<br>"; 
    } 
 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
$person2 = clone $person; 
 
var_dump(&#39;persion1:&#39;); 
var_dump($person); 
echo &#39;<br>&#39;; 
var_dump(&#39;persion2:&#39;); 
var_dump($person2);

看結(jié)果:

Person::__clone你正在克隆對(duì)象 
 
string(9) "persion1:" object(Person)#1 (3) { ["sex"]=> string(3) "男" ["name"]=> string(6) "小明" ["age"]=> int(25) } 
 
string(9) "persion2:" object(Person)#2 (3) { ["sex"]=> string(3) "男" ["name"]=> string(6) "小明" ["age"]=> int(25) }

克隆成功。

十五、__autoload(),嘗試加載未定義的類

作用:

你可以通過(guò)定義這個(gè)函數(shù)來(lái)啟用類的自動(dòng)加載。

在魔術(shù)函數(shù) __autoload() 方法出現(xiàn)以前,如果你要在一個(gè)程序文件中實(shí)例化100個(gè)對(duì)象,那么你必須用include或者require包含進(jìn)來(lái)100個(gè)類文件,或者你把這100個(gè)類定義在同一個(gè)類文件中 —— 相信這個(gè)文件一定會(huì)非常大,然后你就痛苦了。

但是有了 __autoload() 方法,以后就不必為此大傷腦筋了,這個(gè)類會(huì)在你實(shí)例化對(duì)象之前自動(dòng)加載制定的文件。

還是通過(guò)例子來(lái)看看吧:

先看看以往的方式:

/**  
 * 文件non_autoload.php  
 */  
    
require_once(&#39;project/class/A.php&#39;);   
require_once(&#39;project/class/B.php&#39;);   
require_once(&#39;project/class/C.php&#39;);   
    
if (條件A) {   
    $a = new A();   
    $b = new B();   
    $c = new C();   
    // … 業(yè)務(wù)邏輯   
} else if (條件B) {   
    $a = newA();   
    $b = new B();   
    // … 業(yè)務(wù)邏輯   
}

看到了嗎?不用100個(gè),只是3個(gè)看起來(lái)就有點(diǎn)煩了。而且這樣就會(huì)有一個(gè)問(wèn)題:如果腳本執(zhí)行“條件B”這個(gè)分支時(shí),C.php這個(gè)文件其實(shí)沒(méi)有必要包含。因?yàn)?,任何一個(gè)被包含的文件,無(wú)論是否使用,均會(huì)被php引擎編譯。如果不使用,卻被編譯,這樣可以被視作一種資源浪費(fèi)。更進(jìn)一步,如果C.php包含了D.php,D.php包含了E.php。并且大部分情況都執(zhí)行“條件B”分支,那么就會(huì)浪費(fèi)一部分資源去編譯C.php,D.php,E.php三個(gè)“無(wú)用”的文件。

那么如果使用 __autoload() 方式呢?

/**  
 * 文件autoload_demo.php  
 */  
function  __autoload($className) {   
    $filePath = “project/class/{$className}.php”;   
    if (is_readable($filePath)) {   
        require($filePath);   
    }   
}   
    
if (條件A) {   
    $a = new A();   
    $b = new B();   
    $c = new C();   
    // … 業(yè)務(wù)邏輯   
} else if (條件B) {   
    $a = newA();   
    $b = new B();   
    // … 業(yè)務(wù)邏輯   
}

ok,不論效率怎么用,最起碼界面看起來(lái)舒服多了,沒(méi)有太多冗余的代。

再來(lái)看看這里的效率如何,我們分析下:

當(dāng)php引擎第一次使用類A,但是找不到時(shí),會(huì)自動(dòng)調(diào)用 __autoload 方法,并將類名“A”作為參數(shù)傳入。所以,我們?cè)?__autoload()中需要的做的就是根據(jù)類名,找到相應(yīng)的文件,并包含進(jìn)來(lái),如果我們的方法也找不到,那么php引擎就會(huì)報(bào)錯(cuò)了。

注意:

這里可以只用require,因?yàn)橐坏┌M(jìn)來(lái)后,php引擎再遇到類A時(shí),將不會(huì)調(diào)用__autoload,而是直接使用內(nèi)存中的類A,不會(huì)導(dǎo)致多次包含。

擴(kuò)展:

其實(shí)php發(fā)展到今天,已經(jīng)有將 `spl_autoload_register` — 注冊(cè)給定的函數(shù)作為 __autoload 的實(shí)現(xiàn)了,但是這個(gè)不在啊本文講解之內(nèi),有興趣可以自行看手冊(cè)。

十六、__debugInfo(),打印所需調(diào)試信息

注意:

該方法在PHP 5.6.0及其以上版本才可以用,如果你發(fā)現(xiàn)使用無(wú)效或者報(bào)錯(cuò),請(qǐng)查看啊你的版本。

看代碼:

<?php 
class C { 
    private $prop; 
 
    public function __construct($val) { 
        $this->prop = $val; 
    } 
 
    /** 
     * @return array 
     */ 
    public function __debugInfo() { 
        return [ 
            &#39;propSquared&#39; => $this->prop ** 2, 
        ]; 
    } 
} 
 
var_dump(new C(42));

結(jié)果:

object(C)#1 (1) { ["propSquared"]=> int(1764) }

再次注意:

這里的 `**` 是乘方的意思,也是在PHP5.6.0及其以上才可以使用,詳情請(qǐng)查看PHP手冊(cè)

總結(jié)

以上就是PHP中我了解到的魔術(shù)方法了,常用的包括 __set() __get() __autoload() 等應(yīng)該熟悉,其他的了解也沒(méi)有關(guān)系,畢竟知識(shí)不怕多嘛。


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to get the current session ID in PHP? How to get the current session ID in PHP? Jul 13, 2025 am 03:02 AM

The method to get the current session ID in PHP is to use the session_id() function, but you must call session_start() to successfully obtain it. 1. Call session_start() to start the session; 2. Use session_id() to read the session ID and output a string similar to abc123def456ghi789; 3. If the return is empty, check whether session_start() is missing, whether the user accesses for the first time, or whether the session is destroyed; 4. The session ID can be used for logging, security verification and cross-request communication, but security needs to be paid attention to. Make sure that the session is correctly enabled and the ID can be obtained successfully.

PHP get substring from a string PHP get substring from a string Jul 13, 2025 am 02:59 AM

To extract substrings from PHP strings, you can use the substr() function, which is syntax substr(string$string,int$start,?int$length=null), and if the length is not specified, it will be intercepted to the end; when processing multi-byte characters such as Chinese, you should use the mb_substr() function to avoid garbled code; if you need to intercept the string according to a specific separator, you can use exploit() or combine strpos() and substr() to implement it, such as extracting file name extensions or domain names.

How do you perform unit testing for php code? How do you perform unit testing for php code? Jul 13, 2025 am 02:54 AM

UnittestinginPHPinvolvesverifyingindividualcodeunitslikefunctionsormethodstocatchbugsearlyandensurereliablerefactoring.1)SetupPHPUnitviaComposer,createatestdirectory,andconfigureautoloadandphpunit.xml.2)Writetestcasesfollowingthearrange-act-assertpat

How to split a string into an array in PHP How to split a string into an array in PHP Jul 13, 2025 am 02:59 AM

In PHP, the most common method is to split the string into an array using the exploit() function. This function divides the string into multiple parts through the specified delimiter and returns an array. The syntax is exploit(separator, string, limit), where separator is the separator, string is the original string, and limit is an optional parameter to control the maximum number of segments. For example $str="apple,banana,orange";$arr=explode(",",$str); The result is ["apple","bana

JavaScript Data Types: Primitive vs Reference JavaScript Data Types: Primitive vs Reference Jul 13, 2025 am 02:43 AM

JavaScript data types are divided into primitive types and reference types. Primitive types include string, number, boolean, null, undefined, and symbol. The values are immutable and copies are copied when assigning values, so they do not affect each other; reference types such as objects, arrays and functions store memory addresses, and variables pointing to the same object will affect each other. Typeof and instanceof can be used to determine types, but pay attention to the historical issues of typeofnull. Understanding these two types of differences can help write more stable and reliable code.

Using std::chrono in C Using std::chrono in C Jul 15, 2025 am 01:30 AM

std::chrono is used in C to process time, including obtaining the current time, measuring execution time, operation time point and duration, and formatting analysis time. 1. Use std::chrono::system_clock::now() to obtain the current time, which can be converted into a readable string, but the system clock may not be monotonous; 2. Use std::chrono::steady_clock to measure the execution time to ensure monotony, and convert it into milliseconds, seconds and other units through duration_cast; 3. Time point (time_point) and duration (duration) can be interoperable, but attention should be paid to unit compatibility and clock epoch (epoch)

How to pass a session variable to another page in PHP? How to pass a session variable to another page in PHP? Jul 13, 2025 am 02:39 AM

In PHP, to pass a session variable to another page, the key is to start the session correctly and use the same $_SESSION key name. 1. Before using session variables for each page, it must be called session_start() and placed in the front of the script; 2. Set session variables such as $_SESSION['username']='JohnDoe' on the first page; 3. After calling session_start() on another page, access the variables through the same key name; 4. Make sure that session_start() is called on each page, avoid outputting content in advance, and check that the session storage path on the server is writable; 5. Use ses

How does PHP handle Environment Variables? How does PHP handle Environment Variables? Jul 14, 2025 am 03:01 AM

ToaccessenvironmentvariablesinPHP,usegetenv()orthe$_ENVsuperglobal.1.getenv('VAR_NAME')retrievesaspecificvariable.2.$_ENV['VAR_NAME']accessesvariablesifvariables_orderinphp.iniincludes"E".SetvariablesviaCLIwithVAR=valuephpscript.php,inApach

See all articles