Collection::every
Determines whether every item passes the given truth test, returning true for an empty collection.
every(mixed $key, mixed $operator = null, mixed $value = null): bool- Added in Laravel 5.2
Parameters
| Parameter | Type | Description |
|---|---|---|
$$key | (callable(TValue, TKey): bool)|TValue|string | A closure truth test, or — when further arguments are given — the key to read from each item. |
$$operatoroptional | mixed= null | With three arguments, the comparison operator (=, ==, ===, !=, <, >, <=, >=, <=>). With two arguments, the value the key must equal. |
$$valueoptional | mixed= null | The value the resolved key must match. |
Return value
boolTrue when every item passes the test, and true when the collection is empty.
Changelog
- PHP 5.3The key/operator/value form was added alongside the original closure-only signature.
- PHP 5.2Repurposed from the old every($step, $offset) nth-item helper, which became nth(). Code predating 5.2 that calls every(3) means something entirely different.
every() is the universal quantifier: true only when the callback passes for every item. It short-circuits on the first failure, so an expensive test stops as soon as one item fails.
Empty means true
This is the trap the method is known for. collect([])->every(...) returns true, because "all zero items passed" is vacuously correct. It is mathematically right and operationally dangerous: a guard reading if ($approvals->every(fn ($a) => $a->granted)) lets everything through when nothing was ever loaded — an empty result set, a failed query, a relation that was not eager-loaded. When "all" is meant to imply "at least one", write $c->isNotEmpty() && $c->every(...).
Argument forms
Besides a closure, it accepts a key/value pair — every('active', true) — or a key, operator and value — every('age', '>=', 18). The key resolves through data_get(), so arrays, objects, models and dot paths all work. A bare string with one argument is treated as a property to read, not as a value to compare, which differs from contains().
Inverse
There is no none(). Use ! $c->contains($test), or $c->doesntContain(...), to assert that nothing matches.
Example
When to use it
- Confirm every line item in a cart is in stock before checkout.
- Verify all uploaded files pass a size limit before processing.
- Assert that every record in a batch reached a terminal status.
Frequently asked questions
Why does every() return true on an empty collection?
Because it is vacuously true — no item failed the test, so the assertion holds. Combine it with isNotEmpty() whenever an empty collection should not pass your guard.
Does every() stop at the first failing item?
Yes, it short-circuits and returns false immediately, so items after the first failure are never passed to the callback. Do not rely on the callback running for every item as a side effect.
How do I check that no item matches a condition?
There is no none() method — use doesntContain() with the same test, or negate contains(). every() with an inverted predicate also works but reads less clearly.
More examples
The vacuous-truth bug in an authorisation guard
Both methods look identical in review, but the first ships an unverified deployment. The empty relation makes every() vacuously true, and the same failure appears when a query returns nothing or a relation was never loaded. The isNotEmpty() conjunction is the standard fix. Needs a booted application with a database.
<?php
class ReleaseGate
{
public function canRelease(Deployment $deployment): bool
{
$checks = $deployment->checks; // HasMany, may be empty
// BUG: a deployment with no checks recorded passes the gate.
return $checks->every(fn (Check $c) => $c->passed);
}
public function canReleaseSafely(Deployment $deployment): bool
{
$checks = $deployment->checks;
// "All checks passed" must also mean "checks actually ran".
return $checks->isNotEmpty()
&& $checks->every(fn (Check $c) => $c->passed);
}
}
$fresh = Deployment::factory()->create(); // no checks yet
var_dump((new ReleaseGate)->canRelease($fresh)); // bool(true) <- wrong
var_dump((new ReleaseGate)->canReleaseSafely($fresh)); // bool(false) <- rightOperator form and short-circuiting
The counter proves the short circuit: only two of three lines were tested because B2 failed. That matters when the test hits a database or an API. The last two calls show the argument forms that avoid a closure entirely — the key resolves through data_get(), so models work the same way.
<?php
$cart = collect([
['sku' => 'A1', 'qty' => 2, 'stock' => 5],
['sku' => 'B2', 'qty' => 9, 'stock' => 3],
['sku' => 'C3', 'qty' => 1, 'stock' => 8],
]);
$checked = 0;
$ok = $cart->every(function (array $line) use (&$checked) {
$checked++;
return $line['qty'] <= $line['stock'];
});
var_dump($ok); // bool(false)
echo $checked, PHP_EOL; // 2 <- stopped at B2, never looked at C3
// Key/value and key/operator/value forms need no closure.
$users = collect([
['name' => 'Ada', 'age' => 34, 'active' => true],
['name' => 'Finn', 'age' => 17, 'active' => true],
]);
var_dump($users->every('active', true)); // bool(true)
var_dump($users->every('age', '>=', 18)); // bool(false)
Discussion