Можно ли действительно ограничить доступ к этой частной собственности?

Я использую три уловки в моей попытке:

  • Отражения нельзя использовать со свойствами динамического класса
  • __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. Прямой доступ за пределы $ будет запрещен.
  • ReflectionProperty
    • Неустранимая ошибка PHP: Uncaught ReflectionException: панель свойств не существует
    • Отражения не работают с динамическими свойствами. Он даже не обнаруживает существование этого через ReflectionClass::hasProperty() 🙂
  • Closure::bind
    • Не проверено, но я считаю, что debug_backtrace () должна возвращать «файл», отличающийся от ФАЙЛ, скорее файл, который определил Закрытие. У меня есть только правильное использование Foo, так что мне все равно, пока правильный код загружен.

Предполагая, что нет разрешения на запись каких-либо файлов и нет расширения для переопределения методов класса, но можно загрузить произвольный код PHP, есть ли способы изменить это Foo->bar имущество?

0

Решение

Немного поработав, я пришел к выводу, что то, что вы пытаетесь достичь, невозможно, а также бессмысленно.
Я объясню почему.

Свойство класса имеет 3 возможных видимости: общественности, защищенный, а также частный.
Если это общественности, Вы можете изменить значение с помощью простого присваивания:

$foo->bar = "new value";

Можем ли мы перехватить это с __set()? От Руководство по PHP:

__set () запускается при записи данных в недоступные свойства.

общественности Недвижимость всегда доступна.
Поэтому у вас просто нет возможности перехватить и выполнить ваши проверки, потому что __set() не будет называться.

Далее, если свойство защищенный или же частный, Вы должны объявить это в классе,
что означает, что вы можете использовать ReflectionProperty или же Closure::bind изменить его значение.

Наконец, вы можете убедиться, что __set() вызывается путем сохранения значения в другом месте.
Например, под другим именем в том же объекте или даже в другом объекте.
К сожалению, независимо от того, где вы храните значение, мое объяснение выше применимо снова, поэтому оно бессмысленно.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]