Я использую три уловки в моей попытке:
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;
}
}
}
Это должно быть (не проверено) неуязвимым для трех видов доступа:
ReflectionClass::hasProperty()
🙂Closure::bind
Foo
, так что мне все равно, пока правильный код загружен.Предполагая, что нет разрешения на запись каких-либо файлов и нет расширения для переопределения методов класса, но можно загрузить произвольный код PHP, есть ли способы изменить это Foo->bar
имущество?
Немного поработав, я пришел к выводу, что то, что вы пытаетесь достичь, невозможно, а также бессмысленно.
Я объясню почему.
Свойство класса имеет 3 возможных видимости: общественности, защищенный, а также частный.
Если это общественности, Вы можете изменить значение с помощью простого присваивания:
$foo->bar = "new value";
Можем ли мы перехватить это с __set()
? От Руководство по PHP:
__set () запускается при записи данных в недоступные свойства.
общественности Недвижимость всегда доступна.
Поэтому у вас просто нет возможности перехватить и выполнить ваши проверки, потому что __set()
не будет называться.
Далее, если свойство защищенный или же частный, Вы должны объявить это в классе,
что означает, что вы можете использовать ReflectionProperty
или же Closure::bind
изменить его значение.
Наконец, вы можете убедиться, что __set()
вызывается путем сохранения значения в другом месте.
Например, под другим именем в том же объекте или даже в другом объекте.
К сожалению, независимо от того, где вы храните значение, мое объяснение выше применимо снова, поэтому оно бессмысленно.
Других решений пока нет …