Laravel集合计数结果

27

在一个用户模型上(拥有4条记录的表),当我执行:

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

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

但是当我执行以下操作:

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

我预期的结果是1,但实际上返回的是结果集中属性的数量(在这种情况下为23)。

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


更新:

好的,感谢大家的帮助,现在我明白了集合和模型之间的差别。

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

if(count($coll) > 1)

能够工作,但这是正确的方法吗?


我不相信::find()会返回一个集合。 - Don't Panic
3
实际上,如果你传递一个id数组给它,它是可以的。但在这种情况下,如果找到id = 2的条目,它将返回一个Eloquent模型。 - Bogdan
1
@Bogdan,好观点。我想我应该更明确地说,::find(2) 不会返回一个集合。 - Don't Panic
3个回答

29

以下是你的代码进行的操作:

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:

您可能需要检查结果是否为空值(null),因为如果使用给定的ID未找到任何条目,则find函数将返回null

if (is_null($coll))

当然!我没有区分集合和模型。谢谢你为我澄清这一点!请查看更新后的问题,以获取我正在寻找的真正解决方案。 - Klaaz
@Klaaz 我已经更新了答案,解决了你更新后的问题。 - Bogdan
太好了!这让事情变得非常清晰,谢谢你的解释 :-) - Klaaz
1
Collection有自己的方法 $collection->count() - CodeToLife

1

看起来你希望find()方法的行为有所不同。请参考文档

Find a model by its primary key.

Laravel在某个时候的重新设计中破坏了许多文档链接,因此这些旧的API链接已经失效。 - kjones

0
如果你的问题是要检查它是否来自集合,为什么不检查它是否来自Illuminate\Database\Eloquent\Collection呢?
if (get_class($coll) == 'Illuminate\Database\Eloquent\Collection') {
   your code...
}

或者

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

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