Раньше я использовал ORM сопоставленные столбцы базы данных непосредственно с свойствами класса, которые позволяли вам обладать определенной видимостью свойств, так же, как вы обычно ограничивали бы доступ к определенным свойствам, например паролям.
С Eloquent я не могу воспроизвести это, потому что столбцы базы данных отображаются в массив внутренних атрибутов, которые не содержат видимости.
Мое желание состоит в том, чтобы ограничить область доступа к паролю пользователя только для объекта, то есть личного.
Установка свойства класса с видимостью не работает, потому что это свойство выходит за пределы атрибутов модели Eloquent и, следовательно, свойство не отображается в столбец.
Яркие $ скрытые и $ охраняемые свойства не работают, поскольку они имеют дело с массовым выходом (toArray, toJSON) и массовым назначением, а не прямым назначением.
Я попытался использовать accessors / mutators (getters / seters), чтобы достичь этого со смешанными результатами.
Указание видимости на аксессоре не работает, потому что вызванный метод доступа (например, getPasswordAttribute) вызывается из метода Eloquent \ Model-> getAttribute, и поскольку такой public / protected будет всегда работать, а private всегда будет терпеть неудачу, независимо от того, где атрибут, к которому он обращался из.
Тем не менее, что работает, чтобы остановить аксессуар Eloquent, полностью возвращающий атрибут, поэтому любой запрос к $ user-> password или $ user-> getAttribute («пароль») завершается с ошибкой, а затем имеет отдельный метод с видимостью, определенным для возврата атрибут непосредственно из массива атрибутов Eloquent только в разрешенной области, например
/** * Return password string only for private scope * @return string */ private function getPassword () { return $this->attributes['password']; } /** * Don't return password with accessor * @param string $password Password * @return void * @throws Exception */ public function getPasswordAttribute ($password) { throw new Exception ('Password access denied'); }
Этот же подход также работает для мутаторов (сеттеров) для тех, кто хочет видеть видимость метода сеттера.
Правильно ли это, или есть лучший способ «Laravel-Approved» справиться с этим? 🙂
Я не знаю об «одобренном» способе делать это, как таковой, но вы всегда можете переопределить магический метод __get()
Eloquent, чтобы проверить частные поля?
debug_backtrace()
немного взломана; Я не мог заставить это работать так, как ожидалось, так как метод getPassword()
(или вообще любой метод в этом классе, вызывающий $this->password
) все еще использовал __get
. Это просто проверяет, что класс, вызывающий __get
является самим классом, а не другим.
Он не должен быть слишком неэффективным, поскольку проверка in_array завершится неудачей для неличных свойств, прежде чем он будет делать обратную линию в любом случае. Хотя, вероятно, это лучший способ сделать это!
private $private = array( 'password' ); public function __get($key) { // check that the class calling __get is this class, and the key isn't 'private' if (in_array($key, $this->private) && debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] != get_class()) { throw new \Exception('Private'); } // anything else can return as normal return parent::__get($key); } public function getPassword() { // calling this method elsewhere should work return $this->password; }