請注意,會返回繼承的屬性,但不會返回父類別的私有屬性。根據使用案例,您也需要檢查這一點。
do {
foreach ($reflectionClass->getProperties() as $property) {
/* ... */
}
} while ($reflectionClass = $reflectionClass->getParentClass());
(PHP 5, PHP 7, PHP 8)
ReflectionClass::getProperties — 取得屬性
一個 ReflectionProperty 物件的陣列。
版本 | 說明 |
---|---|
7.2.0 |
filter 現在可以為 null。 |
範例 #1 ReflectionClass::getProperties() 過濾範例
此範例示範了可選參數 filter
的用法,它實際上跳過了私有屬性。
<?php
class Foo {
public $foo = 1;
protected $bar = 2;
private $baz = 3;
}
$foo = new Foo();
$reflect = new ReflectionClass($foo);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
foreach ($props as $prop) {
print $prop->getName() . "\n";
}
var_dump($props);
?>
上述範例將輸出類似以下的內容
foo bar array(2) { [0]=> object(ReflectionProperty)#3 (2) { ["name"]=> string(3) "foo" ["class"]=> string(3) "Foo" } [1]=> object(ReflectionProperty)#4 (2) { ["name"]=> string(3) "bar" ["class"]=> string(3) "Foo" } }
請注意,會返回繼承的屬性,但不會返回父類別的私有屬性。根據使用案例,您也需要檢查這一點。
do {
foreach ($reflectionClass->getProperties() as $property) {
/* ... */
}
} while ($reflectionClass = $reflectionClass->getParentClass());
第一個範例中的程式碼實際上確實使用至少 php 5.5.9 取得了繼承的屬性。我不知道這個行為是否/何時發生了變化。
以下是輸出
array(2) {
[0] =>
class ReflectionProperty#2 (2) {
public $name =>
string(2) "a2"
public $class =>
string(2) "AA"
}
[1] =>
class ReflectionProperty#3 (2) {
public $name =>
字串(2) "a1"
public $class =>
字串(1) "A"
}
}
有些人可能會覺得這很有用。
<?php
/**
* Recursive function to get an associative array of class properties by property name => ReflectionProperty() object
* including inherited ones from extended classes
* @param string $className Class name
* @param string $types Any combination of <b>public, private, protected, static</b>
* @return array
*/
function getClassProperties($className, $types='public'){
$ref = new ReflectionClass($className);
$props = $ref->getProperties();
$props_arr = array();
foreach($props as $prop){
$f = $prop->getName();
if($prop->isPublic() and (stripos($types, 'public') === FALSE)) continue;
if($prop->isPrivate() and (stripos($types, 'private') === FALSE)) continue;
if($prop->isProtected() and (stripos($types, 'protected') === FALSE)) continue;
if($prop->isStatic() and (stripos($types, 'static') === FALSE)) continue;
$props_arr[$f] = $prop;
}
if($parentClass = $ref->getParentClass()){
$parent_props_arr = getClassProperties($parentClass->getName());//RECURSION
if(count($parent_props_arr) > 0)
$props_arr = array_merge($parent_props_arr, $props_arr);
}
return $props_arr;
}
//USAGE
class A{
public $a1;
function abc(){
//do something
}
}
class AA extends A{
public $a2;
function edf(){
//do something
}
}
class AAA extends AA{
//may not have extra properties, but may have extra methods
function ghi(){
//ok
}
}
//$ref = new ReflectionClass('AAA'); $props = $ref->getProperties();//This will get no properties!
$props_arr = getClassProperties('AAA', 'public');//Use this
var_dump($props_arr);
/*
OUTPUT on PHP5.2.6:
array
'a1' =>
object(ReflectionProperty)[4]
public 'name' => string 'a1' (length=2)
public 'class' => string 'AAA' (length=3)
'a2' =>
object(ReflectionProperty)[3]
public 'name' => string 'a2' (length=2)
public 'class' => string 'AAA' (length=3)
*/
?>
需要注意的是,getProperties(filter) 方法中的 'filter' 參數預期是 long 類型。不知道為什麼,但它不能用作傳入字串以透過字串匹配來獲取屬性子集的方式。
看起來您可以透過將物件轉換為陣列來存取 public、protected、private 變數(可用於單元測試)。但是,轉換為陣列仍然不允許您存取 protected 和 private 的靜態變數。
在 PHP 5.3.0+ 中使用 ReflectionProperty::setAccessable(true);
<?php
echo "PHP 版本: ".phpversion()."\n";
class Foo {
public $foo = 'public';
protected $bar = 'protected';
private $baz = 'private';
public static $sfoo = 'public static';
protected static $sbar = 'protected static';
private static $sbaz = 'private static';
const COO = 'const';
}
$obj = new Foo;
$arr = (array)$obj;
print_r($arr);
echo "存取 Public Static: ".Foo::$sfoo."\n";
// echo Foo::$sbar."\n"; // 致命錯誤:無法存取 protected 屬性 Foo::$sbar
// echo Foo::$sbaz."\n"; // 致命錯誤:無法存取 private 屬性 Foo::$sbaz
echo "存取常數: ".Foo::COO."\n";
?>
PHP 版本: 5.2.12
陣列
(
[foo] => public
[*bar] => protected
[Foobaz] => private
)
存取 Public Static: public static
存取常數: const
PHP 版本: 5.1.6
陣列
(
[foo] => public
[*bar] => protected
[Foobaz] => private
)
存取 Public Static: public static
存取常數: const
使用 PHP 5.3,可以使用 setAccessible() 輕鬆存取 protected 或 private 屬性。然而,有時需要它(例如單元測試),這裡有一個 getValue() 的解決方法
<?php
$class = new ReflectionClass('SomeClass');
$props = $class->getProperties();
// $propsStatic = $class->getStaticProperties();
$myPrivatePropertyValue = $props['aPrivateProperty'];
?>
請注意,如果您直接使用 getProperty() 存取屬性,則它將無法正常運作。