使用存储库模式将 Eloquent\Collection (Laravel) 转换为 stdClass 数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31436448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:57:00  来源:igfitidea点击:

Casting Eloquent\Collection (Laravel) to stdClass array using Repository pattern

laravelcastingeloquentrepository-patternstdclass

提问by Vic

I'm trying to implement the Repository pattern in a Laravel 5app by following this article. In it, the repository implementation converts the object for the specific data source (in this case Eloquent) to an stdClass so that the app uses a standard format and doesn't care about the data source.

我正在尝试按照这篇文章Laravel 5应用程序中实现存储库模式。在其中,存储库实现将特定数据源(在本例中为 Eloquent)的对象转换为 stdClass,以便应用程序使用标准格式并且不关心数据源。

To convert a single Eloquent object they do this:

要转换单个 Eloquent 对象,他们这样做:

/**
* 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;
}

Or, as someone in the comments pointed out, this could also work:

或者,正如评论中有人指出的那样,这也可以:

protected function convertFormat($pokemon)
{
    return $pokemon ? (object) $pokemon->toArray() : null;
}

But then, what happens when I want to cast an entire collection of Eloquent objects to an array of ** stdClass**? Do I have to loop through the collection and cast each element separately?I feel this would be a big hit on performance, having to loop and cast every element every time I need a collection of something and it also feels dirty.

但是,当我想将整个 Eloquent 对象集合转换为 ** stdClass**数组时会发生什么?我是否必须遍历集合并分别投射每个元素?我觉得这会对性能造成很大影响,每次我需要收集一些东西时都必须循环和投射每个元素,而且感觉很脏。

Laravel provides Eloquent\Collection::toArray()which turns the entire collection to an array of arrays. I suppose this is better, but still not stdClass

Laravel 提供了Eloquent\Collection::toArray()将整个集合转换为数组数组的功能。我想这更好,但仍然不是stdClass

The benefits of using a generic object would be that I could do this in my code

使用通用对象的好处是我可以在我的代码中做到这一点

echo $repo->getUser()->name;

Instead of having to do this:

而不是必须这样做:

echo $repo->getUser()['name'];

采纳答案by sisve

Yes, you would need to loop through the collection and cast every object. You can save a few lines of code by using array_map.

是的,您需要遍历集合并转换每个对象。您可以使用array_map节省几行代码。

回答by Keith Mifsud

Using eloquent you can do something like this:

使用 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();
}

All my factories etc accept stdClass so that it's uniform. In eloquent you can either do as above as Eloquent already has a toArray() function which is needed for serialisation, but you can also easily extend Model (Illuminate\Database\Eloquent) to have this method available to all your eloquent models. I suggest that you extend the model so that you can also automate this collections and not just single records.

我所有的工厂等都接受 stdClass 以便它是统一的。在 eloquent 中,您可以执行上述操作,因为 Eloquent 已经具有序列化所需的 toArray() 函数,但您也可以轻松扩展 Model (Illuminate\Database\Eloquent) 以使此方法可用于所有 eloquent 模型。我建议您扩展模型,以便您还可以自动化此集合,而不仅仅是单个记录。

Because I use the repository pattern with Eloquent I normally create an abstract EloquentRepository which extends the Eloquent Model methods and also obviously allows us to add new methods such as this one.

因为我在 Eloquent 中使用存储库模式,所以我通常会创建一个抽象的 EloquentRepository,它扩展了 Eloquent 模型方法,并且显然还允许我们添加新方法,例如这个。

回答by Jaykesh Patel

You can do something like this way,

你可以这样做

For example there is User class

例如有用户类

$user = User::find(1)->toArray();

//this is code for convert to std class
$user = json_encode($user);
$user = json_decode($user);

json_decode by default return stdClass object.

json_decode 默认返回 stdClass 对象。

I hope this will help.

我希望这将有所帮助。

回答by Paul Spiegel

You can use the getQuery()method to convert/cast the \Illuminate\Database\Eloquent\Builderto \Illuminate\Database\Query\Builder.

您可以使用getQuery()方法将 转换/转换\Illuminate\Database\Eloquent\Builder\Illuminate\Database\Query\Builder

return $this->model->getQuery()->get();

will return a collection (or an array before 5.3) of stdClassobjects.

将返回对象的集合(或 5.3 之前的数组)stdClass

return $this->model->where('email', $email)->getQuery()->first();

will return a stdClassobject.

将返回一个stdClass对象。

There is no need to fetch eloquent models and convert them one by one.

无需获取 eloquent 模型并对其进行一一转换。