160
$all = array
(
    0 => 307,
    1 => 157,
    2 => 234,
    3 => 200,
    4 => 322,
    5 => 324
);
$search_this = array
(
    0 => 200,
    1 => 234
);

I would like to find out if $all contains all $search_this values and return true or false. Any ideas please?

Blackbam
  • 17,496
  • 26
  • 97
  • 150
peter
  • 4,289
  • 12
  • 44
  • 67
  • 1
    Possible duplicate of [Checking to see if one array's elements are in another array in PHP](http://stackoverflow.com/questions/523796/checking-to-see-if-one-arrays-elements-are-in-another-array-in-php) – Vishal Kumar Sahu Apr 19 '17 at 10:01
  • 2
    @VishalKumarSahu Not quite a duplicate: Your given link has to do with checking if ANY elements are contained in another array, not if ALL elements are contained in another. – Stefan Jun 20 '17 at 15:15

6 Answers6

321

The previous answers are all doing more work than they need to. Just use array_diff. This is the simplest way to do it:

$containsAllValues = !array_diff($search_this, $all);

That's all you have to do.

Zanshin13
  • 980
  • 4
  • 19
  • 39
orrd
  • 9,469
  • 5
  • 39
  • 31
  • 1
    What about of using `empty(array_diff($search_this, $all));`? – Miguel May 06 '21 at 08:34
  • ! operator on array will always return true. Use @Miguel 's suggestion: empty(array_diff($search_this, $all)); – cquezel Jan 14 '22 at 19:56
  • 1
    The original answer works because an empty array evaluates as false in PHP. Using `empty()` also works, but the `!` operator does work fine. – orrd Jan 17 '22 at 01:35
  • @Miguel an empty array in this context is treated as falsey, there is no need to use `empty`. – zanderwar Apr 08 '22 at 13:17
  • This should actually be flipped, so it reads `$containsAllValues = !array_diff($all, $search_this);` ----- Example: `$containsAllValues = !array_diff($all = ['a', 'b', 'c'], $search_this = ['c', 'c', 'c']);` >> result false ----- Example: `$containsAllValues = !array_diff($search_this = ['c', 'c', 'c'], $search_this = ['a', 'b', 'c']);` >> Result true – bluegman991 Jul 07 '22 at 15:03
  • @bluegman991 That suggestion doesn't work according to my understanding of the question, which is that they want it to return true if every value in `$search_this` is a value that exists in `$all`. So for the arrays `$search_this = ['c', 'c', 'c']` and `$all = ['a', 'b', 'c']` it should return `true`, as my original answer does, because `'c'` exists in `$all`. – orrd Jul 24 '22 at 23:51
  • this answer doesnt work on multidimensional arrays! different values on level 2 or deeper are ignored – Sliq Sep 16 '22 at 15:30
  • 1
    @Sliq This question isn't about multidimensional arrays. – mbomb007 Jul 13 '23 at 14:19
199

Look at array_intersect().

$containsSearch = count(array_intersect($search_this, $all)) === count($search_this);

Or for associative array, look at array_intersect_assoc().

Or for recursive compare of sub-arrays, try:

<?php

namespace App\helpers;

class Common {
    /**
     * Recursively checks whether $actual parameter includes $expected.
     *
     * @param array|mixed $expected Expected value pattern.
     * @param array|mixed $actual Real value.
     * @return bool
     */
    public static function intersectsDeep(&$expected, &$actual): bool {
        if (is_array($expected) && is_array($actual)) {
            foreach ($expected as $key => $value) {
                if (!static::intersectsDeep($value, $actual[$key])) {
                    return false;
                }
            }
            return true;
        } elseif (is_array($expected) || is_array($actual)) {
            return false;
        }
        return (string) $expected == (string) $actual;
    }
}
Top-Master
  • 7,611
  • 5
  • 39
  • 71
jasonbar
  • 13,333
  • 4
  • 38
  • 46
  • 13
    You know you can omit both `count()` calls? – Wrikken Aug 15 '13 at 16:01
  • 1
    @Wrikken Can't the values get reordered during `array_intersect()`? I mean, `['a', 'b'] != ['b', 'a']`. – Stas Bichenko Oct 16 '13 at 18:57
  • 1
    @exizt: `array_intersect()` does not alter the input arrays, so `$search_this` & `$all` are safe (it just returns an output). The function signature is `array array_intersect ( array $array1 , array $array2 [, array $... ] )` (safe). If it would/could alter them, it would be `array array_intersect ( array &$array1 , array &$array2 [, array &$... ] )` (possible altering of input arguments). Also, the keys of `$search_this` are _preserve_, and the order of the first array is kept. So, both key/value pairs, as their order, match. – Wrikken Oct 16 '13 at 21:03
  • 4
    And even then: [array comparison](http://php.net/manual/en/language.operators.array.php): _"`==` TRUE if $a and $b have the same key/value pairs."_, so the order doesn't even matter (use `===` for that) – Wrikken Oct 16 '13 at 21:24
  • 2
    This answer assumes that the $all array only contains unique values. If this is not the case, one may use the array_unique function on the $all array in the array_intersects function. – Relequestual Dec 12 '13 at 21:49
15

A bit shorter with array_diff

$musthave = array('a','b');
$test1 = array('a','b','c');
$test2 = array('a','c');

$containsAllNeeded = 0 == count(array_diff($musthave, $test1));

// this is TRUE

$containsAllNeeded = 0 == count(array_diff($musthave, $test2));

// this is FALSE
javigzz
  • 942
  • 2
  • 11
  • 20
5

I think you're looking for the intersect function

array array_intersect ( array $array1 , array $array2 [, array $ ... ] )

array_intersect() returns an array containing all values of array1 that are present in all the arguments. Note that keys are preserved.

http://www.php.net/manual/en/function.array-intersect.php

shA.t
  • 16,580
  • 5
  • 54
  • 111
James Kyburz
  • 13,775
  • 1
  • 32
  • 33
0

How about this:

function array_keys_exist($searchForKeys = array(), $searchableArray) {
    $searchableArrayKeys = array_keys($searchableArray);

    return count(array_intersect($searchForKeys, $searchableArrayKeys)) == count($searchForKeys); 
}
MaartenDev
  • 5,631
  • 5
  • 21
  • 33
K-Alex
  • 380
  • 1
  • 3
  • 17
0

The other answers work with the given use case, however, you might get a false positive if you're checking "[] exists in $all". One way you can account for this edge case using array_diff() is like so:

function hasAllElems(array $arr1, array $arr2): bool
{
    if (empty($arr1) && ! empty($arr2)) {
        return false;
    }

    return ! array_diff($arr1, $arr2);
}

$searchThis = [0 => 200, 1 => 234];
$all = [0 => 307, 1 => 157, 2 => 234, 3 => 200, 4 => 322, 5 => 324];

var_dump(hasAllElems($searchThis, $all)); // true

var_dump(hasAllElems($all, $searchThis)); // false
var_dump(hasAllElems([], $all)); // false
var_dump(hasAllElems($searchThis, [])); // false

Here, by making an explicit check (i.e. if first array is empty and the second array is not empty), you can return false early in the code.

You can, of course, also use array_intersect() or a loop to achieve the same.

Wrote a blog post for those interested in learning more.

designcise
  • 4,204
  • 1
  • 17
  • 13