Видимость атрибутов модели Laravel / Eloquent Model

Раньше я использовал 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» справиться с этим? 🙂

Solutions Collecting From Web of "Видимость атрибутов модели Laravel / Eloquent Model"

Я не знаю об «одобренном» способе делать это, как таковой, но вы всегда можете переопределить магический метод __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; }