php __set __get __isset __unset用法防被忽悠分析
來源:程序員人生 發布時間:2014-12-16 08:40:00 閱讀次數:2820次
大家好我是小煙 今天分享下 php面向對象中__set __get __isset __unset用法之防忽悠介紹
全文注意=====================================
__set __get __isset __unset 這些方法 老版本php是可以設置成私有的 但是現在php版本 最好不要設置成私有 更不能設置成靜態 設置成靜態方法直接就出錯了 設置成私有的話 雖然能正常返回值 但是會有個 Warning
正告!!(本人是php5.5版本)

正文開始======================================
我們常常會在php的面向對象中可以看到位__set __get __isset __unset這些東西的用法,但很不明白為何會要用這些東西,下面我們來逐一介紹1下他們哥4的用法吧。
1般來講,總是把類的屬性定義為private,這更符合現實的邏輯。但是,對屬性的讀取和賦值操作是非常頻繁的,因此在PHP5中,預定義了兩個函數“__get()”和“__set()”來獲得和賦值其屬性,和檢查屬性的“__isset()”和刪除屬性的方法“__unset()”。
我們為每一個屬性做了設置和獲得的方法,在PHP5中給我們提供了專門為屬性設置值和獲得值的方法,“__set()”和“__get()”這兩個方法,這兩個方法不是默許存在的,而是我們手工添加到類里面去的,像構造方法(__construct())1樣, 類里面添加了才會存在,可以按下面的方式來添加這兩個方法,固然也能夠按個人的風格來添加:
public function __get($property_name){
if(isset($this->$property_name)){
return($this->$property_name);
}else{
return(NULL);
}
}
//__set()方法用來設置私有屬性
public function __set($property_name, $value){
$this->$property_name = $value;
}
__get()方法:這個方法用來獲得私有成員屬性值的,有1個參數,參數傳入你要獲得的成員屬性的名稱,返回獲得的屬性值,這個方法不用我們手工的去調用,由于我們也能夠把這個方法做成私有的方法,是在直接獲得私有屬性的時候對象自動調用的。由于私有屬性已被封裝上了,是不能直接獲得值的(比如:"echo $p1->name"這樣直接獲得是毛病的),但是如果你在類里面加上了這個方法,在使用"echo $p1->name"這樣的語句直接獲得值的時候就會自動調用__get($property_name)方法,將屬性name傳給參數$property_name,通過這個方法的內部履行,返回我們傳入的私有屬性的值。如果成員屬性不封裝成私有的,對象本身就不會去自動調用這個方法。
基本上網上 99%的文章 介紹 __get() 都是這么說的 但是我還要說最關鍵的是 __get() 不光只是獲得當前類的私有成員變量
還能在這個方法里面 做其他操作 比如說 實例化另外一個類 獲得另外一個類的對象。 請看下面代碼
public function __get($name) {
return LibsComponents::getInstance()->$name;
}
這里 如果 獲得name 其實不是獲得當前類的 私有屬性 而且靜態調用 Components類 里面的 $name 屬性 所以 __get 方法1定要靈活應用 還有就是 __get() 方法不只是調用當前類的私有變量
public function __get($name) {
if(isset($this->config[$name])) {
return $this->config[$name];
}
return null;
}
也還能這么用 指定 要獲得的 變量!!
乃至 還能在類里面用 請看下面代碼
class b {
private $config = ['aa'=>'小煙'];
public function __get($key) {
if($this->config[$key]) return $this->config[$key];
}
public function __construct() {
echo $this->aa;
}
}
$b = new b(); //輸出 小煙
類里面 $this->bb 根本不存在 就會在類里面觸發 __get 方法 返回config 里面的 aa 從而返回內容
__set()方法:這個方法也是用來取得你指定的變量 1般來說都是獲得類里面的私有變量,有兩個參數,第1個參數為你要為設置值的屬性名,第2個參數是要給屬性設置的值,沒有返回值。,
如果沒有__set()這個方法,是不允許直接獲得私有變量的,比如:$this->name='zhangsan', 這樣會出錯,但是如果你在類里面加上了__set($property_name, $value)這個方法,在直接給私有屬性賦值的時候,就會自動調用它,把屬性比如name傳給$property_name, 把要賦的值"zhangsan"傳給$value,通過這個方法的履行,到達賦值的目的。如果成員屬性不封裝成私有的,對象本身就不會去自動調用這個方法。為了不傳入非法的值,還可以在這個方法給做1下判斷。代碼以下:
<?php
class Person{
private $name;
private $sex;
private $age;
private
function __get($property_name){
echo "在直接獲得私有屬性值的時候,自動調用了這個__get()方法<br>";
if (isset($this->$property_name)) {
return ($this->$property_name);
} else {
return null;
}
}
private
function __set($property_name, $value) {
echo "在直接設置私有屬性值的時候,自動調用了這個__set()方法為私有屬性賦值<br>";
$this->$property_name = $value;
}
}
$p1 = new Person();
$p1->name = "小煙";
$p1->sex = "男";
$p1->age = 23;
echo "姓名:".$p1->name."<br>";
echo "性別:".$p1->sex."<br>";
echo "年齡:".$p1->age."<br>";
程序履行結果:
在直接設置私有屬性值的時候,自動調用了這個__set()方法為私有屬性賦值
在直接設置私有屬性值的時候,自動調用了這個__set()方法為私有屬性賦值
在直接設置私有屬性值的時候,自動調用了這個__set()方法為私有屬性賦值
在直接獲得私有屬性值的時候,自動調用了這個__get()方法
姓名:小煙
在直接獲得私有屬性值的時候,自動調用了這個__get()方法
性別:男
在直接獲得私有屬性值的時候,自動調用了這個__get()方法
年齡:23
以上代碼如果不加上__get()和__set()方法,程序就會出錯,由于不能在類的外部操作私有成員,而上面的代碼是通過自動調用__get()和__set()方法來幫助我們直接存取封裝的私有成員的。
__isset() 方法:在看這個方法之前我們看1下"isset()"函數的利用,isset()是測定變量是不是設定用的函數,傳入1個變量作為參數,如果傳入的變量存在則傳回true,否則傳回false。
那末如果在1個對象外面使用"isset()"這個函數去測定對象里面的成員是不是被設定可不可以用它呢?分兩種情況,如果對象里面成員是公有的,我們就能夠使用這個函數來測定成員屬性,如果是私有的成員屬性,這個函數就不起作用了,緣由就是由于私有的被封裝了,在外部不可見。那末我們就不可以在對象的外部使用"isset()"函數來測定私有成員屬性是不是被設定了呢?
答案是可以的,你只要在類里面加上1個"__isset()"方法就能夠了,當在類外部使用"isset()"函數來測定對象里面的私有成員是不是被設定時,就會自動調用類里面的"__isset()"方法了幫我們完成這樣的操作,"__isset()"方法也能夠做成私有的。你可以在類里面加上下面這樣的代碼就能夠了:
private function __isset($nm){
echo "當在類外部使用isset()函數測定私有成員$nm時,自動調用<br>";
return isset($this->$nm);
}
__unset()方法:看這個方法之前呢,我們也先來看1下"unset()"這個函數,"unset()"這個函數的作用是刪除指定的變量且傳回true,參數為要刪除的變量。那末如果在1個對象外部去刪除對象內部的成員屬性用"unset()"函數可不可以呢,也是分兩種情況,如果1個對象里面的成員屬性是公有的,就能夠使用這個函數在對象外面刪除對象的公有屬性,如果對象的成員屬性是私有的,我使用這個函數就沒有權限去刪除,但一樣如果你在1個對象里面加上"__unset()"這個方法,就能夠在對象的外部去刪除對象的私有成員屬性了。
在對象里面加上了"__unset()"這個方法以后,在對象外部使用"unset()"函數刪除對象內部的私有成員屬性時,自動調用"__unset()"函數來幫
我們刪除對象內部的私有成員屬性,這個方法也能夠在類的內部定義成私有的。在對象里面加上下面的代碼就能夠了:
private function __unset($nm){
echo "當在類外部使用unset()函數來刪除私有成員時自動調用的<br>";
unset($this->$nm);
}
最后,我們來看1個完全的實例:
<?php
class Person {
private $name;
private $sex;
private $age;
public function __get($property_name) {
if(isset($this->$property_name))
{
return ($this->$property_name);
} else {
return (NULL);
}
}
public function __set($property_name, $value) {
$this->$property_name = $value;
}
public function __isset($nm) {
echo "isset()函數測定私有成員時,自動調用<br>";
return isset($this->$nm);
}
public function __unset($nm) {
echo "當在類外部使用unset()函數來刪除私有成員時自動調用的<br>";
unset($this->$nm);
}
}
$p1 = new Person();
$p1->name = "this is a person name";
echo var_dump(isset($p1->name))."<br>";
echo $p1->name."<br>";
unset($p1->name);
echo $p1->name;
輸出結果為:
isset()函數測定私有成員時,自動調用
bool(true)
this is a person name
當在類外部使用unset()函數來刪除私有成員時自動調用的
isset()函數測定私有成員時,自動調用
最后最后 小煙還是要提示下你 這4個方法用法都是非常的靈活的 不要以為只能獲得類里面的私有變量 而且可以自由擴大 獲得類里某個特定成員變量的值 或 其他類里面的值切記切記 不要被誤導!!
小煙 2014⑴2-03 轉載請注明出處 謝謝!
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈