php反序列化之魔術方法超詳細講解
php魔術方法
在php類保留方法中以 “__”兩個下劃線開頭的函數稱為魔術方法,我的理解為php類設計中自定義好的函數。
常見的魔術方法有:
__construct(),類的構造函數
__destruct(),類的析構函數
__call(),在對象中調用一個不可訪問方法時調用
__callStatic(),用靜態方式中調用一個不可訪問方法時調用
__get(),獲得一個類的成員變量時調用
__set(),設置一個類的成員變量時調用
__isset(),當對不可訪問屬性調用isset()或empty()時調用
__unset(),當對不可訪問屬性調用unset()時被調用
__sleep(),執行serialize()時,先會調用這個函數
__wakeup(),執行unserialize()時,先會調用這個函數
__toString(),類被當成字符串時的回應方法
__invoke(),調用函數的方式調用一個對象時的回應方法
__set_state(),調用var_export()導出類時,此靜態方法會被調用
__clone(),當對象復制完成時調用
__autoload(),嘗試加載未定義的類
__debugInfo(),打印所需調試信息
__construct()與__destruct()
__construct() 構造函數與 __destruct() 析構函數,與其他的語言如java,c#,一樣,構造函數就是在對象實例化的時候先執行初始化的方法。
__construct()構造函數隻有在new 一個對象的時候會觸發,在serialize 序列化和unserialize反序列化中都不會觸發
<?php class demo1{ private $k1; public function __construct() { echo("構造函數被調用"."<br>"); } public function f1(){ echo("f1 函數被調用"); } } echo("0000"."<br>"); $f=new demo1(); echo("1111"."<br>"); $a=serialize($f); echo("2222"."<br>"); unserialize($a); ?>
輸出結果
__destruct() 析構函數則在對象銷毀和serialize 反序列化的情況下會被觸發。如下
<?php class demo1{ private $k1; public function __destruct() { echo("析構函數被調用"."<br>"); } } $f=new demo1(); echo("0000"."<br>"); $a=serialize($f); echo("1111"."<br>"); unset($f); echo("2222"."<br>"); unserialize($a); ?>
輸出結果
__call
__call 魔術方法的作用是當前對象調用一個不存在的方法時,就會被觸發
<?php class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } //當調用不存在的方法時,方法名作為參數傳到$name 變量,方法名的輸入參數傳到arguments參數列表中 public function __call($name, $arguments) { // TODO: Implement __call() method. echo($name."---".$arguments[0]); } } $f=new demo1(); $f->f2("123");//調用不存在的方法f2() ?>
輸出結果
__get
__get() 魔術方法是當訪問一個對象不存在的變量時就會被觸發
<?php class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __get($name)//不存在的變量k會以參數傳到$name { echo($name); } } $f=new demo1(); $f->k;//不存在的變量k ?>
輸出結果
__set
__set() 魔術方法是當給一個對象不存在的變量賦值時就會被觸發
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __set($name, $value) { echo($name."---".$value); } } $f=new demo1(); $f->k=123; //給不存在的成員變量賦值 ?>
輸出結果
__isset
當對不可訪問屬性調用isset()或empty()時會觸發,例如訪問類的私有屬性,類不存在的成員屬性
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __isset($name) { echo($name); } } $f=new demo1(); $f2=unserialize(serialize($f));//反序列化 isset($f2->k1);//使用isset方法判斷私有成員屬性k1 empty($f2->k1);//使用empty方法判斷私有成員屬性k1 ?>
輸出結果
__unset
當嘗試使用unset() 銷毀函數去銷毀一個不可訪問的成員屬性時會觸發,不可訪問(包括私有成員屬性,不存在的成員屬性)
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __unset($name) { echo($name); } } $f=new demo1(); $f2=unserialize(serialize($f));//反序列化 unset($f2->k1);//使用unset銷毀私有成員屬性k1 unset($f2->faaa);//使用unset銷毀不存在的成員屬性faaa ?>
輸出結果
__sleep
當對象被serialize 序列化時觸發調用__sleep
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __sleep() { echo("在被序列化時被調用"); } } $f=new demo1(); echo("00000"."</br>"); serialize($f); ?>
輸出結果
__wakeup
當進行unserialize 反序列化對象時,__wakeup魔術方法會被觸發,看起來__wakeup與__sleep 觸發條件是相反的
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __wakeup() { echo("在被反序列化時被調用"); } } $f=new demo1(); $uz=serialize($f); echo("00000"."</br>"); unserialize($uz); ?>
輸出結果
__toString
如果一個對象類中存在__toString魔術方法,這個對象類被當做字符串進行處理時,就會觸發__toString魔術方法,而不會產生錯誤
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __toString() { echo("__toString 被觸發瞭"); return ""; } } $f=new demo1(); echo($f); ?>
輸出結果
__invoke
當一個對象類中存在__invoke魔術方法,這個對象類被當作函數進行調用時,就會觸發__invoke魔術方法,而不會產生錯誤
<?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函數被調用"); } public function __invoke() { echo("__invoke 被觸發瞭"); } } $f=new demo1(); $f(); ?>
輸出結果
到此這篇關於php反序列化之魔術方法超詳細講解的文章就介紹到這瞭,更多相關php反序列化 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!