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

首頁 類庫下載 PHP類庫 PHP之十六個魔術(shù)方法詳解

PHP之十六個魔術(shù)方法詳解

Oct 31, 2016 pm 01:40 PM
php

前言

PHP中把以兩個下劃線__開頭的方法稱為魔術(shù)方法(Magic methods),這些方法在PHP中充當(dāng)了舉足輕重的作用。 魔術(shù)方法包括:

__construct(),類的構(gòu)造函數(shù)

__destruct(),類的析構(gòu)函數(shù)

__call(),在對象中調(diào)用一個不可訪問方法時調(diào)用

__callStatic(),用靜態(tài)方式中調(diào)用一個不可訪問方法時調(diào)用

__get(),獲得一個類的成員變量時調(diào)用

__set(),設(shè)置一個類的成員變量時調(diào)用

__isset(),當(dāng)對不可訪問屬性調(diào)用isset()或empty()時調(diào)用

__unset(),當(dāng)對不可訪問屬性調(diào)用unset()時被調(diào)用。

__sleep(),執(zhí)行serialize()時,先會調(diào)用這個函數(shù)

__wakeup(),執(zhí)行unserialize()時,先會調(diào)用這個函數(shù)

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

__invoke(),調(diào)用函數(shù)的方式調(diào)用一個對象時的回應(yīng)方法

__set_state(),調(diào)用var_export()導(dǎo)出類時,此靜態(tài)方法會被調(diào)用。

__clone(),當(dāng)對象復(fù)制完成時調(diào)用

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

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

范例

下面讓我們以實(shí)例的形式向大家講解下這幾個魔術(shù)方法時如何使用的。

一、 __construct(),類的構(gòu)造函數(shù)

php中構(gòu)造方法是對象創(chuàng)建完成后第一個被對象自動調(diào)用的方法。在每個類中都有一個構(gòu)造方法,如果沒有顯示地聲明它,那么類中都會默認(rèn)存在一個沒有參數(shù)且內(nèi)容為空的構(gòu)造方法。

1、 構(gòu)造方法的作用

通常構(gòu)造方法被用來執(zhí)行一些有用的初始化任務(wù),如對成員屬性在創(chuàng)建對象時賦予初始值。

2、 構(gòu)造方法的在類中的聲明格式

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

3、 在類中聲明構(gòu)造方法需要注意的事項(xiàng)

在同一個類中只能聲明一個構(gòu)造方法,原因是,PHP不支持構(gòu)造函數(shù)重載。

構(gòu)造方法名稱是以兩個下畫線開始的__construct()

下面是它的例子:

<?php 
    class Person 
    {                                                                       
            public $name;         
            public $age;         
            public $sex;         
                                                                  
        /** 
         * 顯示聲明一個構(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; 
        }    
                                                                                            
    }

創(chuàng)建對象$Person1且不帶任參數(shù)

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

創(chuàng)建對象$Person2且?guī)?shù)“小明”

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

創(chuàng)建對象$Person3且?guī)齻€參數(shù)

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

二、__destruct(),類的析構(gòu)函數(shù)

通過上面的講解,現(xiàn)在我們已經(jīng)知道了什么叫構(gòu)造方法。那么與構(gòu)造方法對應(yīng)的就是析構(gòu)方法。

析構(gòu)方法允許在銷毀一個類之前執(zhí)行的一些操作或完成一些功能,比如說關(guān)閉文件、釋放結(jié)果集等。

析構(gòu)方法是PHP5才引進(jìn)的新內(nèi)容。

析造方法的聲明格式與構(gòu)造方法 __construct() 比較類似,也是以兩個下劃線開始的方法 __destruct() ,這種析構(gòu)方法名稱也是固定的。

1、 析構(gòu)方法的聲明格式

function __destruct() 
 
{ 
 
  //方法體 
 
}

注意:析構(gòu)函數(shù)不能帶有任何參數(shù)。

2、 析構(gòu)方法的作用

一般來說,析構(gòu)方法在PHP中并不是很常用,它屬類中可選擇的一部分,通常用來完成一些在對象銷毀前的清理任務(wù)。

舉例演示,如下:

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

上面的程序運(yùn)行時輸出:

我覺得我還可以再搶救一下,我的名字叫小明

三、 __call(),在對象中調(diào)用一個不可訪問方法時調(diào)用。

該方法有兩個參數(shù),第一個參數(shù) $function_name 會自動接收不存在的方法名,第二個 $arguments 則以數(shù)組的方式接收不存在方法的多個參數(shù)。

1、 __call() 方法的格式:

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

2、 __call() 方法的作用:

為了避免當(dāng)調(diào)用的方法不存在時產(chǎn)生錯誤,而意外的導(dǎo)致程序中止,可以使用 __call() 方法來避免。

該方法在調(diào)用的方法不存在時會自動調(diào)用,程序仍會繼續(xù)執(zhí)行下去。

請參考如下代碼:

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

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

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

四、 __callStatic(),用靜態(tài)方式中調(diào)用一個不可訪問方法時調(diào)用

此方法與上面所說的 __call() 功能除了 __callStatic() 是未靜態(tài)方法準(zhǔn)備的之外,其它都是一樣的。

請看下面代碼:

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

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

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

五、 __get(),獲得一個類的成員變量時調(diào)用

在 php 面向?qū)ο缶幊讨?,類的成員屬性被設(shè)定為 private 后,如果我們試圖在外面調(diào)用它則會出現(xiàn)“不能訪問某個私有屬性”的錯誤。那么為了解決這個問題,我們可以使用魔術(shù)方法 __get()。

魔術(shù)方法__get()的作用

在程序運(yùn)行過程中,通過它可以在對象的外部獲取私有成員屬性的值。

我們通過下面的 __get() 的實(shí)例來更進(jìn)一步的連接它吧:

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

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

姓名:小明 
 
年齡:50

六、 __set(),設(shè)置一個類的成員變量時調(diào)用

__set() 的作用:

__set( $property, $value )` 方法用來設(shè)置私有屬性, 給一個未定義的屬性賦值時,此方法會被觸發(fā),傳遞的參數(shù)是被設(shè)置的屬性名和值。

請看下面的演示代碼:

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

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

我叫小紅,今年16歲了

七、 __isset(),當(dāng)對不可訪問屬性調(diào)用isset()或empty()時調(diào)用

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

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

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

__isset()的作用:當(dāng)對不可訪問屬性調(diào)用 isset() 或 empty() 時,__isset() 會被調(diào)用。

請看下面代碼演示:

<?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ù)測定私有成員{$content}時,自動調(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ù)測定私有成員name時,自動調(diào)用 // __isset() 內(nèi) 第一個echo 
 
1 // __isset() 內(nèi)第二個echo 
 
當(dāng)在類外部使用isset()函數(shù)測定私有成員age時,自動調(diào)用 // __isset() 內(nèi) 第一個echo 
 
1 // __isset() 內(nèi)第二個echo

八、 __unset(),當(dāng)對不可訪問屬性調(diào)用unset()時被調(diào)用。

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

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

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

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

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

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

請看如下代碼:

<?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ù)來刪除私有成員時自動調(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ù)來刪除私有成員時自動調(diào)用的 
 
1當(dāng)在類外部使用unset()函數(shù)來刪除私有成員時自動調(diào)用的 
 
1

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

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

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

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

注意:

__sleep() 不能返回父類的私有成員的名字。這樣做會產(chǎn)生一個 E_NOTICE 級別的錯誤??梢杂?Serializable 接口來替代。

作用:

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

具體請參考如下代碼:

<?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()時會調(diào)用這里的__sleep()方法<br>"; 
        $this->name = base64_encode($this->name); 
        return array(&#39;name&#39;, &#39;age&#39;); // 這里必須返回一個數(shù)值,里邊的元素表示返回的屬性名稱 
    } 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
echo serialize($person); 
echo &#39;<br/>&#39;;

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

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

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

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

那么為什么呢?

因?yàn)椋?/p>

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

作用:

__wakeup() 經(jīng)常用在反序列化操作中,例如重新建立數(shù)據(jù)庫連接,或執(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()時會調(diào)用這里的__sleep()方法<br>"; 
        $this->name = base64_encode($this->name); 
        return array(&#39;name&#39;, &#39;age&#39;); // 這里必須返回一個數(shù)值,里邊的元素表示返回的屬性名稱 
    } 
 
    /** 
     * __wakeup 
     */ 
    public function __wakeup() { 
        echo "當(dāng)在類外部使用unserialize()時會調(diào)用這里的__wakeup()方法<br>"; 
        $this->name = 2; 
        $this->sex = &#39;男&#39;; 
        // 這里不需要返回數(shù)組 
    } 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
var_dump(serialize($person)); 
var_dump(unserialize(serialize($person)));

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

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

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

作用:

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

注意:

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

警告:

不能在 __toString() 方法中拋出異常。這么做會導(dǎ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 __toString() 
    { 
        return  &#39;go go go&#39;; 
    } 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值

結(jié)果:

go go go

那么如果類中沒有 __toString() 這個魔術(shù)方法運(yùn)行會發(fā)生什么呢?讓我們來測試下:

代碼:

<?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

很明顯,頁面報了一個致命錯誤,這是語法所不允許的。

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

作用:

當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個對象時,__invoke() 方法會被自動調(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;這可是一個對象哦&#39;; 
    } 
 
} 
 
$person = new Person(&#39;小明&#39;); // 初始賦值 
$person();

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

這可是一個對象哦

當(dāng)然,如果你執(zhí)意要將對象當(dāng)函數(shù)方法使用,那么會得到下面結(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)出類時,此靜態(tài)方法會被調(diào)用。

作用:

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

參數(shù):

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

下面我們先來看看在沒有加 __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, ))

很明顯,將對象中的屬性都打印出來了

加了 __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)對象復(fù)制完成時調(diào)用

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

作用:

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

語法:

$copy_of_object = clone $object;

注意:

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

當(dāng)復(fù)制完成時,如果定義了 __clone() 方法,則新創(chuàng)建的對象(復(fù)制生成的對象)中的 __clone() 方法會被調(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__."你正在克隆對象<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你正在克隆對象 
 
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(),嘗試加載未定義的類

作用:

你可以通過定義這個函數(shù)來啟用類的自動加載。

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

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

還是通過例子來看看吧:

先看看以往的方式:

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

那么如果使用 __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,不論效率怎么用,最起碼界面看起來舒服多了,沒有太多冗余的代。

再來看看這里的效率如何,我們分析下:

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

注意:

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

擴(kuò)展:

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

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

注意:

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

看代碼:

<?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及其以上才可以使用,詳情請查看PHP手冊

總結(jié)

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


本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1600
29
PHP教程
1502
276
PHP調(diào)用AI智能語音助手 PHP語音交互系統(tǒng)搭建 PHP調(diào)用AI智能語音助手 PHP語音交互系統(tǒng)搭建 Jul 25, 2025 pm 08:45 PM

用戶語音輸入通過前端JavaScript的MediaRecorderAPI捕獲并發(fā)送至PHP后端;2.PHP將音頻保存為臨時文件后調(diào)用STTAPI(如Google或百度語音識別)轉(zhuǎn)換為文本;3.PHP將文本發(fā)送至AI服務(wù)(如OpenAIGPT)獲取智能回復(fù);4.PHP再調(diào)用TTSAPI(如百度或Google語音合成)將回復(fù)轉(zhuǎn)為語音文件;5.PHP將語音文件流式返回前端播放,完成交互。整個流程由PHP主導(dǎo)數(shù)據(jù)流轉(zhuǎn)與錯誤處理,確保各環(huán)節(jié)無縫銜接。

如何用PHP搭建社交分享功能 PHP分享接口集成實(shí)戰(zhàn) 如何用PHP搭建社交分享功能 PHP分享接口集成實(shí)戰(zhàn) Jul 25, 2025 pm 08:51 PM

在PHP中搭建社交分享功能的核心方法是通過動態(tài)生成符合各平臺要求的分享鏈接。1.首先獲取當(dāng)前頁面或指定的URL及文章信息;2.使用urlencode對參數(shù)進(jìn)行編碼;3.根據(jù)各平臺協(xié)議拼接生成分享鏈接;4.在前端展示鏈接供用戶點(diǎn)擊分享;5.動態(tài)生成頁面OG標(biāo)簽優(yōu)化分享內(nèi)容展示;6.務(wù)必對用戶輸入進(jìn)行轉(zhuǎn)義以防止XSS攻擊。該方法無需復(fù)雜認(rèn)證,維護(hù)成本低,適用于大多數(shù)內(nèi)容分享需求。

如何用PHP結(jié)合AI實(shí)現(xiàn)文本糾錯 PHP語法檢測與優(yōu)化 如何用PHP結(jié)合AI實(shí)現(xiàn)文本糾錯 PHP語法檢測與優(yōu)化 Jul 25, 2025 pm 08:57 PM

要實(shí)現(xiàn)PHP結(jié)合AI進(jìn)行文本糾錯與語法優(yōu)化,需按以下步驟操作:1.選擇適合的AI模型或API,如百度、騰訊API或開源NLP庫;2.通過PHP的curl或Guzzle調(diào)用API并處理返回結(jié)果;3.在應(yīng)用中展示糾錯信息并允許用戶選擇是否采納;4.使用php-l和PHP_CodeSniffer進(jìn)行語法檢測與代碼優(yōu)化;5.持續(xù)收集反饋并更新模型或規(guī)則以提升效果。選擇AIAPI時應(yīng)重點(diǎn)評估準(zhǔn)確率、響應(yīng)速度、價格及對PHP的支持。代碼優(yōu)化應(yīng)遵循PSR規(guī)范、合理使用緩存、避免循環(huán)查詢、定期審查代碼,并借助X

PHP打造博客評論系統(tǒng)變現(xiàn) PHP評論審核與防刷策略 PHP打造博客評論系統(tǒng)變現(xiàn) PHP評論審核與防刷策略 Jul 25, 2025 pm 08:27 PM

1.評論系統(tǒng)商業(yè)價值最大化需結(jié)合原生廣告精準(zhǔn)投放、用戶付費(fèi)增值服務(wù)(如上傳圖片、評論置頂)、基于評論質(zhì)量的影響力激勵機(jī)制及合規(guī)匿名數(shù)據(jù)洞察變現(xiàn);2.審核策略應(yīng)采用前置審核 動態(tài)關(guān)鍵詞過濾 用戶舉報機(jī)制組合,輔以評論質(zhì)量評分實(shí)現(xiàn)內(nèi)容分級曝光;3.防刷需構(gòu)建多層防御:reCAPTCHAv3無感驗(yàn)證、Honeypot蜜罐字段識別機(jī)器人、IP與時間戳頻率限制阻止灌水、內(nèi)容模式識別標(biāo)記可疑評論,持續(xù)迭代應(yīng)對攻擊。

如何用PHP結(jié)合AI做圖像生成 PHP自動生成藝術(shù)作品 如何用PHP結(jié)合AI做圖像生成 PHP自動生成藝術(shù)作品 Jul 25, 2025 pm 07:21 PM

PHP不直接進(jìn)行AI圖像處理,而是通過API集成,因?yàn)樗瞄LWeb開發(fā)而非計算密集型任務(wù),API集成能實(shí)現(xiàn)專業(yè)分工、降低成本、提升效率;2.整合關(guān)鍵技術(shù)包括使用Guzzle或cURL發(fā)送HTTP請求、JSON數(shù)據(jù)編解碼、API密鑰安全認(rèn)證、異步隊(duì)列處理耗時任務(wù)、健壯錯誤處理與重試機(jī)制、圖像存儲與展示;3.常見挑戰(zhàn)有API成本失控、生成結(jié)果不可控、用戶體驗(yàn)差、安全風(fēng)險和數(shù)據(jù)管理難,應(yīng)對策略分別為設(shè)置用戶配額與緩存、提供prompt指導(dǎo)與多圖選擇、異步通知與進(jìn)度提示、密鑰環(huán)境變量存儲與內(nèi)容審核、云存

PHP實(shí)現(xiàn)商品庫存管理變現(xiàn) PHP庫存同步與報警機(jī)制 PHP實(shí)現(xiàn)商品庫存管理變現(xiàn) PHP庫存同步與報警機(jī)制 Jul 25, 2025 pm 08:30 PM

PHP通過數(shù)據(jù)庫事務(wù)與FORUPDATE行鎖確保庫存扣減原子性,防止高并發(fā)超賣;2.多平臺庫存一致性需依賴中心化管理與事件驅(qū)動同步,結(jié)合API/Webhook通知及消息隊(duì)列保障數(shù)據(jù)可靠傳遞;3.報警機(jī)制應(yīng)分場景設(shè)置低庫存、零/負(fù)庫存、滯銷、補(bǔ)貨周期和異常波動策略,并按緊急程度選擇釘釘、短信或郵件通知責(zé)任人,且報警信息需完整明確,以實(shí)現(xiàn)業(yè)務(wù)適配與快速響應(yīng)。

超越燈堆:PHP在現(xiàn)代企業(yè)體系結(jié)構(gòu)中的作用 超越燈堆:PHP在現(xiàn)代企業(yè)體系結(jié)構(gòu)中的作用 Jul 27, 2025 am 04:31 AM

PHPisstillrelevantinmodernenterpriseenvironments.1.ModernPHP(7.xand8.x)offersperformancegains,stricttyping,JITcompilation,andmodernsyntax,makingitsuitableforlarge-scaleapplications.2.PHPintegrateseffectivelyinhybridarchitectures,servingasanAPIgateway

PHP集成AI語音識別與轉(zhuǎn)寫 PHP會議記錄自動生成方案 PHP集成AI語音識別與轉(zhuǎn)寫 PHP會議記錄自動生成方案 Jul 25, 2025 pm 07:06 PM

選擇合適AI語音識別服務(wù)并集成PHPSDK;2.用PHP調(diào)用ffmpeg將錄音轉(zhuǎn)為API要求格式(如wav);3.上傳文件至云存儲并調(diào)用API異步識別;4.解析JSON結(jié)果并用NLP技術(shù)整理文本;5.生成Word或Markdown文檔完成會議記錄自動化,全過程需確保數(shù)據(jù)加密、訪問控制與合規(guī)性以保障隱私安全。

See all articles