Laravel 集合计数结果

Posted

技术标签:

【中文标题】Laravel 集合计数结果【英文标题】:Laravel Collections counting result 【发布时间】:2015-07-22 14:45:34 【问题描述】:

在用户模型(有 4 条记录的表)上,当我这样做时:

$coll = User::all();
echo $coll->count();

我得到了找到的记录数量 (4)。

但是当我这样做时:

$coll = User::find(2);
echo $coll->count();

我没有得到 1(如我所料),而是结果集合中的属性数量(在本例中为 23)。

如何检查是否找到多个记录?


更新:

好的,谢谢大家,我现在看到了集合和模型之间的结果差异。

但我真正的问题是我必须检测我是否有一个模型或一个集合作为结果。根据这个结果,我对项目(使用 map())或模型中的字段内容进行了一些更改。如何检测结果是模型还是集合?

if(count($coll) > 1)

有效,但这是正确的方法吗?

【问题讨论】:

我不相信::find() 实际上会返回一个集合。 @Don'tPanic 实际上它可以,如果你传递一个 id 数组。但是在这种情况下,如果找到带有 id = 2 的条目,它将返回一个 Eloquent 模型。 @Bogdan,好点子。我想我应该更具体地说明::find(2) 不返回集合。 【参考方案1】:

这是您那里的代码的情况:

1. 调用User::all() 时,您将获得一个Illuminate\Database\Eloquent\Collection,您可以在其上调用count,它计算集合中的元素,如下所示:

public function count()

    return count($this->items);

这将返回您正确预期的集合中的项目数。

2. 但是,当调用 User::find(2) 时,Eloquent 查询构建器不会返回 Collection,因为它会检查有多少结果,并且由于您通过了 一个 ID 你最多会得到 一个结果,所以它会返回一个 Eloquent 模型。该模型没有count() 方法,因此当您尝试调用$coll->count(); 时,它将转到该类已实现的神奇__call 方法,如下所示:

public function __call($method, $parameters)

    if (in_array($method, array('increment', 'decrement')))
    
        return call_user_func_array(array($this, $method), $parameters);
    

    $query = $this->newQuery();

    return call_user_func_array(array($query, $method), $parameters);

如您所见,该方法尝试查看是否应该调用几个硬编码方法(incrementdecrement),在这种情况下它们当然不匹配,因为 $method = 'count',所以它继续创建一个新的查询,它将在其上调用count 方法。

最重要的是,第一个和第二个代码示例最终都做了同样的事情:计算users 表中的所有条目

而且,正如我在上面指出的那样,一个 ID 不能匹配多于一行(因为 ID 是唯一的),您的问题的答案是没有必要或方法来计算结果find(2),因为它只能是 0(如果返回 null)或 1(如果返回 Model)。


更新

首先,为了将来参考,您可以使用 php get_class 来确定对象的类名或使用get_parent_class 来确定它正在扩展的类。在您的情况下,第二个函数 get_parent_class 可能对确定模型类很有用,因为 User 类扩展了 Laravel 抽象模型类。

所以如果你有一个模型get_class($coll) 将报告User,但get_parent_class($coll) 将报告\Illuminate\Database\Eloquent\Model

现在检查结果是集合还是模型,您可以使用instanceof

instanceof用于判断PHP变量是否为某个类的实例化对象

您的支票应如下所示:

// Check if it's a Collection
if ($coll instanceof \Illuminate\Support\Collection)

// Check if it's a Model
if ($coll instanceof \Illuminate\Database\Eloquent\Model)

您可能还想检查结果是否为 null,因为如果没有找到具有给定 ID 的条目,find 将返回 null

if (is_null($coll))

【讨论】:

当然!我没有区分集合和模型。感谢您为我清除这个!请查看更新后的问题,了解我正在寻找的真正解决方案。 @Klaaz 我已经用您更新问题的解决方案更新了答案。 太棒了!这让事情变得非常清楚,谢谢你的解释:-)【参考方案2】:

您似乎期望find()-method 的行为有所不同。来自docs

Find a model by its primary key.

【讨论】:

Laravel 在重新设计期间破坏了许多文档链接,因此这些旧的 API 链接已失效。【参考方案3】:

如果你的问题是通过检查它是否来自集合。你为什么不检查它是否来自 Illuminate\Database\Eloquent\Collection。

if (get_class($coll) == 'Illuminate\Database\Eloquent\Collection') 
   your code...

if ($coll instanceof \Illuminate\Database\Eloquent\Collection) 
   your code...

【讨论】:

以上是关于Laravel 集合计数结果的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:当数组为空时数组循环的集合

如何使用 Laravel 合并两个计数

Laravel 集合从每个函数中检索变量结果

Eloquent 集合:计数和检测空

Laravel,数据表,具有关系计数的列

为啥我的 laravel 集合返回 500 错误,即使不是在我使用 dd() 检查结果时?