Приведение 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 3

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.

Нет необходимости извлекать красноречивые модели и преобразовывать их одну за другой.