in_array

Checks whether a value exists anywhere in an array, with optional strict type comparison.

Signature
in_array(mixed $needle, array $haystack, bool $strict = false): bool
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$needlemixedThe value to look for. String comparisons are case-sensitive.
$haystackarrayThe array to search.
$strictoptionalbool= falseWhen true, types must match as well as values (identical comparison). When false, PHP's loose comparison rules apply.

Return value

booltrue if needle is found in haystack, false otherwise.

Changelog

  • PHP 8.0.0Loose comparison of a string needle against a numeric array value (and vice versa) follows the new PHP 8 string-to-number comparison rules; previously a non-numeric string could match 0.

in_array answers one question: is this value somewhere in this array? It walks the array comparing each element to the needle and returns as soon as it finds a match.

When to reach for it

Whitelist and blacklist checks are the bread and butter: is this status one of the allowed ones, is this role permitted, is this extension in the accepted list. If you only need to know whether the value is present, in_array is the right call; if you need where, use array_search, which returns the key.

What trips people up

The default is loose comparison, and that has burned generations of PHP developers. PHP 8 fixed the worst case — in_array('abc', [0]) is now false where it used to be true — but loose mode still matches '1' against 1, true against any non-empty value, and null against ''. Pass true as the third argument unless you have a specific reason not to.

The comparison is also case-sensitive, so in_array('Admin', ['admin']) is false. Normalise the case first, or use array_map('strtolower', ...) on the haystack.

Performance is the other consideration: in_array is O(n). For a large fixed set checked many times, flip it once with array_flip and use isset, which is O(1).

Example

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

When to use it

  • Reject a request whose status field is not one of the allowed values.
  • Check whether an uploaded file's extension is in the accepted list.
  • Test whether a user's role appears in a permission group before rendering an admin link.

Frequently asked questions

What is the difference between in_array and array_search?

in_array returns a boolean saying whether the value exists, while array_search returns the key of the first match or false if there is none. Use array_search only when you actually need the key.

Why does in_array return true for a value that is not in my array?

You are using the default loose comparison, which type-juggles — '1' matches 1, null matches 0 and an empty string, and true matches any truthy element. Pass true as the third argument to compare types as well as values.

How do I check if a key exists rather than a value?

Use array_key_exists($key, $array), or isset($array[$key]) if a null value should count as missing. in_array only searches values.

More examples

Why strict mode matters

Without the strict flag, null and true both find a match through PHP's type-juggling rules, which is almost never intended in an authorisation or validation check. The last two calls show that strict mode reports the truth: neither value is actually in the array.

Example · php
<?php
$ids = [0, 1, 2];

var_dump(in_array('1', $ids));         // true  — '1' == 1
var_dump(in_array(null, $ids));        // true  — null == 0
var_dump(in_array(true, $ids));        // true  — true == 1

var_dump(in_array(null, $ids, true));  // false — the honest answer
var_dump(in_array(true, $ids, true));  // false

Case-insensitive membership

in_array never folds case, so 'admin' does not match 'Admin' in either mode. Lowercasing both sides first gives a reliable comparison that still uses strict typing.

Example · php
<?php
$roles = ['Admin', 'Editor', 'Viewer'];
$input = 'admin';

var_dump(in_array($input, $roles, true));                              // false
var_dump(in_array(strtolower($input), array_map('strtolower', $roles), true)); // true

Faster repeated lookups with array_flip

array_flip turns the values into keys so membership becomes a hash lookup instead of a linear scan, which matters once the haystack has thousands of entries or the check runs in a tight loop. The output marks 'the' and 'and' as stop words and keeps the rest.

Example · php
<?php
$stopWords = ['the', 'a', 'of', 'and', 'to'];
$lookup = array_flip($stopWords);   // build once

foreach (['php', 'the', 'array', 'and'] as $word) {
    $skip = isset($lookup[$word]);  // O(1) hash lookup
    echo $word, ': ', $skip ? 'stop word' : 'keep', "\n";
}

Discussion

  • Be the first to comment on this lesson.