2024 日本 PHP 研討會

ReflectionProperty::setAccessible

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

ReflectionProperty::setAccessible設定屬性存取權限

說明

公開 ReflectionProperty::setAccessible(布林值 $accessible):

透過 ReflectionProperty::getValue()ReflectionProperty::setValue() 方法啟用對受保護或私有屬性的存取。

注意: 從 PHP 8.1.0 開始,呼叫此方法無效;所有屬性預設皆可存取。

參數

accessible

true 表示允許存取,或 false

回傳值

不回傳任何值。

範例

範例 #1 簡單的類別定義

<?php
class MyClass
{
private
$foo = 'bar';
}

$property = new ReflectionProperty("MyClass", "foo");
$property->setAccessible(true);

$obj = new MyClass();
echo
$property->getValue($obj);
echo
$obj->foo;
?>

上述範例將輸出類似以下的內容

bar
Fatal error: Uncaught Error: Cannot access private property MyClass::$foo in /in/WJqTv:12

另請參閱

新增註解

使用者貢獻的註解 3 則註解

41
matthieu at mnapoli dot fr
12 年前
請注意,該屬性僅能透過 ReflectionProperty 類別存取。在類別實例中,該屬性仍然是私有或受保護的。

<?php
class MyClass {
private
$myProperty = true;
}

$class = new ReflectionClass("MyClass");
$property = $class->getProperty("myProperty");
$property->setAccessible(true);

$obj = new MyClass();
echo
$property->getValue($obj); // 可以運作
echo $obj->myProperty; // 無法運作 (錯誤)
?>
3
Rob McVey
14 年前
如果你使用 PHP 5.3 以前的版本,並且需要取得私有屬性及其值,你可以使用這個方法

這是你正在做的

<?php
$obj_with_privates
= new MyObject();
$class = get_class($obj_with_privates);
$vars = get_object_vars($obj_with_privates);
//不會顯示私有屬性
print_r($vars);

$reflection = new ReflectionClass( $class );
$attributes = $reflection->getProperties();
//仍然無法存取私有屬性!
print_r($attributes);
?>

這是你應該做的

<?php
$obj_with_privates
= new MyObject();

$class = get_class( $obj_with_privates );
$reflection = new ReflectionClass( $class );
$abstract = $reflection->getMethods( ReflectionMethod::IS_ABSTRACT );
$priv_attr = $reflection->getProperties( ReflectionProperty::IS_PRIVATE );
$privates = array();
$parent = get_parent_class( $class );
$child = $class;
$constructor = $reflection->getConstructor();

//If the class has abstract methods you need to implement them
$abstr_methods = "";
if(
sizeof($abstr_methods))
{
foreach(
$abstract as $method)
{
$mname = $method->name;
$abstr_methods .= "public function $mname(){return false;}";
}
}

//Convert private attributes to public attributes
if(sizeof($priv_attr))
{
$parseable = unserialize(str_replace("\0$class\0", "\0*\0", serialize($obj)));
foreach(
$priv_attr as $attribute)
{
$aname = $attribute->name;
$privates[$aname] = $parseable->$aname;
}
}


$temp_child_class = "temp" . str_replace("_", "", "$class");

//You can gain access to protected attributes by extending the target class
$class_def = "
class
$temp_child_class extends $class{
$constructor
public function reflect_getmyvars(){
return get_object_vars(\$this);
}
$abstr_methods
}
"
;

//place class definition in memory
eval($class_def);

//generate object from dynamic class
$tcobj =@ new $temp_child_class;
//call the method we added to the object (to access protected vars)
$vars = $tcobj->reflect_getmyvars();

$attribs = array_merge($vars, $privates);

//will now show private attributes
print_r($attribs);
?>
2
Yzmir Ramirez
14 年前
你試過這個方法嗎?

<?php

echo "PHP 版本: ".phpversion()."\n";

class
Foo
{
private
$bar = "private";
protected
$bar2 = "protected";
public
$bar3 = "public";
}

$obj = new Foo;

$arr = (array)$obj;

print_r($arr);
?>

輸出

PHP 版本: 5.2.12
陣列
(
[Foobar] => private
[*bar2] => protected
[bar3] => public
)

PHP 版本: 5.1.6
陣列
(
[Foobar] => private
[*bar2] => protected
[bar3] => public
)
To Top