【发布时间】:2017-05-22 16:44:12
【问题描述】:
我在尝试中使用了三个技巧:
- 反射不能与动态类属性一起使用
- 访问动态类属性时必须调用__get() 或__set()
- debug_backtrace() 可以用来模拟类似于
private的东西
对于具有私有非静态属性$bar 的类Foo,我想禁止$this 之外的任何范围修改其值。因此我这样做:
/** @property object $bar */
class Foo{
public function __get($k){
if($k === "bar") return $this->bar;
}
public function __set($k, $v){
if($k === "bar"){
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
if($trace[0]["object"] !== $this or $trace[0]["file"] !== __FILE__) throw new RuntimeException("Illegal access");
$this->bar = $v;
}
}
}
这应该(未经测试)不受三种访问的影响:
- 直接访问
- debug_backtrace() 检查调用上下文是否来自 $this。不允许在 $this 之外直接访问。
- 反射属性
- PHP 致命错误:未捕获的 ReflectionException:属性栏不存在
- 反射不适用于动态属性。它甚至没有通过
ReflectionClass::hasProperty()检测到它的存在 :-)
-
Closure::bind- 未测试,但我相信 debug_backtrace() 应该返回与 FILE 不同的“文件”,而是定义闭包的文件。我只有
Foo的正确用法,所以只要加载了正确的代码,我就不管了。
- 未测试,但我相信 debug_backtrace() 应该返回与 FILE 不同的“文件”,而是定义闭包的文件。我只有
假设没有写任何文件的权限,也没有重新定义类方法的扩展名,但是可以加载任意PHP代码,有没有办法改变这个Foo->bar属性?
【问题讨论】:
-
您试图阻止从课堂外更改
$bar属性?一个简单的private $bar有什么问题? -
@RayRadin 正如我已经提到的,它可以通过反射访问。我试图通过动态属性防止反射触及它。
-
我明白了。所以你想要像
private $bar这样的行为而不在对象中声明它?
标签: php oop reflection visibility pocketmine