如何在 Laravel 4 中手动创建一个新的空 Eloquent 集合?

78
在 Laravel 4 中,如果不使用查询构建器,我们该如何创建新的 Eloquent Collection?
有一个方法叫做 newCollection() 可以被重写,但实际上它并没有什么用处,因为它仅在查询结果集时使用。
我考虑创建一个空的 Collection,然后用 Eloquent 对象填充它。我之所以不使用数组,是因为我喜欢 Eloquent Collections 的方法,比如 contains
如果有其他选择,我很乐意听听。
9个回答

145

为了将 Eloquent 模型添加到集合中,您有几个选项,但这并不是很优雅。在 Laravel 5 中,您可以使用帮助程序来简化该过程。

$c = collect(new Post);
或者
$c = collect();
$c->add(new Post);

旧版 Laravel 4 回答

$c = new \Illuminate\Database\Eloquent\Collection;

然后你就可以

$c->add(new Post);

或者你可以使用make:

$c = Collection::make(new Post);

4
快要成功了!我认为\Illuminate\Support\Collection\Illuminate\Database\Eloquent\Collection的更通用版本。所以,我猜它毕竟是Eloquent的一部分。希望这对其他人有所帮助。 - JofryHS
是的,我应该看一下它,因为我错过了add方法,这个方法只存在于Eloquent\Collection中。已编辑。 - Antonio Carlos Ribeiro
1
如果使用\Illuminate\Support\Collection,你可以使用$c->push(new Post);代替add方法。 - Rogier
我更喜欢使用静态方法:$c = \Illuminate\Database\Eloquent\Collection::make();。这样可以确保正确的工厂实例化。 - Soulriser
1
Illuminate\Database\Eloquent\Collection 不同于 \Illuminate\Support\Collection。前者具有与模型一起使用的特定方法。 - Javis
显示剩余2条评论

15

从 Laravel 5 开始,我使用全局函数 collect()

$collection = collect([]); // initialize an empty array [] inside to start empty collection

这种语法非常简洁,如果您不想要数字索引,还可以添加偏移量,就像这样:

$collection->offsetSet('foo', $foo_data); // similar to add function but with
$collection->offsetSet('bar', $bar_data); // an assigned index

11

事实上,我发现使用newCollection()更加具有未来性......

例如:

$collection = (new Post)->newCollection();

如果你决定在以后的某个阶段为你的模型创建自己的集合类(就像我已经做过几次),那么这样做会使重构代码变得更加容易,因为你只需要在模型中覆盖newCollection()函数。


7

Laravel >= 5.5

这可能与原问题无关,但由于它是谷歌搜索结果中最先出现的链接之一,我认为对那些像我一样正在寻找如何创建空集合的人很有帮助。

如果你想手动创建新的空集合,可以使用collect帮助方法,像这样:

$new_empty_collection = collect();

你可以在Illuminate\Support\helpers.php中找到这个助手。
代码片段:
if (! function_exists('collect')) {
    /**
     * Create a collection from the given value.
     *
     * @param  mixed  $value
     * @return \Illuminate\Support\Collection
     */
    function collect($value = null)
    {
        return new Collection($value);
    }
}

值得一提的是,在您发布这个答案之前,collect() 辅助函数已经在被接受的答案中编辑了2年。 - miken32
2
能否创建一个类型为 Illuminate\Database\Eloquent\Collection 的空集合? - Connor Leech

5

我正在使用这种方法:

$coll = new Collection();
    
$coll->name = 'name';
$coll->value = 'value';
$coll->description = 'description';

并将其作为普通集合使用

dd($coll->name);


5

补充一下已接受的答案,你也可以在config/app.php中创建一个别名。

'aliases' => array(

    ...
    'Collection'      => Illuminate\Database\Eloquent\Collection::class,

那么您只需要执行以下操作
$c = new Collection;

4
在 Laravel 5 和 Laravel 6 中,您可以从服务容器中解析出 Illuminate\Database\Eloquent\Collection 类,并将模型添加到其中。
$eloquentCollection = resolve(Illuminate\Database\Eloquent\Collection::class);
// or app(Illuminate\Database\Eloquent\Collection::class). Whatever you prefer, app() and resolve() do the same thing.

$eloquentCollection->push(User::first());

如果想要更好地理解 Laravel 中容器对象的解析,可以查看这里:https://laravel.com/docs/5.7/container#resolving


这应该是被接受的答案。其他答案解决的是支持集合而不是优雅的集合! - Connor Leech

1

最好使用注入模式,并在$this->collection->make([])之后,而不是使用new Collection

use Illuminate\Support\Collection;
...
// Inside of a clase.
...
public function __construct(Collection $collection){
    $this->collection = $collection;
}

public function getResults(){
...
$results = $this->collection->make([]);
...
}

如果这个备注仍然有效,您能解释一下原因吗? - Douwe de Haan

1
我的做法是给使用的命名空间命名并直接实例化它:
use Illuminate\Database\Eloquent\Collection as EloquentCollection;

# Usage
$this->latest_posts = new EloquentCollection();

允许我合并两个Eloquent集合结果的数据子集,这将保持关系 - 普通集合(collect())会失去关系和可能丢失一些元数据。

$limit = 5;
$this->latest_posts = new EloquentCollection();

$pinned_posts = PinnedPostReference::where('category', $category)->get();
if($pinned_posts->count() > 0) {
    foreach($pinned_posts as $ppost) {
        $this->latest_posts->push($ppost->post);
    }
}

# Another Eloquent result set ($regular_posts)
foreach($regular_posts as $regular_post) {
    $this->latest_posts->push($regular_post);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接