標籤:keyword 建構函式 tar style string 調用 oid dir variable
從php5以後的版本,類就可以使用魔術方法了。PHP規定以兩個底線開頭的方法都保留為魔術方法,所以建議大家函數名最好不用__開 頭,除非是為了重載已有的魔術方法。
目前php已有的魔術方法有
__construct,__destruct,__call,__get,__set,__isset,__unset,__sleep,__wakeup,__toString,__set_state 和 __clone。
__construct和__destruct
__construct和__destruct是類的建構函式和解構函式,這個大家經常會用到,相信大家都很熟悉,這裡就不多說了。
__sleep和__wakeup
__sleep和__wakeup是序列化類別的時候調用的。當序列化對象時,php將試圖在序列動作之前調用該對象的成員函數__sleep(), 當使用unserialize() 恢複對象時, 將調用__wakeup()。
__toString
__toString是對象被轉為string時調用的必須有傳回值即:return xxx ; 否則報錯,例如
<?php class Str { private $str; public function __construct($str) { $this->str = $str; } public function __toString() { return $this->str; } } $class = new Str(‘Hello‘); echo $class; // 這裡對象被轉為了string,所以調用了__toString ?>
上例將輸出 Hello
__set_state
__set_state是當用var_export()來匯出類的時候調用的,這個魔術函數只有一個參數,這個參數是一個數組,用來指定 export的時候得到的屬性。一般很少用到。
__call, __get和__set
__call, __get和__set 這三個魔術方法是最常用的,當調用類中不存在的方法時就會調用__call,而__get和__set則是訪問和設定類不存在的成員變數時調用的。
這三個的函數原型如下:
mixed __call(string $name, array $arguments) void __set(string $name, mixed $value) mixed __get(string $name)
__call的例子:
<?php class Caller { public function __call( $method , $args ) { echo "Method $method called:/n" ; print_r($args ); } } $foo = new Caller(); $foo ->test(1, 2); ?>
上例將輸出:
Method test called:
Array
(
[0] => 1
[1] => 2
)
__get 和 __set 的例子:
<?php class a { public $c = 0; public $arr = array(); public function __set($k, $v) { echo $k . "/n"; echo $v . "/n"; $this->arr[$k] = $v; } public function __get($k) { echo "The value of $k is " . $this->arr[$k]; } } $a = new a; $a->b = 1; // 成員變數b不存在,所以會調用__set $a->c = 2; // 成員變數c是存在的,所以不調用__set,無任何輸出 $d = $a->b; // 成員變數b不存在,所以會調用__get ?>
上例將輸出:
b
1
The value of b is 1
__isset和__unset
__isset和__unset這兩個與__get和__set其實原理是差不多的,他們的原型如下:
bool __isset(string $name) void __unset(string $name)
舉個例子:
<?php class a { public $c = 3; public $arr = array ( ‘a‘ => 1, ‘b‘ => 2); public function __isset( $k ) { return isset( $this ->arr[ $k ]); } public function __unset( $k ) { unset($this ->arr[ $k ]); } } $a = new a; var_dump(isset($a ->a)); // 成員變數a不存在,所以調用__isset,返回true var_dump(isset($a ->c)); // 成員變數c是存在的,沒有調用__isset,同樣返回true unset($a ->b); // 成員變數b不存在,調用__unset var_dump($a ); ?>
上例將輸出:
bool(true)bool(true)object(a)#1 (2) { ["c"]=>int(3) ["arr"]=>array(1) { ["a"]=>int(1) }}
__clone
類複製(clone)的時候,如果有定義__clone這個魔術方法就會調用它。
舉例如下:
<?php class a { public function __clone() { echo "object cloned" ; } } $a = new a; $b = $a ; // $b只是$a的引用, 不是複製,所以不調用__clone,沒任何輸出。 $c = clone $a ; // 調用了__clone,將輸出 object cloned ?>
object cloned
參考: http://php.net/manual/zh/language.oop5.magic.php
PHP的魔術常量
定義: 以兩個_開頭和結尾的常量為魔術常量
注意: 魔術常量不區分大小寫
<?php$file1 = __FILE__;$file2 = __file__;var_dump($file1);var_dump($file2);?>
結果是:
string(36) “F:\Apache\www\temp\php_demo\temp.php”
string(36) “F:\Apache\www\temp\php_demo\temp.php”
_LINE_
檔案中的當前行號。
_FILE_
檔案的完整路徑和檔案名稱。如果用在被包含檔案中,則返回被包含的檔案名稱。自 PHP 4.0.2 起,FILE 總是包含一個絕對路徑(如果是符號串連,則是解析後的絕對路徑),而在此之前的版本有時會包含一個相對路徑。
_DIR_
檔案所在的目錄。如果用在被包括檔案中,則返回被包括的檔案所在的目錄。它等價於 dirname(FILE)。除非是根目錄,否則目錄中名不包括末尾的斜杠。(PHP 5.3.0中新增)
_FUNCTION_
函數名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該函數被定義時的名字(區分大小寫)。在 PHP 4 中該值總是小寫字母的。
_CLASS_
類的名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該類被定義時的名字(區分大小寫)。在 PHP 4 中該值總是小寫字母的。類名包括其被聲明的作用地區(例如 Foo\Bar)。注意自 PHP 5.4 起 CLASS 對 trait 也起作用。當用在 trait 方法中時,CLASS 是調用 trait 方法的類的名字。
_NAMESPACE_
當前命名空間的名稱(區分大小寫)。此常量是在編譯時間定義的(PHP 5.3.0 新增)。
_TRAIT_
Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定義時的名字(區分大小寫)。Trait 名包括其被聲明的作用地區(例如 Foo\Bar)。
_METHOD_
類的方法名(PHP 5.0.0 新加)。返回該方法被定義時的名字(區分大小寫)。
PHP魔術方法和魔術變數總結