How to Check If an Array Contains All Elements of Another Array in PHP?

In PHP, checking if an array contains all elements of a second array, depends on how you wish to handle the case where the first array is empty:

  1. Vacuously True;
  2. Non-Vacuously True.

Vacuously True

When checking if an array contains all elements of a second array, if you follow the mathematical definition of Subsets, you can use any of the following functions:

  1. Using array_diff()

    function isSubset(array $arr1, array $arr2): bool
    {
        // check if there's no difference between `arr1` and `arr2`, indicating `arr1` is a subset of `arr2`
        return ! array_diff($arr1, $arr2);
    }
    
  2. Using array_intersect()

    function isSubset(array $arr1, array $arr2): bool
    {
        // 1: find the common elements between `arr1` and `arr2`
        $result = array_intersect($arr1, $arr2);
        // 2: if the number of common elements are the same as `arr1`, then `arr1` is a subset of `arr2`
        return $result === $arr1;
    }
    
  3. Using a Loop

    function isSubset(array $arr1, array $arr2): bool
    {
        $containsAll = true;
        // 1: iterate over each element in `arr1`
        foreach ($arr1 as $value) {
            // 2: check if the current value does not exist in `arr2`
            if (! in_array($value, $arr2)) {
                $containsAll = false;
                // 2.1: `arr1` is not a subset of `arr2`
                break;
            }
        }
    
        // 2.2: `arr1` is a subset of `arr2`
        return $containsAll;
    }
    

All of these functions will produce the same result:

// case 1: first array contains all elements of second array
var_dump(isSubset([1, 2, 3], [1, 2, 3])); // true
var_dump(isSubset([1, 2], [1, 2, 3])); // true
var_dump(isSubset([], [1, 2, 3])); // true
var_dump(isSubset([], [])); // true

// case 2: first array does not contain all elements of second array
var_dump(isSubset([1, 2, 3], [1, 2])); // false
var_dump(isSubset([1, 2, 3], [])); // false

This handles the following edge case differently than the non-vacuously true context:

// ...
var_dump(isSubset([], [1, 2, 3])); // true
// ...

In this case, the mathematical statement, "[] is a subset of [1, 2, 3]" is considered "vacuously true" — i.e., it's considered to be true based on the absence of a condition or the lack of elements. In other words, a statement is vacuously true if it is true because the relevant condition or criteria for it to be false does not exist or is not applicable.

Non-Vacuously True

In a mathematical context, when "A" is empty, "B" is vacuously a subset of "A", explaining why isSubset([], [1, 2, 3]) returns true in the previous example. However, this might not align with expectations in certain contexts, as an empty set "A" technically contains no elements, including nothing from "B". You can handle this case differently by using any of the following functions:

  1. Using array_diff()

    function hasAllElems(array $arr1, array $arr2): bool
    {
        // 1: `arr1` is empty and `arr2` is not
        if (! $arr1 && $arr2) {
            return false;
        }
    
        // 2: `arr1` is a subset of `arr2` if there's no difference between them
        return ! array_diff($arr1, $arr2);
    }
    
  2. Using array_intersect()

    function hasAllElems(array $arr1, array $arr2): bool
    {
        // 1: `arr1` is empty and `arr2` is not
        if (! $arr1 && $arr2) {
            return false;
        }
    
        // 2: find the common elements between `arr1` and `arr2`
        $result = array_intersect($arr1, $arr2);
        // 3: if the number of common elements are the same as `arr1`, then `arr1` is a subset of `arr2`
        return $result === $arr1;
    }
    
  3. Using a Loop

    function hasAllElems(array $arr1, array $arr2): bool
    {
        // 1: `arr1` is empty and `arr2` is not
        if (! $arr1 && $arr2) {
            return false;
        }
    
        $containsAll = true;
        // 2: iterate over each element in `arr1`
        foreach ($arr1 as $value) {
            // 3: check if the current value does not exist in `arr2`
            if (! in_array($value, $arr2)) {
                $containsAll = false;
                // 3.1: `arr1` is not a subset of `arr2`
                break;
            }
        }
    
        // 3.2: `arr1` is a subset of `arr2`
        return $containsAll;
    }
    

These variations allow you to handle the case differently where the first array is empty and the second array is not, rather than being considered "vacuously true". All of these functions will produce the same result:

// case 1: first array contains all elements of second array
var_dump(hasAllElems([1, 2, 3], [1, 2, 3])); // true
var_dump(hasAllElems([1, 2], [1, 2, 3])); // true
var_dump(hasAllElems([], [])); // true

// case 2: first array does not contain all elements of second array
var_dump(hasAllElems([1, 2, 3], [1, 2])); // false
var_dump(hasAllElems([1, 2, 3], [])); // false
var_dump(hasAllElems([], [1, 2, 3])); // false

As you can see, in this instance, the following edge case is handled differently than the vacuously true mathematical context:

// ...
var_dump(hasAllElems([], [1, 2, 3])); // false
// ...

This post was published (and was last revised ) by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.