261

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?

hakre
  • 178,314
  • 47
  • 389
  • 754
laukok
  • 47,545
  • 146
  • 388
  • 689
  • 1
    The accepted solution works great but may lead to **unintended results** when doing non-strict comparisons due to PHP's type juggling. See: https://stackoverflow.com/a/48890256/1579327 – Paolo Feb 20 '18 at 17:07
  • @Paolo thanks for the comment. what is the solution then? Is it the answer you just posted? – laukok Feb 22 '18 at 09:37
  • 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. – Paolo Feb 22 '18 at 09:50
  • 1
    one liner: `var_dump(array_sum(array_map(function ($tmp) {return in_array('NT',$tmp);}, $multiarray)) > 0);` – Agnius Vasiliauskas Feb 22 '18 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"));` – Paolo Feb 22 '18 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. – Agnius Vasiliauskas Feb 22 '18 at 11:13

23 Answers23

487

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';
jwueller
  • 28,909
  • 4
  • 60
  • 69
  • 1
    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. – laukok Nov 08 '10 at 22:00
  • @acoder: Yes, unless the strict parameter is set to `false`. It has the exact same parameters as `in_array()` to make it more intuitive. One small exception is that I chose to use make the strict comparison the default behavior to minimize unintended side-effects. – jwueller Nov 08 '12 at 23:05
  • I know this is old, but it's so well written it deserves a compliment. I would change the default value of strict to false, so that it mimics the in_array default. – Manatax Dec 20 '12 at 05:38
  • @Manatax: Thank you! You are probably right. People should use the strict mode (which is why I made it the default), but most will probably expect it to work like `in_array()`, so I changed it to `false`. – jwueller Dec 20 '12 at 05:57
  • 14
    I was looking for something that did this, you just saved me from writing my own :) – Liam W Jul 19 '13 at 14:42
  • why the return false in the end? – mercy Mar 10 '14 at 12:37
  • @mercy: How else would you indicate that the value is not present? – jwueller Mar 10 '14 at 15:49
  • @elusive: Sorry, i'm used to putting that in the 'else' part and I got confused. – mercy Mar 11 '14 at 06:22
  • I've never found such a beautifuk answer so fast as I needed. I was thinking about how would it be using "in_array()", I imagined something like in_array('something', $array[][][])... wouldn't work thanks for quitting me of even test this shi... – I Wanna Know Jan 08 '15 at 11:14
  • @jwueller do you mind if I use this exact function in my code without attribution? – D.Tate Feb 05 '15 at 18:06
  • 1
    It works great. So how can we search and display array key? For example: $b = array(1 => array("Mac", "NT"), 3 => array("Irix", "Linux")); – Rashad Feb 06 '15 at 11:19
  • Thanks! In my case, I needed to search a value, but display a key, so I used `return $item;` instead of `return true;` – Robert Dundon Feb 11 '15 at 14:31
  • 2
    @D.Tate Code on StackOverflow is licensed under [cc by-sa 3.0](https://creativecommons.org/licenses/by-sa/3.0/) with attribution required (see page footer). You can just include a comment with the permalink to this answer. – jwueller Jul 02 '17 at 22:15
  • Did anybody notice that inside the `in_array_r` `in_array_r` is called, instead of `in_array`? Can you please edit your answer @jwueller? – blamb Sep 19 '17 at 23:14
  • 1
    @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. – jwueller Sep 20 '17 at 19:15
  • Interesting! I dont believe i have called a function from within its own definition, do you have any documentation on that feature? So, i didnt use the `_r` and it worked for me, so im guessing this is because it was only nested one level deep then? – blamb Sep 20 '17 at 21:21
71

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;

ethmz
  • 1,164
  • 1
  • 11
  • 23
56

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!
}
revo
  • 43,830
  • 14
  • 67
  • 109
NassimPHP
  • 926
  • 8
  • 10
  • 3
    Clever, I like this. I wonder what the performance is like compared with the `foreach` loop. – James Aug 19 '16 at 16:19
  • 1
    Worked like a charm. – kemicofa ghost Oct 21 '16 at 13:04
  • 1
    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. – mickmackusa Mar 03 '17 at 12:53
  • Note that this will fail if `$item` contains characters that screws up the first parameter (regular expression) of `preg_match` – Paolo Feb 22 '18 at 10:46
34

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.

Alan Geleynse
  • 23,597
  • 5
  • 43
  • 54
  • 7
    However, this will only work in one dimension. You'll have to create a recursive function in order to check each depth. – metrobalderas Nov 08 '10 at 21:44
  • 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. – laukok Nov 08 '10 at 21:51
  • @lauthiamkok: There is a `)` missing at the end of the mentioned line. – jwueller Nov 08 '10 at 21:52
  • Thanks, I fixed my answer. That's what happens when I type too fast and don't reread my code. – Alan Geleynse Nov 08 '10 at 21:53
  • You should always call `in_array()` with the third parameter set to `true`. Check out here why: http://stackoverflow.com/questions/37080581/why-does-in-array-return-unexpected-strange-results – Andreas May 16 '16 at 08:37
25

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");

rynhe
  • 2,481
  • 1
  • 18
  • 27
22
$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';
}
Azam Alvi
  • 6,144
  • 5
  • 57
  • 80
Mukesh Goyal
  • 383
  • 3
  • 9
14

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

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

Mohd Abdul Mujib
  • 10,585
  • 8
  • 50
  • 78
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;
}
Alberto Zaccagni
  • 28,473
  • 10
  • 71
  • 102
Fernando
  • 149
  • 1
  • 2
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:

  • 1
    Thats wrong. Your function will also give true if the search-string is contain in some array-value (will find "Irix" in "mytoll Irixus"). – mdunisch May 16 '14 at 15:28
  • I've fixed my answer. @user3351722 –  May 16 '14 at 18:15
  • 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.'";'); – Anees Hikmat Abu Hmiad Jun 26 '14 at 08:08
  • @MisterDood this answer still valid i want to use it for my webapp please reply asap – Giant Oct 15 '14 at 10:14
  • 2
    @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. –  Oct 16 '14 at 18:50
  • @MisterDood thank you for fast reply sir i just want to be sure it is ok – Giant Oct 17 '14 at 03:54
  • @I--I No worries. I'm glad you cared enough to ask. I wish there were more people in the world like you. –  Oct 17 '14 at 04:45
  • 1
    Interesting answer, definitely works in certain situations, but not all. – MKN Web Solutions Aug 06 '15 at 03:33
6

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)
Fabien Salles
  • 921
  • 11
  • 20
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!";
  }
?>
SrAxi
  • 18,577
  • 10
  • 42
  • 65
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;
}
Paolo
  • 13,439
  • 26
  • 59
  • 82
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;
    }
?>
Gazillion
  • 4,722
  • 10
  • 38
  • 59
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.

Meloman
  • 2,745
  • 3
  • 35
  • 39
  • 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. – Paolo Feb 22 '18 at 10:06
  • Of course it depends what you will do, but for me this solution has fast execution and is enough. – Meloman Feb 23 '18 at 13:37
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;
}
FreshSnow
  • 324
  • 2
  • 12
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);
Banzy
  • 688
  • 6
  • 10
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.

andreszs
  • 2,589
  • 2
  • 22
  • 28
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";
          }
Dhruv Thakkar
  • 115
  • 2
  • 11
0

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;
        }
    }
Sr. Libre
  • 123
  • 1
  • 9
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
}
Svenwas3f
  • 73
  • 1
  • 11
-1

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

Anne
  • 26,035
  • 9
  • 61
  • 70
sparco
  • 65
  • 7
  • 2
    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. – Ben D Sep 22 '12 at 19:52
-1

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";
}
Shirker
  • 921
  • 2
  • 13
  • 29
  • actually array_search is not recursive, so this does not work. I wish it did becuase this is so clean and simple. http://php.net/manual/en/function.array-search.php – MatthewLee Jul 10 '14 at 17:57
-1

you can use like this

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

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

mak
  • 329
  • 1
  • 3
  • 19