我在尝试中使用了三个技巧:
- 反射不能与动态类属性一起使用
- 访问动态类属性时必须调用 __get() 或 __set()
- debug_backtrace() 可以用来模拟类似的东西
private
对于Foo
具有私有非静态属性的类$bar
,我想禁止外部$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
属性?