欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Laravel Collections counting result count 集合的数量 有大用


On a User model (table with 4 records), when I do:

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

I get the amount of records found (4).

But when I do:

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

I do not get 1 (As I expect) but the amount of attributes in the resulting collection (23 in this case).

How can I check if more then one records are found?


UPDATE:

OK, thanks to you all I now see the difference in result between collection and model.

But my real problem is that I have to detect if I am having a model or a collection as a result. Depending on this result I perform some changes on the contents of the fields in the items (with map()) or model. How can I detect if the result is a model or a collection?

if(count($coll) > 1)

Works, but is this the right approach?

shareimprove this question
 
  
I don't believe::find()returns a collection, actually.Don't PanicMay 11 '15 at 22:56
1 
@Don'tPanic Actually it can, if you pass it an array of id's. But in this case if the entry with anid = 2is found it will return an Eloquent Model.BogdanMay 11 '15 at 22:57
  
@Bogdan, Good point. I guess I should have said more specifically::find(2)does not return a collection.Don't PanicMay 11 '15 at 22:59

2 Answers 正确答案 

Here's what's going on with the code you have there:

1.When callingUser::all()you'll get aIlluminate\Database\Eloquent\Collectionon which you can callcountwhich counts the elements in the collection like so:

public function count()
{
    return count($this->items);
}

This will return the number of items in the collection as you correctly expected.

2.When callingUser::find(2)however, the Eloquent Query Builder will not return aCollection, because it will check to see how many results there are, and since you passedone IDyou'll get at mostone result, so it will return an Eloquent Model instead. The Model does not have acount()method, so when you try to call$coll->count();it will go to the magic__callmethod that the class has implemented which looks like this:

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);
}

As you can see the method tries to see if it should call a couple of hardcoded methods (incrementanddecrement), which of course don't match in this case because$method = 'count', so it continues to create a new Query on which it will call thecountmethod.

The bottom line is that both the first and second code samples end up doing the same thing:counting all the entries in theuserstable.

And since, as I pointed our above, one ID cannot match more than one row (since IDs are unique), theanswer to your questionis that there's no need or way to count the results offind(2), since it can only be 0 (ifnullis returned) or 1 (if aModelis returned).


UPDATE

First of all, for future reference you can use the PHPget_classto determine the class name of an object orget_parent_classto determine the class it is extending. In your case the second functionget_parent_classmight be useful for determining the model class since theUserclass extends a Laravel abstract Model class.

So if you have a modelget_class($coll)will reportUser, butget_parent_class($coll)will report\Illuminate\Database\Eloquent\Model.

Now to check if the result is a Collection or a Model you can useinstanceof:

instanceofis used to determine whether a PHP variable is an instantiated object of a certain class

Your checks should look something like this:

// 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)

You might also want to check if the result isnull, sincefindwill returnnullif no entry is found with the given ID:

if (is_null($coll))
shareimprove this answer
 
  
Of course! I did not make the difference between a collection and a model. Thanks for clearing this for me! Please see the updated question for the real solution I am looking for.KlaazMay 12 '15 at 7:49
  
@Klaaz I've updated the answer with the solution to your updated question.BogdanMay 12 '15 at 9:12
  
Great! This makes things very clear, thank you for explaining :-)KlaazMay 12 '15 at 10:36

It seems you are expecting thefind()-methodto behave differently. From thedocs

Find a model by its primary key.
shareimprove this answer
 

来自 https://stackoverflow.com/questions/30178809/laravel-collections-counting-result


普通分类: