Filtering an array with a string mask in PHP


I’ve been working on a solution the Kohana problem of the Validation library being unable to validate cleanly inside multidimensional arrays, and the root of this problem is passing a mask to the Validation::add_rules() method to identify deeply nested elements. In the course of trying to work out this problem, I wrote a function that accepts a mask and an array and returns the filtered array. While it doesn’t get me any closer to my actual goal, I do think it is an interesting function nonetheless and could be quite useful in the right circumstances. In the future, I might tweak this to allow you to invert the results, whereby it deletes anything that matches the mask, rather than preserves those that match the mask.

An example of a mask would be “messages/*/timestamp” would only keep elements of the array that matched $array['messages'][*]['timestamp'] with * being a wildcard.

function array_mask_filter($mask, $array, $ci = false) {
    if(!is_string($mask)) {
        throw new exception('filter mask must be a string');
    }

    if(!is_array($array)) {
        throw new exception('variable to be filtered must be an array');
    }

    $mask_chunks = explode('/', $mask);

    $this_mask = array_shift($mask_chunks);

    if($this_mask != '*') {
        foreach(array_keys($array) as $key) {
            $key = $ci ? strtolower($key) : $key;
            $this_mask = $ci ? strtolower($this_mask) : $this_mask;
            if($key !== $this_mask) {
                unset($array[$key]);
            }
        }
    }

    foreach(array_filter($array, 'is_array') as $key=>$element) {
        $array[$key] = array_mask_filter($element, implode('/', $mask_chunks));
        if(empty($array[$key])) {
            unset($array[$key]);
        }
    }

    return $array;
}

,

  1. No comments yet.
(will not be published)
  1. No trackbacks yet.