濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > PHP獲取類私有屬性的3種方法

PHP獲取類私有屬性的3種方法

熱門標(biāo)簽:黔江400電話如何辦理 地圖標(biāo)注視頻廣告入駐 中原區(qū)電話機(jī)器人價(jià)格 電銷機(jī)器人便宜的有嗎 OMG地圖標(biāo)注app ai電話機(jī)器人加盟代理 400電話鄭州申請(qǐng) gps 地圖標(biāo)注軟件 招標(biāo)自動(dòng)語(yǔ)音外呼系統(tǒng)

今天在推上看到一條獲取PHP類私有屬性的推文,感覺(jué)很有意思:

順著推文聯(lián)想,還有其他方式嗎?經(jīng)過(guò)自己的測(cè)試及網(wǎng)上答案,總結(jié)出三種方法:

1. 反射

反射可以獲取類的詳細(xì)信息,要獲取私有屬性的值,只需將對(duì)應(yīng)屬性的ReflectionProperty實(shí)例設(shè)置為可訪問(wèn)再取值即可。示例代碼如下:

namespace tlanyan;

class Foo {
 private $bar = "Foo bar!";
}

// 獲取反射類及反射屬性
$class = new \ReflectionClass(Foo::class);
$property = $class->getProperty("bar");
// 設(shè)置屬性可訪問(wèn)
$property->setAccessible(true);

$foo = new Foo;
// 獲取對(duì)象屬性值
// 注意:只能通過(guò) ReflectionProperty 實(shí)例的 getValue 方法訪問(wèn)
// 不能這樣直接訪問(wèn): $foo->bar;
echo $property->getValue($foo), PHP_EOL:
// 輸出: Foo bar!

本人之前寫過(guò)“PHP回顧之反射”一文,比較詳細(xì)的介紹了反射及用法,有興趣的閱讀參考。

2. 轉(zhuǎn)換成數(shù)組

這種方法用將對(duì)象強(qiáng)制轉(zhuǎn)換成數(shù)組,再通過(guò)鍵獲取其值。示例代碼如下:

class Foo {
 private $bar = "Foo bar!";
}

$foo = new Foo;
// 強(qiáng)制轉(zhuǎn)型
$attrs = (array)$foo;
// 拼接key,注意 "\0" 不能改成單引號(hào)!
$key = "\0" . Foo::class . "\0" . "bar";
echo $attrs[$key], PHP_EOL;
// 輸出: Foo bar!

上述代碼中key的拼接方式比較詭異,key規(guī)則如下:

  1. public屬性, key是 屬性名;
  2. protected屬性,key是 \0*\0屬性名;
  3. private屬性, key是 \0類名\0屬性名。

注意 \0 是一個(gè)字符(不是兩個(gè)),對(duì)應(yīng)的ASCII碼是數(shù)字0。編程時(shí)要用雙引號(hào)將其引起來(lái)。不能使用單引號(hào),否則轉(zhuǎn)義失效,那就是兩個(gè)字符。如果你有C語(yǔ)言基礎(chǔ),應(yīng)該知道 \0 就是字符串的結(jié)束符。這個(gè)符號(hào)直接輸出不會(huì)顯示,但可以通過(guò)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個(gè)字符,加上兩個(gè)不顯示字符,所以長(zhǎng)度是8

還需要注意拼接private屬性時(shí)類名應(yīng)該是 “完全限定類名” ,建議通過(guò)Foo::class的方式獲取。

與強(qiáng)制轉(zhuǎn)換成數(shù)組類似的另一種方法是serialize,但是serialize比較慢,并且序列化后的字符串更難辨認(rèn)結(jié)構(gòu)和處理,不建議使用。

3. 閉包

文章開(kāi)頭的推特截圖已經(jīng)展示了閉包的用法,其中call方法在PHP7中引入,另一個(gè)是PHP5.4引入的bindTo。callbindTo的用法示例如下:

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方法的第二個(gè)參數(shù)注意傳入對(duì)象的 “完全限定類名”,指示函數(shù)應(yīng)該放置在該類的作用域下,從而可以訪問(wèn)私有屬性。

總結(jié)

性能: 數(shù)組 > 反射 > 閉包

易用性: 閉包 > 數(shù)組 > 反射

推薦: 閉包 > 反射 > 數(shù)組

以上就是PHP獲取類私有屬性的3種方法的詳細(xì)內(nèi)容,更多關(guān)于PHP獲取類私有屬性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • PHPUnit測(cè)試私有屬性和方法功能示例
  • PHP實(shí)現(xiàn)在對(duì)象之外訪問(wèn)其私有屬性private及保護(hù)屬性protected的方法

標(biāo)簽:池州 濟(jì)源 哈密 那曲 日照 阿里 北京 孝感

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP獲取類私有屬性的3種方法》,本文關(guān)鍵詞  PHP,獲取,類,私有,屬,性的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP獲取類私有屬性的3種方法》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于PHP獲取類私有屬性的3種方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    新巴尔虎右旗| 吉木萨尔县| 阜阳市| 沿河| 普宁市| 芒康县| 孟州市| 昌图县| 务川| 黄平县| 河曲县| 民乐县| 田阳县| 阿鲁科尔沁旗| 江安县| 沁源县| 蕲春县| 梁河县| 阳江市| 密山市| 开原市| 钦州市| 迁西县| 克什克腾旗| 仁布县| 宜君县| 临沭县| 伊金霍洛旗| 安达市| 盐山县| 普格县| 息烽县| 五常市| 甘谷县| 子洲县| 屏南县| 察隅县| 金湖县| 登封市| 义马市| 中方县|