PHP獲取類私有屬性的3種方法
今天在推上看到一條獲取PHP類私有屬性的推文,感覺很有意思:
順著推文聯(lián)想,還有其他方式嗎?經(jīng)過自己的測試及網(wǎng)上答案,總結(jié)出三種方法:
1. 反射
反射可以獲取類的詳細信息,要獲取私有屬性的值,只需將對應(yīng)屬性的ReflectionProperty實例設(shè)置為可訪問再取值即可。示例代碼如下:
namespace tlanyan;class Foo { private $bar = 'Foo bar!';}// 獲取反射類及反射屬性$class = new ReflectionClass(Foo::class);$property = $class->getProperty('bar');// 設(shè)置屬性可訪問$property->setAccessible(true);$foo = new Foo;// 獲取對象屬性值// 注意:只能通過 ReflectionProperty 實例的 getValue 方法訪問// 不能這樣直接訪問: $foo->bar;echo $property->getValue($foo), PHP_EOL:// 輸出: Foo bar!
本人之前寫過“PHP回顧之反射”一文,比較詳細的介紹了反射及用法,有興趣的閱讀參考。
2. 轉(zhuǎn)換成數(shù)組
這種方法用將對象強制轉(zhuǎn)換成數(shù)組,再通過鍵獲取其值。示例代碼如下:
class Foo { private $bar = 'Foo bar!';}$foo = new Foo;// 強制轉(zhuǎn)型$attrs = (array)$foo;// 拼接key,注意 '0' 不能改成單引號!$key = '0' . Foo::class . '0' . 'bar';echo $attrs[$key], PHP_EOL;// 輸出: Foo bar!
上述代碼中key的拼接方式比較詭異,key規(guī)則如下:
public屬性, key是 屬性名; protected屬性,key是 0*0屬性名; private屬性, key是 0類名0屬性名。注意 0 是一個字符(不是兩個),對應(yīng)的ASCII碼是數(shù)字0。編程時要用雙引號將其引起來。不能使用單引號,否則轉(zhuǎn)義失效,那就是兩個字符。如果你有C語言基礎(chǔ),應(yīng)該知道 0 就是字符串的結(jié)束符。這個符號直接輸出不會顯示,但可以通過strlen或者ord讓其現(xiàn)形:
foreach ($attrs as $key => $value) { echo 'key:$key', ', key length:', strlen($key), ', ascii: '; for ($i = 0; $i < strlen($key); ++ $i) { echo ord($key[$i]), ' '; } echo PHP_EOL;}// 輸出// key:Foobar, key length:8, ascii: 0 70 111 111 0 98 97 114// Foobar 有6個字符,加上兩個不顯示字符,所以長度是8
還需要注意拼接private屬性時類名應(yīng)該是 “完全限定類名” ,建議通過Foo::class的方式獲取。
與強制轉(zhuǎn)換成數(shù)組類似的另一種方法是serialize,但是serialize比較慢,并且序列化后的字符串更難辨認結(jié)構(gòu)和處理,不建議使用。
3. 閉包
文章開頭的推特截圖已經(jīng)展示了閉包的用法,其中call方法在PHP7中引入,另一個是PHP5.4引入的bindTo。call和bindTo的用法示例如下:
namespace tlanyan;class Foo { private $bar = 'Foo bar!';}$foo = new Foo;// 閉包(匿名函數(shù))是PHP5.3引入的功能$closure = function() { return $this->bar; };// PHP5.4起支持bindTo方法$method = $closure->bindTo($foo, Foo::class);echo $method(), PHP_EOL;// PHP7引入call方法,可綁定this直接執(zhí)行echo $closure->call($foo), PHP_EOL;
bindTo方法的第二個參數(shù)注意傳入對象的 “完全限定類名”,指示函數(shù)應(yīng)該放置在該類的作用域下,從而可以訪問私有屬性。
總結(jié)
性能: 數(shù)組 > 反射 > 閉包
易用性: 閉包 > 數(shù)組 > 反射
推薦: 閉包 > 反射 > 數(shù)組
以上就是PHP獲取類私有屬性的3種方法的詳細內(nèi)容,更多關(guān)于PHP獲取類私有屬性的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. 什么是Python變量作用域2. Android 實現(xiàn)徹底退出自己APP 并殺掉所有相關(guān)的進程3. Vue實現(xiàn)仿iPhone懸浮球的示例代碼4. js select支持手動輸入功能實現(xiàn)代碼5. Android studio 解決logcat無過濾工具欄的操作6. vue使用moment如何將時間戳轉(zhuǎn)為標準日期時間格式7. bootstrap select2 動態(tài)從后臺Ajax動態(tài)獲取數(shù)據(jù)的代碼8. 一個 2 年 Android 開發(fā)者的 18 條忠告9. PHP正則表達式函數(shù)preg_replace用法實例分析10. vue-drag-chart 拖動/縮放圖表組件的實例代碼
