在 Laravel 5 Collection 中,如何返回对象数组而不是数组数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28776849/
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:02:03  来源:igfitidea点击:

In a Laravel 5 Collection how do you return an array of objects instead of an array of arrays?

phplaraveliteratorlaravel-5

提问by ebakunin

I am using Laravel 5 and a Blade template. In a view I want to iterate over an array of Model objects, not an array of arrays. IfI did want to iterate over an array of arrays I would do the following, which works as expected:

我正在使用 Laravel 5 和 Blade 模板。在视图中,我想遍历一组 Model 对象,而不是一组数组。如果我确实想遍历数组数组,我会执行以下操作,这将按预期工作:

$models = Foo::where('id', '>', 5)->get();
return view('home.index', ['models' => $models->toArray()]);

However I want an array of objects with accessible properties. If I were to run:

但是我想要一组具有可访问属性的对象。如果我要跑:

$models = Foo::where('id', '>', 5)->get();
return view('home.index', ['models' => $models->all()]);

The var_dumpwould look like this:

var_dump是这样的:

object(Illuminate\Support\Collection)[164]
  protected 'items' => 
    array (size=3)
      0 => 
        object(App\Foo)[172]
          public 'id' => null
          public 'foo' => null
          private 'created_at' => null
          private 'updated_at' => null
          protected 'connection' => null
          protected 'table' => null
          protected 'primaryKey' => string 'id' (length=2)
          protected 'perPage' => int 15
          public 'incrementing' => boolean true
          public 'timestamps' => boolean true
          protected 'attributes' => 
            array (size=4)
              'id' => int 1
              'foo' => string 'Foo!' (length=4)
              'created_at' => string '2015-02-27 15:44:09' (length=19)
              'updated_at' => null

Not only is the Model in an 'items' object the properties are not filled.

不仅“项目”对象中的模型没有填充属性。

In a view I would like to do something like this:

在我看来,我想做这样的事情:

@foreach ($models as $model)
    @include('_partial') {
        'id' => $model->id,
        'foo' => $model->foo,
    }
@endforeach

How do I get an array of Models instead of an array of an array of Models?

如何获取模型数组而不是模型数组的数组?

采纳答案by ebakunin

Figured out the problem. I was explicitly defining the attributes in the Model. Laravel uses __get() in a particular way which causes passed parameters to be overridden whatever attributes are explicitly defined.

想通了问题所在。我在模型中明确定义了属性。Laravel 以一种特定的方式使用 __get() ,这会导致传递的参数被覆盖,无论显式定义的属性都是什么。

In other words, I was getting null values in the partial because the info I was passing to the partial was overridden.

换句话说,我在部分中获得了空值,因为我传递给部分的信息被覆盖了。

回答by windsor

According to the Docs:

根据文档

$array = $collection->all();

"The all method returns the underlying array represented by the collection."

“all 方法返回由集合表示的底层数组。”

回答by Bogdan

Your code is just fine, except you don't need to call toArrayon your Eloquent query result. Let me explain what the code does, so you can understand why the following is what you want:

你的代码很好,只是你不需要调用toArray你的 Eloquent 查询结果。让我解释一下代码的作用,这样你就可以理解为什么下面是你想要的:

$models = Foo::where('id', '>', 5)->get();
return view('home.index', ['models' => $models]);

The first statememt Foo::where('id', '>', 5)->get();returns a value of type Illuminate\Support\Collection.

第一个语句Foo::where('id', '>', 5)->get();返回一个类型的值Illuminate\Support\Collection

That Collectionclass holds the collection elements in a protected property called $items(as you could see from your dump protected 'items' =>), which is of type array. The class also implements an interface called IteratorAggregate, which basically means it allows any variable of that type to be iterated using a foreachstatement.

Collection类拥有被称为保护财产集合元素$items(如,你可以从你的转储看protected 'items' =>,这是类型)array。该类还实现了一个名为IteratorAggregate的接口,这基本上意味着它允许使用foreach语句迭代该类型的任何变量。

In your case this means that, even if $modelsis of type Illuminate\Support\Collectionit will behave as an array when you go over it with foreach:

在您的情况下,这意味着,即使$models是类型Illuminate\Support\Collection,当您使用foreach以下命令检查它时,它也会表现得像一个数组:

@foreach ($models as $model)
{
    {{ $model->foo }}
}

So in short Collectionis an iterable object that can be treated as an array, but is better than an array because if offers extra methods that allow you to manipulate the items from the collection. You can check the Collection APIto see a complete list of available methods.

简而言之,它Collection是一个可迭代对象,它可以被视为一个数组,但比数组更好,因为 if 提供了额外的方法,允许您操作集合中的项目。您可以查看Collection API以查看可用方法的完整列表。

So in reality you're getting an improvedarray of models.

所以实际上你得到了一系列改进的模型。



Also, don't worry that the properties are not filled, they are in fact filled, I just think you're looking in the wrong place.

另外,不要担心属性没有被填充,它们实际上是被填充的,我只是认为你找错了地方。

If you look closely at your var_dump, you'll see that you have some lines that start with public, protectedor private. Those keywords mean that those lines contain object properties. In the case of Laravel Eloquent models, the values fetched from the database are not stored directly in the properties that are named like the database columns. The values are in fact stored in a single property called attributesand are fetched using PHP's magic _get. Take a look at the comments on the code below:

如果您仔细查看您的var_dump,您会发现您有一些以public,protected或开头的行private。这些关键字意味着这些行包含对象属性。在 Laravel Eloquent 模型的情况下,从数据库获取的值不会直接存储在像数据库列一样命名的属性中。这些值实际上存储在一个名为的单个属性中attributes,并使用 PHP 的魔法来获取_get。看看下面代码的注释:

object(Illuminate\Support\Collection)[164]
  protected 'items' => 
    array (size=3)
      0 => 
        object(App\Foo)[172]
          public 'id' => null  // <<< THE VALUES ARE
          public 'foo' => null // <<< NOT STORED HERE
          private 'created_at' => null
          private 'updated_at' => null
          protected 'connection' => null
          protected 'table' => null
          protected 'primaryKey' => string 'id' (length=2)
          protected 'perPage' => int 15
          public 'incrementing' => boolean true
          public 'timestamps' => boolean true
          protected 'attributes' => 
            array (size=4)
              'id' => int 1 // <<< THEY ARE HERE
              'foo' => string 'Foo!' (length=4) // <<< AND HERE
              'created_at' => string '2015-02-27 15:44:09' (length=19)
              'updated_at' => null

Laravel does a lot of trickery behind the scenes to allow you to get things done with only a few lines of code. That's why a var_dumpwill not always display the simple data structures that you might expect.

Laravel 在幕后做了很多诡计,让你只用几行代码就可以完成任务。这就是为什么 avar_dump不会总是显示您可能期望的简单数据结构的原因。