當前位置:首頁 >  站長 >  編程技術(shù) >  正文

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

 2020-10-30 13:42  來源: 腳本之家   我來投稿 撤稿糾錯

  阿里云優(yōu)惠券 先領(lǐng)券再下單

這篇文章主要介紹了PHP獲取類私有屬性的3種方法,幫助大家更好的理解和使用php,感興趣的朋友可以了解下

今天在推上看到一條獲取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)注腳本之家其它相關(guān)文章!

來源:腳本之家

鏈接:https://www.jb51.net/article/195305.htm

申請創(chuàng)業(yè)報道,分享創(chuàng)業(yè)好點子。點擊此處,共同探討創(chuàng)業(yè)新機遇!

相關(guān)標簽
php教程

相關(guān)文章

  • PHP8的數(shù)據(jù)類型轉(zhuǎn)換-PHP8知識詳解

    什么是數(shù)據(jù)類型轉(zhuǎn)換?答:數(shù)據(jù)從一個類型轉(zhuǎn)換成另外一個類型,就是數(shù)據(jù)類型轉(zhuǎn)換。在PHP8中,變量的類型就是由賦值決定的,也就是說,如果string賦值給$var,然后$var的類型就是string。之后將int值賦值給$var,它將是int類型。列如:在上面的代碼中的“=”不是數(shù)學里面的“等于”,它是

    標簽:
    php教程
  • 在PHP8中檢測數(shù)據(jù)類型-PHP8知識詳解

    在PHP8中,可以使用多種方法來檢測數(shù)據(jù)類型。以下是常用的四種方法:使用gettype()函數(shù)、使用is_*系列函數(shù)、使用get_debug_type()函數(shù)、使用get_class()函數(shù)。一、使用gettype()函數(shù)gettype()函數(shù)返回給定變量的數(shù)據(jù)類型。例如:二、使用is_*系列函數(shù)P

    標簽:
    php教程
  • PHP語言優(yōu)勢-PHP8知識詳解

    PHP起源于自由軟件,并且得到了不斷的迭代更新,在web開發(fā)領(lǐng)域獨領(lǐng)風騷,得到了廣大使用者的喜愛,PHP作為一款優(yōu)秀的腳本語言,具有以下優(yōu)勢:1、源碼開源:所有的PHP源代碼,你都能從PHP官方網(wǎng)站下載到,可以快速修改和利用。2、完全免費:你可以從PHP官方網(wǎng)站下載源碼完全免費,無需支付任何費用,直

    標簽:
    php教程
  • PHP8的新特性-PHP8知識詳解

    PHP8是PHP編程語言的一個主要版本,在2020年11月26日發(fā)布。它引入了許多新特性和改進,包括以下一些主要特性:1.JIT編譯器:PHP8引入了名為TracingJIT的即時(Just-In-Time)編譯器。JIT可以將PHP腳本中頻繁執(zhí)行的部分編譯成原生機器碼,提高執(zhí)行速度。2.類型系統(tǒng)改

    標簽:
    php教程
  • PHP是什么-PHP8知識詳解

    PHP是什么?PHP服務(wù)網(wǎng)從下面幾點為你講清楚什么是PHP。1、PHP最開始是PersonalHomePage(個人主頁)的縮寫,已經(jīng)正式更名為“PHP:HypertextPreprocessor”,超文本預處理器的字母縮寫。2、PHP是一種被廣泛應(yīng)用的、跨平臺、開放源代碼的多用途服務(wù)器端腳本語言,

    標簽:
    php教程

熱門排行

信息推薦