Search in Arrays

La Lakshmi Priya Updated 19 Oct 2026
7 min read ·Lesson 133 of 143

Searching an array answers questions such as: Does this value exist? Where is it? Which elements match a condition? Is this key present? PHP provides a dedicated function for each question.

QuestionFunctionReturns
Does a value exist?in_array($value, $array, true)bool
Which key holds a value?array_search($value, $array, true)First key, or false
Which keys hold a value (all of them)?array_keys($array, $value, true)Array of keys
Does a key exist?array_key_exists($key, $array) / isset($array[$key])bool
Which elements match a condition?array_filter($array, $callback)Array of matches
First element matching a condition?array_find() (PHP 8.4+)Value or null
Key of the first match?array_find_key() (PHP 8.4+)Key or null
Does any / every element match?array_any() / array_all() (PHP 8.4+)bool
Which strings match a pattern?preg_grep($pattern, $array)Array of matches

in_array() — Does the Value Exist?

Syntax

in_array(mixed $needle, array $haystack, bool $strict = false): bool

Example

<?php
$fruits = ['Mango', 'Banana', 'Guava'];

var_dump(in_array('Banana', $fruits, true));
var_dump(in_array('banana', $fruits, true));
var_dump(in_array('Apple', $fruits, true));

Output

bool(true)
bool(false)
bool(false)

The search is case-sensitive: 'banana' does not match 'Banana'.

Always Use Strict Mode

Without the third argument, in_array() compares with == (loose comparison):

<?php
$allowedIds = [1, 2, 3];

var_dump(in_array('1', $allowedIds));
var_dump(in_array('1', $allowedIds, true));
var_dump(in_array(null, [0, 1]));
var_dump(in_array(null, [0, 1], true));

Output

bool(true)
bool(false)
bool(true)
bool(false)
  • The string '1' loosely equals the integer 1, but strictly it does not.
  • null == 0 is true, so a loose search for null finds 0.

Loose matches can let invalid input pass validation. Pass true as the third argument unless you deliberately want type juggling — and make sure the value's type matches the array's (for example, cast form input with (int) before searching a list of integer IDs).


array_search() — Where Is the Value?

<?php
$queue = ['ORD-11', 'ORD-12', 'ORD-13'];

$position = array_search('ORD-11', $queue, true);
var_dump($position);

$missing = array_search('ORD-99', $queue, true);
var_dump($missing);

if ($position !== false) {
    echo "ORD-11 is number " . ($position + 1) . " in the queue\n";
}

Output

int(0)
bool(false)
ORD-11 is number 1 in the queue

array_search() returns the key of the first match, or false. Because a valid key can be 0 (falsy), always check with !== false. Writing if ($position) would treat the first element as "not found".

All Matching Keys: array_keys()

<?php
$ratings = ['Asha' => 5, 'Bala' => 3, 'Charu' => 5, 'Dev' => 4];

$fiveStars = array_keys($ratings, 5, true);

echo "Five-star reviewers: " . implode(', ', $fiveStars) . "\n";

Output

Five-star reviewers: Asha, Charu

With a second argument, array_keys() returns every key whose value matches — not just the first.


Searching for Keys

<?php
$prices = ['Pen' => 20, 'Notebook' => 60, 'Gift Card' => null];

var_dump(array_key_exists('Notebook', $prices));
var_dump(isset($prices['Gift Card']));
var_dump(array_key_exists('Gift Card', $prices));
var_dump(isset($prices['Lamp']));

Output

bool(true)
bool(false)
bool(true)
bool(false)
  • array_key_exists() reports whether the key exists, even if its value is null.
  • isset() returns false for null values. It also works for nested paths (isset($a['x']['y'])).

Searching Records

Data often comes as a list of records. Two common approaches:

<?php
$users = [
    ['id' => 7, 'email' => 'asha@example.com'],
    ['id' => 9, 'email' => 'bala@example.com'],
    ['id' => 12, 'email' => 'charu@example.com'],
];

$index = array_search('bala@example.com', array_column($users, 'email'), true);

if ($index !== false) {
    echo "Found user #{$users[$index]['id']}\n";
}

Output

Found user #9

array_column() builds a list of emails with the same positions as $users, so the index found in it can be used to read the full record. (This assumes $users is a list with keys 0, 1, 2, ….)

Using array_filter() for All Matches

<?php
$products = [
    ['name' => 'Gel Pen', 'category' => 'Stationery', 'price' => 20],
    ['name' => 'Desk Lamp', 'category' => 'Home', 'price' => 1299],
    ['name' => 'Notebook', 'category' => 'Stationery', 'price' => 60],
];

$stationery = array_filter($products, fn(array $p): bool => $p['category'] === 'Stationery');

echo implode(', ', array_column($stationery, 'name')) . "\n";

Output

Gel Pen, Notebook

array_filter() returns every matching record, preserving keys.


PHP 8.4: array_find(), array_find_key(), array_any(), array_all()

PHP 8.4 added functions that search with a callback and stop as soon as the answer is known:

<?php
$products = [
    ['name' => 'Gel Pen', 'price' => 20, 'stock' => 100],
    ['name' => 'Desk Lamp', 'price' => 1299, 'stock' => 0],
    ['name' => 'Backpack', 'price' => 899, 'stock' => 4],
];

$soldOut = array_find($products, fn(array $p): bool => $p['stock'] === 0);
$soldOutKey = array_find_key($products, fn(array $p): bool => $p['stock'] === 0);

var_dump($soldOut['name'], $soldOutKey);
var_dump(array_any($products, fn(array $p): bool => $p['price'] > 1000));
var_dump(array_all($products, fn(array $p): bool => $p['stock'] > 0));
var_dump(array_find($products, fn(array $p): bool => $p['price'] > 5000));

Output

string(9) "Desk Lamp"
int(1)
bool(true)
bool(false)
NULL
FunctionReturns
array_find()The first value for which the callback returns true, or null
array_find_key()The key of that value, or null
array_any()true if at least one element matches
array_all()true if every element matches

The callback receives the value and the key. These functions replace common loops with break, and they stop at the first decisive element. On PHP versions before 8.4, use a foreach loop with break or return.


Pattern Searches: preg_grep()

<?php
$fruits = ['Mango', 'Guava', 'Grapes', 'Apple'];

print_r(preg_grep('/^g/i', $fruits));

Output

Array
(
    [1] => Guava
    [2] => Grapes
)

preg_grep() returns elements matching a regular expression, preserving keys. Here, ^g means "starts with g", and the i modifier makes it case-insensitive. See the PHP RegEx section.

<?php
$tags = ['PHP', 'MySQL', 'Laravel'];
$search = 'mysql';

$found = in_array(mb_strtolower($search), array_map('mb_strtolower', $tags), true);

var_dump($found);

Output

bool(true)

Lowercasing both the search term and the array makes the comparison case-insensitive. When this lookup happens often, store the lowercase version once instead of converting on every search.


Fast Lookups With Keys

in_array() and array_search() check elements one by one, so their time grows with the array size. Checking a key with isset() takes about the same time no matter how big the array is. For repeated lookups, flip the list into keys once:

<?php
$blockedDomains = array_flip(['spam.com', 'fake.org', 'temp-mail.net']);

$emails = ['asha@gocourse.in', 'spammer@spam.com', 'bala@fake.org', 'charu@gmail.com'];

foreach ($emails as $email) {
    $domain = strtolower(substr(strrchr($email, '@'), 1));
    $status = isset($blockedDomains[$domain]) ? 'blocked' : 'allowed';
    echo "$email: $status\n";
}

Output

asha@gocourse.in: allowed
spammer@spam.com: blocked
bala@fake.org: blocked
charu@gmail.com: allowed

How It Works

  1. array_flip() turns ['spam.com', 'fake.org', ...] into ['spam.com' => 0, 'fake.org' => 1, ...].
  2. strrchr($email, '@') returns the part from the last @; substr(..., 1) removes the @.
  3. isset($blockedDomains[$domain]) checks the domain as a key — very fast even with thousands of blocked domains.

For a list of 10 items, the difference is negligible. For large lists checked many times (for example, inside a loop over thousands of records), key lookups are dramatically faster.


Common Mistakes

Effect: Numeric strings match integers, and null matches 0 or '', so invalid input can pass checks.

Fix: Pass true for strict comparison.

Checking array_search() With if ($key)

Effect: A match at key 0 looks like "not found".

Fix: if ($key !== false).

Searching Values When You Need Keys (or the Reverse)

Effect: in_array('Pen', $prices) searches prices, not product names.

Fix: Use array_key_exists() / isset() for keys and in_array() for values.

Repeated in_array() on Large Arrays

Effect: Slow code inside loops.

Fix: Flip the array once and use isset().

Using isset() When null Is a Valid Value

Effect: Existing keys with null values are reported as missing.

Fix: Use array_key_exists().


Best Practices

  • Use strict comparison in in_array(), array_search(), and array_keys().
  • Compare array_search() results with !== false.
  • Use array_find(), array_any(), and array_all() (PHP 8.4+) for condition-based searches.
  • Use key lookups (isset() on a flipped array) for frequent membership checks.
  • Search in the database (WHERE) when the data comes from a query, instead of loading everything into PHP.

Official reference: https://www.php.net/manual/en/function.in-array.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning
Ask about this post
AI Ask about this post

Ask questions about Search in Arrays and get answers drawn from it.

Signed-in readers only.