PHP中的重載和別的物件導向(C#、Java)語言不同,如:在C#中的重載表示,具有相同的方法名,但是形參列表不同(即形參的個數、類型、相片順序中的一個不同)函數,會在調用時根據形參列表來決定該調用那個方法。
而在PHP中重載是針對當前對象不可訪問成員(沒有定義或者定義了但訪問不到)的處理:
<?phpClass Student{private $_age;}$o1=new Student();$o1->_name="Li";var_dump($o1);echo "<br/>";$o1->_age=24;var_dump($o1); ?>
從這個結果我們可以看出:當訪問不存在的成員$_name時,會把成員當做共有屬性放入對象中。而涉及到存取權限問題時,會報錯。
對於這種情況,php中有一些屬性重載的魔術方法:
屬性重載
1.__set($name,$value):當調用的某個屬性不可訪問(並不存在/訪問受限)時,系統會自動調用該對應類中的__set()函數。$name表示調用的屬性名稱,$value 代表操作時傳入的值。
如果屬性不存在:
<?phpClass Student{private $_age;function __set($name,$value){}}$o1=new Student();$o1->_name="Li";var_dump($o1);
這裡當我們將上面的例子做一些改變:在Student類中添加一個__set()方法,當執行$o1->_name="Li";這條代碼時,會自動調用__set()方法。由於裡面沒有任何代碼,無法實現像預設情況一樣的賦值,因此顯示的$o1對象中只有一個私人屬性$_age;
也可以在__set()方法中寫上該代碼:
function __set($name,$value){$this->$name=$value;}
此時的結果為
如果屬性存在,但是其無法訪問:
<?phpheader("Content-Type:text/html;charset=utf-8");Class Student{private $_age;function __set($name,$value){//進入該函數表示$name 這個屬性不可訪問。if(property_exists($this,$name)){//property_exists()函數判斷當前對象($this)中是否存在$name屬性。trigger_error("屬性不可訪問!",E_USER_ERROR);}else{}}}$o1=new Student();$o1->_age=2;var_dump($o1);
2.__get():當訪問不可訪問成員的時候會觸發:
<?phpheader("Content-Type:text/html;charset=utf-8");Class Student{private $_age=23;function __get($name){//進入該函數表示$name 這個屬性不可訪問。return $this->$name;}}$o1=new Student();echo $o1->_age;echo "<br/>";var_dump($o1);
3.__unset():當刪除某個變數時會觸發該函數。
其具體的應用情境:我們都知道unset()函數,即刪除某一個變數,這也可以用到對象中,例如我們上面的例子中,如果$_age為public,那麼可以用unset($o1->_age);但是,這裡的$_age 是一個private屬性,此時用unset()肯定無法訪問。
<?phpheader("Content-Type:text/html;charset=utf-8");Class Student{private $_age=23;}$o1=new Student();unset($o1->_age);
這就需要__unset()魔術方法,在類中實現屬性的刪除:
<?phpheader("Content-Type:text/html;charset=utf-8");Class Student{private $_age=23;function __get($name){return $this->$name;//正常應該有判斷語句,這裡省略了。}function __unset($name){unset($this->$name);}}$o1=new Student();echo $o1->_age;unset($o1->_age);echo $o1->_age;
其具體的應用和上面的__set()、__get()類似,即當你unset(變數名);時,會自動調用__unset()方法,方法體可以自己定義。
4.__isset():主要是用來判斷是否存在屬性,跟__unset()用法一樣。當外部想要判斷是有屬性的時候,用isset()函數無法訪問私人變數,此時可以使用__isset()方法定義。
重載方法
方法重載和屬性重載的條件一樣:當調用不存在或者無法訪問的方法時,會調用__call()、Static__callStatic()方法。
在系統預設的情況下調用本不存在的方法:
<?phpheader("Content-Type:text/html;charset=utf-8");Class Student{public static $a=1;private $_age=23;}$o1=new Student();$o1->getName();//當調用本不存在的方法時。
系統會出現一個嚴重錯誤。
__call():使用對象調用時使用的魔術方法
<?phpheader("Content-Type:text/html;charset=utf-8");Class Student{public static $a=1;private $_age=23;function __call($name,$arr){//$name表示傳入的方法名,$arr表示傳入的方法列表(是一個數組)。trigger_error("不存在該函數",E_USER_NOTICE);//直接報錯//也可以在此重寫函數。}}$o1=new Student();$o1->getName();//當調用本不存在的方法時。
Static__callStatic():使用類調用方法,即調用一個本不存在的靜態方法時,可以使用該魔術方法。