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

Ранее в ORM, которые я использовал, столбцы базы данных отображались непосредственно в свойствах класса, что позволяло вам видеть определенные свойства, так же, как вы обычно ограничивали бы доступ к определенным свойствам, например. пароли.

С Eloquent я не могу воспроизвести это, потому что столбцы базы данных сопоставлены с массивом внутренних атрибутов, которые не содержат видимости.

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

Установка свойства класса с видимостью не работает, потому что это свойство выходит за рамки атрибутов модели Eloquent и, следовательно, свойство не отображается в столбце.

Eloquent $ hidden и $ guarded свойства не работают, так как они имеют дело с массовым выводом (toArray, toJSON) и массовым назначением, а не прямым назначением.

Я пытался использовать аксессоры / мутаторы (геттеры / сеттеры) для достижения этого со смешанными результатами.

Задание видимости для метода доступа не работает, поскольку вызываемый метод метода доступа (например, getPasswordAttribute) вызывается из метода Eloquent \ Model-> getAttribute, поэтому открытый / защищенный метод всегда будет работать, а закрытый всегда будет зависать независимо от того, к какому атрибуту он обращался. от.

Однако работает то, что средство доступа Eloquent не может вернуть атрибут вообще, поэтому любой запрос к $ user-> password или $ user-> getAttribute (‘password’) завершается неудачно, а затем создается отдельный метод с видимостью, определенной для возврата атрибут непосредственно из массива атрибутов 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» способ справиться с этим? 🙂

6

Решение

Я не знаю о «одобренном» способе сделать это, как таковой, но вы всегда можете отменить Eloquent __get() Волшебный метод для проверки приватных полей?

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;
}
3

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

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

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