Collection::has

Determines whether one key, or every key in a list, exists in the collection.

Signature
Collection::has(mixed $key): bool

Parameters

ParameterTypeDescription
$keyTKey|array<array-key, TKey>A single key, or an array of keys that must all be present. Keys may also be passed as separate arguments instead of an array.

Return value

boolTrue when the key exists, or when every key in the given list exists. False as soon as one is missing.

has answers one question: does this key exist? It is array_key_exists with a collection-shaped API, plus the convenience of checking several keys at once — pass an array (or several separate arguments) and the result is true only if every one is present.

When to reach for it

Use it to assert the shape of data before reading it: required fields in a decoded payload, expected columns in an imported row, mandatory options in a config array. Pairing it with get lets you distinguish "absent" from "present but null", which get alone cannot tell you.

The thing that trips people up

has looks at keys, never at values. On the collection ['product' => 'Desk'], has('product') is true and has('Desk') is false. The method that searches values is contains, and mixing the two up is the single most common mistake here — especially on a list, where the keys are the integer offsets, so collect(['a','b'])->has(1) is true because index 1 exists, not because the value 1 is present.

Presence uses array_key_exists, so a key holding null still counts as existing. That is usually what you want for validation, but it means has and isset disagree on null-valued keys. For "any of these" rather than "all of these", use hasAny.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Assert that a decoded request payload carries every required field before reading it.
  • Check whether an imported CSV row has the columns your mapper expects.
  • Distinguish a genuinely missing option from one explicitly set to null.

Frequently asked questions

Does has() check keys or values?

Keys only. collect(['product' => 'Desk'])->has('Desk') is false because Desk is a value, not a key — use contains() to search values instead.

How do I check whether any one of several keys is present?

Use hasAny(), which returns true when at least one key exists. has() with an array is all-or-nothing: it returns true only when every key in the list is present.

Does has() return false for a key whose value is null?

No. Presence is tested with array_key_exists, so a key holding null still returns true. That is what lets you distinguish an explicitly nulled field from one that was never set.

More examples

has, hasAny and reporting what is missing

The output is bool(false), bool(false), then "missing: phone". has() only tells you whether the whole set is present, so when an error message needs to name the absent fields, filter the requirement list against has() rather than calling it once. hasAny() is the "at least one" variant.

Example · php
<?php
$payload = collect(['name' => 'Ada', 'email' => '[email protected]']);

$required = ['name', 'email', 'phone'];

var_dump($payload->has($required));
var_dump($payload->hasAny(['phone', 'fax']));

// has() is all-or-nothing, so name the offenders yourself.
$missing = collect($required)->reject(fn ($k) => $payload->has($k));

echo 'missing: ', $missing->implode(', '), PHP_EOL;

Telling absent apart from null

The output is "timezone: explicitly null" then "currency: not configured". get() alone returns null in both cases, so has() is what lets you treat "the user cleared this setting" differently from "this setting was never written". Note that isset() would report both as absent.

Example · php
<?php
$settings = collect(['timezone' => null, 'locale' => 'en']);

foreach (['timezone', 'currency'] as $key) {
    if (! $settings->has($key)) {
        echo $key, ": not configured", PHP_EOL;
        continue;
    }

    echo $key, ': ', $settings->get($key) ?? 'explicitly null', PHP_EOL;
}

Guarding a mapper over imported rows

The output is "1 of 2 rows usable" followed by the single complete row. Wrapping each row in a collection makes has() available as a per-row shape check, which keeps the validation declarative instead of writing nested isset() calls in the mapper.

Example · php
<?php
$rows = collect([
    ['sku' => 'A1', 'qty' => 2],
    ['sku' => 'B2'],
]);

$valid = $rows->map(fn (array $r) => collect($r))
    ->filter(fn ($r) => $r->has(['sku', 'qty']));

echo $valid->count(), ' of ', $rows->count(), ' rows usable', PHP_EOL;
print_r($valid->map->all()->values()->all());

Discussion

  • Be the first to comment on this lesson.