程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php魔術方法——屬性重載方法,php魔術屬性重載

php魔術方法——屬性重載方法,php魔術屬性重載

編輯:關於PHP編程

php魔術方法——屬性重載方法,php魔術屬性重載


php有一類很神奇的方法,這些方法是保留方法,通常不會在外部被顯式調用,他們使用雙下劃線(__)開頭,他們被稱為魔術方法(Magic Methods)。php官方也不建議定義其他雙下劃線開頭的方法。

這次介紹屬性重載方法:get/set/isset/unset

public void __set ( string $name , mixed $value )

public mixed __get ( string $name )

public bool __isset ( string $name )

public void __unset ( string $name )

這些方法觸發的時機,都是在訪問不可訪問的屬性的時候。

如以下:

 1 <?php
 2 
 3 class Cls{
 4 
 5     private $a = 0;
 6     protected $b = 1;
 7     public $c = 2;
 8     var $d = 3;
 9 
10     private $_properties = array(0);
11 
12     public function __set($name, $value){
13         echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
14         return $this->_properties[$name] = $value;
15     }
16 
17     public function __get($name){
18         echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
19         return $this->_properties[$name];
20     }
21 
22     public function __isset($name){
23         echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
24         return isset($this->_properties[$name]);
25     }
26 
27     public function __unset($name){
28         echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
29         unset($this->_properties[$name]);
30     }
31 
32     public function dump(){
33         echo "====================== DUMP START ====================\n";
34         echo <<<STR
35     a: $this->a
36     b: $this->b
37     c: $this->c
38     d: $this->d\n
39 STR;
40         foreach($this->_properties as $k => $v){
41             echo <<<STR
42     Property $k: $v\n
43 STR;
44         }
45     
46         echo "====================== DUMP STOP =====================\n";
47         
48     }
49 }
50 $string = 'abcdef';
51 $obj = new Cls();
52 
53 $list = array('isset', 'get', 'set', 'isset', 'unset', 'isset');
54 $obj->dump();
55 foreach($list as $method){
56     for($i = 0 ; $i < strlen($string) ; $i ++){
57         $char = $string{$i};
58         echo "------ $method : $char ------\n";
59         switch($method){
60             case 'isset':
61                 echo json_encode($tmp = isset($obj->$char)) . "\n";
62                 break;
63             case 'get':
64                 echo json_encode($tmp = $obj->$char) . "\n";
65                 break;
66             case 'set':
67                 echo json_encode($tmp = $obj->$char = $char . "-val") . "\n";
68                 break;
69             case 'unset':
70                 unset($obj->$char);
71                 break;
72             default:
73                 break;
74         }
75     }
76     $obj->dump();
77 }

結果輸出:

====================== DUMP START ====================
    a: 0
    b: 1
    c: 2
    d: 3
    Property 0: 0
====================== DUMP STOP =====================
------ isset : a ------
Cls::__isset is called! ["a"]
false
------ isset : b ------
Cls::__isset is called! ["b"]
false
------ isset : c ------
true
------ isset : d ------
true
------ isset : e ------
Cls::__isset is called! ["e"]
false
------ isset : f ------
Cls::__isset is called! ["f"]
false
====================== DUMP START ====================
    a: 0
    b: 1
    c: 2
    d: 3
    Property 0: 0
====================== DUMP STOP =====================
------ get : a ------
Cls::__get is called! ["a"]
null
------ get : b ------
Cls::__get is called! ["b"]
null
------ get : c ------
2
------ get : d ------
3
------ get : e ------
Cls::__get is called! ["e"]
null
------ get : f ------
Cls::__get is called! ["f"]
null
====================== DUMP START ====================
    a: 0
    b: 1
    c: 2
    d: 3
    Property 0: 0
====================== DUMP STOP =====================
------ set : a ------
Cls::__set is called! ["a","a-val"]
"a-val"
------ set : b ------
Cls::__set is called! ["b","b-val"]
"b-val"
------ set : c ------
"c-val"
------ set : d ------
"d-val"
------ set : e ------
Cls::__set is called! ["e","e-val"]
"e-val"
------ set : f ------
Cls::__set is called! ["f","f-val"]
"f-val"
====================== DUMP START ====================
    a: 0
    b: 1
    c: c-val
    d: d-val
    Property 0: 0
    Property a: a-val
    Property b: b-val
    Property e: e-val
    Property f: f-val
====================== DUMP STOP =====================
------ isset : a ------
Cls::__isset is called! ["a"]
true
------ isset : b ------
Cls::__isset is called! ["b"]
true
------ isset : c ------
true
------ isset : d ------
true
------ isset : e ------
Cls::__isset is called! ["e"]
true
------ isset : f ------
Cls::__isset is called! ["f"]
true
====================== DUMP START ====================
    a: 0
    b: 1
    c: c-val
    d: d-val
    Property 0: 0
    Property a: a-val
    Property b: b-val
    Property e: e-val
    Property f: f-val
====================== DUMP STOP =====================
------ unset : a ------
Cls::__unset is called! ["a"]
------ unset : b ------
Cls::__unset is called! ["b"]
------ unset : c ------
------ unset : d ------
------ unset : e ------
Cls::__unset is called! ["e"]
------ unset : f ------
Cls::__unset is called! ["f"]
====================== DUMP START ====================
Cls::__get is called! ["c"]
Cls::__get is called! ["d"]
    a: 0
    b: 1
    c: 
    d: 
    Property 0: 0
====================== DUMP STOP =====================
------ isset : a ------
Cls::__isset is called! ["a"]
false
------ isset : b ------
Cls::__isset is called! ["b"]
false
------ isset : c ------
Cls::__isset is called! ["c"]
false
------ isset : d ------
Cls::__isset is called! ["d"]
false
------ isset : e ------
Cls::__isset is called! ["e"]
false
------ isset : f ------
Cls::__isset is called! ["f"]
false
====================== DUMP START ====================
Cls::__get is called! ["c"]
Cls::__get is called! ["d"]
    a: 0
    b: 1
    c: 
    d: 
    Property 0: 0
====================== DUMP STOP =====================

特別強調,當這個屬性不存在(基於當前訪問權限)的時候,才會觸發這些方法。因此嚴重建議使用確定的鍵值進行get/set處理,特別是對應的鍵值不要有訪問權限問題,如上例中的a和b,會導致在類內部、類外部、子類內處理的方式不同,開發時產生不可預知的返回值,極易產生bug。

empty方法不能調用屬性重載方法。

$tmp = $obj->$char = $char . "-val"

此例中,__set自身的返回值將被忽略,同樣__get也不會被調用。

此外:屬性重載方法必須聲明為public,同時參數不能使用引用傳遞,靜態屬性不能通過這些方法重載,這些方法也不能被聲明為static。

當然,使用魔術方法的時候,也會對反射系統造成影響。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved