294

I use in_array() to check whether a value exists in an array like below,

$a = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $a)) 
{
    echo "Got Irix";
}

//print_r($a);

but what about an multidimensional array (below) - how can I check that value whether it exists in the multi-array?

$b = array(array("Mac", "NT"), array("Irix", "Linux"));

print_r($b);

or I shouldn't be using in_array() when comes to the multidimensional array?

6
  • 1
    The accepted solution works great but may lead to unintended results when doing non-strict comparisons due to PHP's type juggling. See: stackoverflow.com/a/48890256/1579327 Commented Feb 20, 2018 at 17:07
  • 1
    both jwueller's answer and mine are correct answers to your question. I proposed an alternate solution that extends jwueller's function in order to avoid a common pitfail due to PHP's type juggling when doing non-strict comparisons. Commented Feb 22, 2018 at 9:50
  • 1
    one liner: var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0); Commented Feb 22, 2018 at 10:00
  • 1
    @AgniusVasiliauskas clever solution, but has issues if the first-level array contains an item that's not an array, ex: $multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux")); Commented Feb 22, 2018 at 10:19
  • 1
    @Paolo Nobody stops you from expanding anonymous function according to your needs - in this case add check in anonymous function if variable $tmp is an array with is_array() function. If not an array - proceed with different scenario. Commented Feb 22, 2018 at 11:13

25 Answers 25

510

in_array() does not work on multidimensional arrays. You could write a recursive function to do that for you:

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}

Usage:

$b = array(array("Mac", "NT"), array("Irix", "Linux"));
echo in_array_r("Irix", $b) ? 'found' : 'not found';
Sign up to request clarification or add additional context in comments.

16 Comments

thank you. the function is elegant! love it! thanks. how can i know it returns true or false as my screen doest show anything when I run your function? thanks.
I was looking for something that did this, you just saved me from writing my own :)
It works great. So how can we search and display array key? For example: $b = array(1 => array("Mac", "NT"), 3 => array("Irix", "Linux"));
@D.Tate Code on StackOverflow is licensed under cc by-sa 3.0 with attribution required (see page footer). You can just include a comment with the permalink to this answer.
@blamb: That is very intentional. This is what makes the function recursive (hence the _r, analogous to print_r(), for example). It descends into all nested arrays to search for the value until there are no more arrays to be found. This way, you can search through arrays of arbitrary complexity instead of just two levels deep.
|
105

If you know which column to search against, you can use array_search() and array_column():

$userdb = Array
(
    (0) => Array
        (
            ('uid') => '100',
            ('name') => 'Sandra Shush',
            ('url') => 'urlof100'
        ),

    (1) => Array
        (
            ('uid') => '5465',
            ('name') => 'Stefanie Mcmohn',
            ('url') => 'urlof5465'
        ),

    (2) => Array
        (
            ('uid') => '40489',
            ('name') => 'Michael',
            ('url') => 'urlof40489'
        )
);

if(array_search('urlof5465', array_column($userdb, 'url')) !== false) {
    echo 'value is in multidim array';
}
else {
    echo 'value is not in multidim array';
}

This idea is in the comments section for array_search() on the PHP manual;

6 Comments

You can also try: in_array('value', array_column($arr, 'active'))
You need PHP 5.5+ for array_column
Is it possible to get the uid of the matched sub array in this example? @ethmz
this is exactly what i want
This is perfect after a long found this solution!
|
61

This will work too.

function in_array_r($item , $array){
    return preg_match('/"'.preg_quote($item, '/').'"/i' , json_encode($array));
}

Usage:

if(in_array_r($item , $array)){
    // found!
}

4 Comments

Clever, I like this. I wonder what the performance is like compared with the foreach loop.
Worked like a charm.
Don't get me wrong, I like this approach for this case. However it will return a false positive match when json_encoding an $array that has an associative key that matches $item. Not to mention the potential to unintentionally match part of a string when there is a double quote in the string itself. I would only trust this function in small/simple situations like this question.
Note that this will fail if $item contains characters that screws up the first parameter (regular expression) of preg_match
35

This will do it:

foreach($b as $value)
{
    if(in_array("Irix", $value, true))
    {
        echo "Got Irix";
    }
}

in_array only operates on a one dimensional array, so you need to loop over each sub array and run in_array on each.

As others have noted, this will only for for a 2-dimensional array. If you have more nested arrays, a recursive version would be better. See the other answers for examples of that.

5 Comments

However, this will only work in one dimension. You'll have to create a recursive function in order to check each depth.
i ran the code but it has an error - Parse error: parse error in C:\wamp\www\000_TEST\php\php.in_array\index.php on line 21 - which is if(in_array("Irix", $value) thanks.
@lauthiamkok: There is a ) missing at the end of the mentioned line.
Thanks, I fixed my answer. That's what happens when I type too fast and don't reread my code.
You should always call in_array() with the third parameter set to true. Check out here why: stackoverflow.com/questions/37080581/…
30
$userdb = Array
(
    (0) => Array
        (
            ('uid') => '100',
            ('name') => 'Sandra Shush',
            ('url') => 'urlof100'
        ),

    (1) => Array
        (
            ('uid') => '5465',
            ('name') => 'Stefanie Mcmohn',
            ('url') => 'urlof5465'
        ),

    (2) => Array
        (
            ('uid') => '40489',
            ('name') => 'Michael',
            ('url') => 'urlof40489'
        )
);

$url_in_array = in_array('urlof5465', array_column($userdb, 'url'));

if($url_in_array) {
    echo 'value is in multidim array';
}
else {
    echo 'value is not in multidim array';
}

4 Comments

While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
6 years later, it gave me what I need. array_column()
perfect answer for multidimensional array
Lil goodie : we can also search a key of a value with array_column() : $key_product = array_search($featured_prod_id, array_column($PRODUCTS_ARRAY, 'id') ); // So ? - no need to make a loop for retrieve key of an entry, this make sense for me in a context given.
26

if your array like this

$array = array(
              array("name" => "Robert", "Age" => "22", "Place" => "TN"), 
              array("name" => "Henry", "Age" => "21", "Place" => "TVL")
         );

Use this

function in_multiarray($elem, $array,$field)
{
    $top = sizeof($array) - 1;
    $bottom = 0;
    while($bottom <= $top)
    {
        if($array[$bottom][$field] == $elem)
            return true;
        else 
            if(is_array($array[$bottom][$field]))
                if(in_multiarray($elem, ($array[$bottom][$field])))
                    return true;

        $bottom++;
    }        
    return false;
}

example : echo in_multiarray("22", $array,"Age");

Comments

26

For Multidimensional Children: in_array('needle', array_column($arr, 'key'))

For One Dimensional Children: in_array('needle', call_user_func_array('array_merge', $arr))

3 Comments

And unlike the array_column() method, the call_user_func_array('array_merge') method also works with index-based child arrays, +1
Fantastic! I vote for this solution.
Great, this works; and to reduce overhead (if it matters), isolate the array_column($arr, 'key') into a named static variable as it is basically a numeric-indexed array of the named 'key';
14

Great function, but it didnt work for me until i added the if($found) { break; } to the elseif

function in_array_r($needle, $haystack) {
    $found = false;
    foreach ($haystack as $item) {
    if ($item === $needle) { 
            $found = true; 
            break; 
        } elseif (is_array($item)) {
            $found = in_array_r($needle, $item); 
            if($found) { 
                break; 
            } 
        }    
    }
    return $found;
}

Comments

7

Since PHP 5.6 there is a better and cleaner solution for the original answer :

With a multidimensional array like this :

$a = array(array("Mac", "NT"), array("Irix", "Linux"))

We can use the splat operator :

return in_array("Irix", array_merge(...$a), true)

If you have string keys like this :

$a = array("a" => array("Mac", "NT"), "b" => array("Irix", "Linux"))

You will have to use array_values in order to avoid the error Cannot unpack array with string keys :

return in_array("Irix", array_merge(...array_values($a)), true)

Comments

6

You could always serialize your multi-dimensional array and do a strpos:

$arr = array(array("Mac", "NT"), array("Irix", "Linux"));

$in_arr = (bool)strpos(serialize($arr),'s:4:"Irix";');

if($in_arr){
    echo "Got Irix!";
}

Various docs for things I used:

7 Comments

Thats wrong. Your function will also give true if the search-string is contain in some array-value (will find "Irix" in "mytoll Irixus").
this way can be fixed a problem when no more one (unique vale), and its to be dynamic ..like this $in_arr = (bool)strpos(serialize($user_term_was_downloaded), 's:3:"tid";s:2:"'.$value->tid.'";');
@MisterDood this answer still valid i want to use it for my webapp please reply asap
@I--I I don't think anybody on Stack Overflow would post code if they didn't want it to be shared. Feel free to use any of the code on this website for anything. I usually add a comment one line above the code snippet that says "Thanks Stack Overflow" and then paste the URL I found the code from.
Interesting answer, definitely works in certain situations, but not all.
|
2

I believe you can just use array_key_exists nowadays:

<?php
$a=array("Mac"=>"NT","Irix"=>"Linux");
if (array_key_exists("Mac",$a))
  {
  echo "Key exists!";
  }
else
  {
  echo "Key does not exist!";
  }
?>

Comments

2

The accepted solution (at the time of writing) by jwueller

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}

Is perfectly correct but may have unintended behaviuor when doing weak comparison (the parameter $strict = false).

Due to PHP's type juggling when comparing values of different type both

"example" == 0

and

0 == "example"

Evaluates true because "example" is casted to int and turned into 0.

(See Why does PHP consider 0 to be equal to a string?)

If this is not the desired behaviuor it can be convenient to cast numeric values to string before doing a non-strict comparison:

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {

        if( ! $strict && is_string( $needle ) && ( is_float( $item ) || is_int( $item ) ) ) {
            $item = (string)$item;
        }

        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}

Comments

1

This is the first function of this type that I found in the php manual for in_array. Functions in the comment sections aren't always the best but if it doesn't do the trick you can look in there too :)

<?php
function in_multiarray($elem, $array)
    {
        // if the $array is an array or is an object
         if( is_array( $array ) || is_object( $array ) )
         {
             // if $elem is in $array object
             if( is_object( $array ) )
             {
                 $temp_array = get_object_vars( $array );
                 if( in_array( $elem, $temp_array ) )
                     return TRUE;
             }

             // if $elem is in $array return true
             if( is_array( $array ) && in_array( $elem, $array ) )
                 return TRUE;


             // if $elem isn't in $array, then check foreach element
             foreach( $array as $array_element )
             {
                 // if $array_element is an array or is an object call the in_multiarray function to this element
                 // if in_multiarray returns TRUE, than return is in array, else check next element
                 if( ( is_array( $array_element ) || is_object( $array_element ) ) && $this->in_multiarray( $elem, $array_element ) )
                 {
                     return TRUE;
                     exit;
                 }
             }
         }

         // if isn't in array return FALSE
         return FALSE;
    }
?>

1 Comment

elusive's solution is better since it's just for arrays
1

Here is my proposition based on json_encode() solution with :

  • case insensitive option
  • returning the count instead of true
  • anywhere in arrays (keys and values)

If word not found, it still returns 0 equal to false.

function in_array_count($needle, $haystack, $caseSensitive = true) {
    if(!$caseSensitive) {
        return substr_count(strtoupper(json_encode($haystack)), strtoupper($needle));
    }
    return substr_count(json_encode($haystack), $needle);
}

Hope it helps.

2 Comments

Note that this function matches substrings too: ex 00 into 10000 or lo into Hello. Furthermore will fail is the needle contains any character that json_encode escapes, like double quotes.
Of course it depends what you will do, but for me this solution has fast execution and is enough.
1

I was looking for a function that would let me search for both strings and arrays (as needle) in the array (haystack), so I added to the answer by @jwueller.

Here's my code:

/**
 * Recursive in_array function
 * Searches recursively for needle in an array (haystack).
 * Works with both strings and arrays as needle.
 * Both needle's and haystack's keys are ignored, only values are compared.
 * Note: if needle is an array, all values in needle have to be found for it to
 * return true. If one value is not found, false is returned.
 * @param  mixed   $needle   The array or string to be found
 * @param  array   $haystack The array to be searched in
 * @param  boolean $strict   Use strict value & type validation (===) or just value
 * @return boolean           True if in array, false if not.
 */
function in_array_r($needle, $haystack, $strict = false) {
     // array wrapper
    if (is_array($needle)) {
        foreach ($needle as $value) {
            if (in_array_r($value, $haystack, $strict) == false) {
                // an array value was not found, stop search, return false
                return false;
            }
        }
        // if the code reaches this point, all values in array have been found
        return true;
    }

    // string handling
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle)
            || (is_array($item) && in_array_r($needle, $item, $strict))) {
            return true;
        }
    }
    return false;
}

Comments

1

I used this method works for any number of nested and not require hacking

<?php
    $blogCategories = [
        'programing' => [
            'golang',
            'php',
            'ruby',
            'functional' => [
                'Erlang',
                'Haskell'
            ]
        ],
        'bd' => [
            'mysql',
            'sqlite'
        ]
    ];
    $it = new RecursiveArrayIterator($blogCategories);
    foreach (new RecursiveIteratorIterator($it) as $t) {
        $found = $t == 'Haskell';
        if ($found) {
           break;
        }
    }

Comments

0

Please try:

in_array("irix",array_keys($b))
in_array("Linux",array_keys($b["irix"])

Im not sure about the need, but this might work for your requirement

1 Comment

How would searching the array keys do anything? $b's array keys are just integers... there are no specified keys in these arrays... and array_keys($b["irix"]) will just throw an error, because $b["irix"] doesn't exist.
0

It works too creating first a new unidimensional Array from the original one.

$arr = array("key1"=>"value1","key2"=>"value2","key3"=>"value3");

foreach ($arr as $row)  $vector[] = $row['key1'];

in_array($needle,$vector);

Comments

0

Shorter version, for multidimensional arrays created based on database result sets.

function in_array_r($array, $field, $find){
    foreach($array as $item){
        if($item[$field] == $find) return true;
    }
    return false;
}

$is_found = in_array_r($os_list, 'os_version', 'XP');

Will return if the $os_list array contains 'XP' in the os_version field.

Comments

0

what about array_search? seems it quite faster than foreach according to https://gist.github.com/Ocramius/1290076 ..

if( array_search("Irix", $a) === true) 
{
    echo "Got Irix";
}

1 Comment

actually array_search is not recursive, so this does not work. I wish it did becuase this is so clean and simple. php.net/manual/en/function.array-search.php
0

I found really small simple solution:

If your array is :

Array
(
[details] => Array
    (
        [name] => Dhruv
        [salary] => 5000
    )

[score] => Array
    (
        [ssc] => 70
        [diploma] => 90
        [degree] => 70
    )

)

then the code will be like:

 if(in_array("5000",$array['details'])){
             echo "yes found.";
         }
     else {
             echo "no not found";
          }

Comments

0

I have found the following solution not very clean code but it works. It is used as an recursive function.

function in_array_multi( $needle, $array, $strict = false ) {
  foreach( $array as $value ) { // Loop thorugh all values
    // Check if value is aswell an array
    if( is_array( $value )) {
      // Recursive use of this function
      if(in_array_multi( $needle, $value )) {
        return true; // Break loop and return true
      }
    } else {
      // Check if value is equal to needle
      if( $strict === true ) {
        if(strtolower($value) === strtolower($needle)) {
          return true; // Break loop and return true
        }
      }else {
        if(strtolower($value) == strtolower($needle)) {
          return true; // Break loop and return true
        }
      }
    }
  }

  return false; // Nothing found, false
}

Comments

0

Many of these searches are usually for finding things in a list of records, as some people have pointed out is really a 2-dimensional array.

This is for a list of records that have a uniform set of keys) such as a list of records grabbed from a database, among other things.

Included are both 'in_array' and 'key_exists' styled functions for this structure for completeness. Both functions return a simple true/false boolean answer.

Example 2-dimensional array of records...

$records array:

  [0] => Array
    (
        [first_name] => Charlie
        [last_name] => Brown
    )
  [1] => Array
    (
        [first_name] => Fred
        [last_name] => Sanford
    )

Functions:

function in_multidimensional_array($array, $column_key, $search) { 
   return in_array($search, array_column($array, $column_key)); 
}

function multidimensional_array_key_exists($array, $column_key) { 
   return in_array($column_key, array_keys(array_shift($array))); 
}

Tests:

var_dump(in_multidimensional_array($records, 'first_name', 'Charlie')); // true

var_dump(multidimensional_array_key_exists($records, 'first_name')); // true

Comments

0

From PHP8.4, array_any() offers an elegant functional style approach WITH the performance of a conditional loop break (under-the-hood) to prevent needless iterating.

Code: (Demo)

$haystacks = [
    ["Mac", "NT"],
    ["Irix", "Linux"]
];

$needle = 'Irix';
var_export(
    array_any(
        $haystacks,
        fn($haystack) => in_array($needle, $haystack) 
    )
);
// true

See the polyfill.

Comments

-1

you can use like this

$result = array_intersect($array1, $array2);
print_r($result);

http://php.net/manual/tr/function.array-intersect.php

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.