Приведение EloquentCollection (Laravel) к массиву stdClass с использованием шаблона репозитория
Я пытаюсь реализовать шаблон репозитория в ПриложенииLaravel 5 , следуяэтой статье . В нем реализация репозитория преобразует объект для конкретного источника данных (в данном случае Eloquent) в класс std, так что приложение использует стандартный формат и не заботится об источнике данных.
Чтобы преобразовать один красноречивый объект, они делают следующее:
/**
* Converting the Eloquent object to a standard format
*
* @param mixed $pokemon
* @return stdClass
*/
protected function convertFormat($pokemon)
{
if ($pokemon == null)
{
return null;
}
$object = new stdClass();
$object->id = $pokemon->id;
$object->name = $pokemon->name;
return $object;
}
Или, как указал кто-то в комментариях, это также может сработать.:
protected function convertFormat($pokemon)
{
return $pokemon ? (object) $pokemon->toArray() : null;
}
Но тогда, что происходит, когда я хочу бросить всю коллекцию красноречивых объектов в массив ** stdClass
**? Должен ли я перебирать коллекцию и приводить каждый элемент отдельно? я чувствую, что это было бы большим хитом по производительности, когда мне нужно зациклить и бросить каждый элемент каждый раз, когда мне нужна коллекция чего-то, и это также кажется грязным.
Laravel предоставляет EloquentCollection::toArray()
, который превращает всю коллекцию в массив массивов. Я полагаю, что это лучше, но все же не stdClass
Преимущества использования универсального объекта заключаются в том, что я могу сделать это в своем коде
echo $repo->getUser()->name;
Вместо того, чтобы делать это:
echo $repo->getUser()['name'];
4 ответа:
Да, вам нужно будет выполнить цикл через коллекцию и привести каждый объект. Вы можете сохранить несколько строк кода с помощью array_map.
Используя eloquent вы можете сделать что-то вроде этого:
/** * Gets the project type by identifier. * * @param string $typeIdentifier * * @return object * */ public function getTypeByIdentifier($typeIdentifier) { $type = ProjectType::where( 'type_identifier', $typeIdentifier )->first(); return (object) $type->toArray(); }
Все мои фабрики и т. д. принимают stdClass, чтобы он был однородным. В eloquent вы можете либо сделать так, как описано выше, поскольку у Eloquent уже есть функция toArray (), которая необходима для сериализации, но вы также можете легко расширить модель (Illuminate\Database\Eloquent), чтобы этот метод был доступен для всех ваших моделей eloquent. Я предлагаю вам расширить модель, чтобы вы также могли автоматизировать эти коллекции, а не только отдельные учетная документация.
Поскольку я использую шаблон репозитория с Eloquent, я обычно создаю абстрактный EloquentRepository, который расширяет методы модели Eloquent, а также, очевидно, позволяет нам добавлять новые методы, такие как этот.
Вы можете сделать что-то вроде этого,
Например есть класс пользователя
$user = User::find(1)->toArray(); //this is code for convert to std class $user = json_encode($user); $user = json_decode($user);
Json_decode по умолчанию возвращает объект stdClass.
Я надеюсь, что это поможет.
Вы можете использовать методgetQuery () для преобразования/приведения
\Illuminate\Database\Eloquent\Builder
к\Illuminate\Database\Query\Builder
.return $this->model->getQuery()->get();
Вернет коллекцию (или массив до 5.3) объектов
stdClass
.return $this->model->where('email', $email)->getQuery()->first();
Вернет объект
Нет необходимости извлекать красноречивые модели и преобразовывать их одну за другой.stdClass
.