說說 PHP 的魔術方法及其應用

2021-09-11 09:44:55 字數 3956 閱讀 8857

php中將所有__(兩個下劃線)開頭的類方法作為魔術方法,這方法之所以稱為魔術方法是因為其實現的功能就如變魔術一樣感覺很神奇。在特定的事件下觸發,這真的很酷。

這個方法應該是最常用的,被稱為構造器或者構造方法,當乙個物件被例項化時會被首先呼叫,而在 php 框架中一些過濾器,中介軟體及依賴注入也一般在這個方法中完成。父類的構造器可以被子類繼承和重寫。

<?php

classa}

class

bextendsa}

class

cextendsa}

new a();// this is a construct

new b();// this is a construct this is b construct

new c();// this is c construct

複製**

以上示例**將按順序輸出:

this is a construct

this is a construct

this is b construct

this is c construct

構造方法能幫助我們完成一些資料初始化,屬性初始化的任務,在例項化類後使得呼叫類更便利。

析構方法,php 將物件銷毀前將呼叫這個方法,這個方法可能對於 php 這種執行時間短的指令碼可能無意義,但在有些情況下還是具有意義的。

比如你需要乙個長時間執行的指令碼,設定set_time_limit(0);後需要不斷執行這個指令碼,一般這樣的指令碼是迴圈執行一些任務,這其中可能會涉及到頻繁的建立某個物件,這時候析構方法就會起到作用,它可以將物件開啟的一些資源及時的釋放,以防止記憶體溢位或單個程序占用過多記憶體。

<?php

class

log public function

__destruct()

}複製**

這兩個方法的作用是當呼叫或設定乙個類及其父類方法中未定義的屬性時這個方法會被觸發。

<?php 

class

methodtest

public function

__get($name)

}class

penguin

extends

animal

public function

getpenguinfromdb($id)

public function

__get($field)

} public function

__set($field, $value)

}}複製**

在 methodtest 這個類中使用get 和set 將所有不存在的屬性都儲存在類的 data 屬性中,而在penguin 類中我們連線了資料庫或者是資料提供者,由於某些原因資料來源中原來的 name 變更為 username ,如果這時要檢查所有呼叫 penguin 類的地方將 name 換成 username 顯然是困難而且無趣的甚至會有忽略的地方,而使用乙個 __get 方法我們不用改變外部呼叫的屬性名就可以實現從 name 轉變為 username

call 和callstatic 是類似的方法,前者是呼叫類不存在的方法時執行,而後者是呼叫類不存在的靜態方式方法時執行。正常情況下如果呼叫乙個類不存在的方法 php 會丟擲致命錯誤,而使用這兩個魔術方法我們可以替換一些更友好的提示或者記錄錯誤呼叫日誌資訊、將使用者重定向、丟擲異常等等,亦或者是如同set 和get 那樣做方法的重新命名。

class

a function

__call($name, $arguments)

}$a = new a();

$a->agfdgdrsfgdf([123,3213]);

a::sdfsd();複製**

當我們執行serialize()unserialize()對物件進行操作是時,會呼叫這兩個方法,比如物件有乙個資料庫鏈結,想要在反序列化時恢復鏈結狀態,而在序列化時希望將屬性鍵名儲存就可以使用這兩個魔術方法:

<?php

class

connection

private function

connect()

public function

__sleep()

public function

__wakeup()

}複製**

如同名字一樣,這個方法在物件被複製是呼叫,如我們要實現乙個單例模式,我們可以用這個魔術方法防止物件被轉殖。

<?php 

public class

singleton

public static

function

getinstance()

return self::$_instance;

}// 防止轉殖例項

public function

__clone()

}複製**

當物件被當做字串是呼叫此方法。

php 5.2.0 之前,tostring() 方法只有在直接使用於 echo 或 print 時才能生效。php 5.2.0 之後,則可以在任何字串環境生效(例如通過 printf(),使用 %s 修飾符),但不能用於非字串環境(如使用 %d 修飾符)。自 php 5.2.0 起,如果將乙個未定義tostring() 方法的物件轉換為字串,會產生 e_recoverable_error 級別的錯誤。

// declare a ****** class

class

testclass

}class

penguin

public function

__tostring()

}$class

= new testclass();

echo $class

;$tux = new penguin('tux');

echo $tux;複製**

在 testclass 的呼叫中我們輸出了乙個友好的提示,而在 penguin 我們將物件的屬性組合後輸出,比如在模板中呼叫。

當嘗試用函式的方式呼叫乙個物件是觸發此方法。

php 5.3.0 新增

<?php

class

callableclass

}$obj = new callableclass;

$obj(5); // int(5)

var_dump(is_callable($obj)) // bool(true)

複製**

呼叫 var_export() 匯出類時,此魔術方法被呼叫。

php 5.1.0 新增

<?php

classa}

$a = new a;

$a->var1 = 5;

$a->var2 = 'foo';

var_dump(var_export($a));複製**

這個方法在對物件使用var_dump()時呼叫。

php 5.6.0 新增

<?php

class

c public function

__debuginfo()

}var_dump(new c(42));

/*object(c)#1 (1)

*/複製**

php中魔術方法的應用

魔術方法是以兩個下劃線 開頭,具有特殊作用的一些方法,可以看做 php 的 語法糖 語法糖 指那些沒有個計算機語言新增新功能,而只是對人類來說更 甜蜜 的語法,語法糖往往給程式設計師提供了更實用的編碼方式或者一些技巧的用法,有益於更好的編碼風格,是 更易讀。不過其並沒有給語言新增什麼新東西。php ...

php中的魔術方法應用例項

獲取當前類名 echo class 當前函式名 confirm echo function 當前方法名 bankcard confirm echo method 在php5中,預定義了兩個函式 get 和 set 來獲取和賦值其屬性,get 方法 這個方法用來獲取私有成員屬性值的,有乙個引數,引數傳...

php的魔術函式(魔術方法)

construct 類的建構函式 destruct 類的析構函式 call 在物件中呼叫乙個不可訪問方法時呼叫 callstatic 用靜態方式中呼叫乙個不可訪問方法時呼叫 get 獲得乙個類的成員變數時呼叫 set 設定乙個類的成員變數時呼叫 isset 當對不可訪問屬性呼叫isset 或empt...