How to Check if a Specific Item Exists Within a Collection in Laravel
Laravel’s contains() method verifies item existence by evaluating scalar values, callbacks, or key-operator-value expressions against collection items using loose or strict comparison logic.
The Illuminate\Support\Collection class provides a robust API for array manipulation throughout the Laravel framework. When you need to check if a specific item exists within a collection in Laravel, the contains() method offers three distinct operational modes—value matching, callable filtering, and attribute comparison—without requiring manual iteration.
Understanding the contains() Method Signature
The implementation resides in src/Illuminate/Collections/Collection.php and accepts flexible arguments to accommodate different lookup strategies:
public function contains($key, $operator = null, $value = null)
{
if (func_num_args() === 1) {
if ($this->useAsCallable($key)) {
return array_any($this->items, $key);
}
return in_array($key, $this->items);
}
return $this->contains($this->operatorForWhere(...func_get_args()));
}
This single method handles three distinct calling conventions:
- Single argument: Checks for scalar values using
in_array()or executes a callback viaarray_any() - Three arguments: Parses
$key,$operator, and$valueinto a comparison closure - Callable detection: Uses
useAsCallable()fromsrc/Illuminate/Support/Traits/EnumeratesValues.phpto identify closures
How contains() Works Under the Hood
The method determines its execution path through argument counting and type inspection:
- Argument Inspection:
func_num_args()identifies whether you passed one value or three - Callable Routing: When the single argument is a closure or invokable object, Laravel delegates to
array_any()(a core helper that iterates until the callback returnstrue) - Value Lookup: Non-callable single arguments trigger PHP’s native
in_array()with loose comparison - Complex Comparisons: Three-argument calls route through
operatorForWhere()to generate a closure, then recurse back into the single-argument logic
This architecture allows contains() to handle primitive scalars, object instances, and dynamic conditions through a unified interface.
Practical Examples: Checking for Items in Laravel Collections
Checking for Simple Scalar Values
When verifying primitive values or exact string matches, pass the target value directly. The method performs a loose comparison using ==.
$users = collect([
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
]);
// Check if "Bob" exists in the names column
$hasBob = $users->pluck('name')->contains('Bob'); // true
// Loose type comparison example
$numbers = collect([1, 2, 3]);
$hasStringOne = $numbers->contains('1'); // true (loose comparison)
Using Closures for Custom Logic
For complex conditions or computed checks, pass a closure (or arrow function) that receives the item and returns a boolean. The iteration stops at the first match.
// Check if any user has an age greater than 30
$hasSenior = $users->contains(fn ($user) => ($user['age'] ?? 0) > 30);
// Check if collection contains an even number
$hasEven = collect([1, 3, 5, 7, 8, 9])->contains(fn ($num) => $num % 2 === 0); // true
Key-Operator-Value Comparisons
Pass three arguments to perform attribute-based comparisons without writing explicit closures. Laravel supports standard operators (=, ==, >, <, >=, <=, !=).
// Find user with id equal to 2
$hasIdTwo = $users->contains('id', '=', 2); // true
// Find user with id greater than 1
$hasHighId = $users->contains('id', '>', 1); // true
Behind the scenes, operatorForWhere() constructs the comparison logic and passes it back to the callable branch of contains().
Strict Comparisons with containsStrict()
When type safety matters, use containsStrict() instead. This method enforces === comparison semantics, available in the same Collection.php file.
$mixed = collect([1, '1', 2, '2']);
// Loose check
$mixed->contains(1); // true (matches integer 1 and string '1')
// Strict check
$mixed->containsStrict(1); // true (matches only integer 1)
$mixed->containsStrict('1'); // true (matches only string '1')
Summary
contains()resides insrc/Illuminate/Collections/Collection.phpand accepts one or three arguments depending on your lookup strategy- Loose comparison is the default for scalar checks, using PHP’s
in_array()internally - Callable support enables complex logic via closures detected by
useAsCallable()inEnumeratesValues.php - Three-argument syntax (
$key,$operator,$value) delegates tooperatorForWhere()for attribute filtering - Strict type checking requires
containsStrict()to enforce===comparisons instead of==
Frequently Asked Questions
What is the difference between contains() and containsStrict()?
contains() performs loose comparisons using == semantics, meaning the integer 1 matches the string "1". containsStrict() uses === semantics, requiring both value and type to match. According to the Laravel source code, both methods share the same internal logic but containsStrict() passes a strict flag to the underlying comparison operations.
Can I use contains() on Eloquent Collections?
Yes. Eloquent Collections extend the base Illuminate\Support\Collection class, so all contains() variants work with model collections. When checking for model instances, contains() uses object identity comparison by default, while containsStrict() ensures the exact same instance or matching primary key depending on your closure logic.
How does contains() handle object comparisons?
When passing an object to contains(), Laravel uses in_array() which checks for object identity by default (same instance). To match objects by attribute values (such as checking if any user has a specific email), use a closure: $users->contains(fn ($user) => $user->email === 'test@example.com').
Is contains() case-sensitive when checking strings?
Yes. The in_array() function and standard comparison operators used internally are case-sensitive. The string "Admin" does not match "admin" in a standard contains() check. For case-insensitive searches, normalize the case within a closure: $collection->contains(fn ($item) => strtolower($item) === 'admin').
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →