Current Location: Home> Latest Articles> Encapsulate the logic of array_filter() into multiplexed components

Encapsulate the logic of array_filter() into multiplexed components

M66 2025-06-03

In PHP, array_filter() is a very powerful function that can filter arrays based on the callback function we pass in. However, in large projects or scenarios where similar filtering logic is used in multiple places, directly writing anonymous functions at each call point is not conducive to code reuse and maintenance. This article will introduce how to encapsulate the filtering logic of array_filter() into a reusable component to make your code more elegant and maintainable.

1. Review of basic usage

Let's first look at the most basic usage:

 $data = [1, 2, 3, 4, 5];

// Filter out even numbers
$filtered = array_filter($data, function($item) {
    return $item % 2 === 0;
});

print_r($filtered);

Although the above code is simple, if we need the logic of "filtering even numbers" in multiple places, we will face the problem of code duplication.

2. Encapsulation filtering logic into class

We can encapsulate commonly used filtering logic into a class and call it through a unified interface to achieve reusability.

 class ArrayFilter
{
    protected array $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function filter(callable $callback): array
    {
        return array_filter($this->data, $callback);
    }
}

How to use:

 $data = [1, 2, 3, 4, 5];
$filter = new ArrayFilter($data);

$result = $filter->filter(function ($item) {
    return $item % 2 === 0;
});

print_r($result);

3. Independently encapsulate filter logic into policy classes

In order to further decouple logic, we can encapsulate the filter conditions into "strategy classes":

 interface FilterStrategyInterface
{
    public function apply($item): bool;
}

class EvenNumberFilter implements FilterStrategyInterface
{
    public function apply($item): bool
    {
        return $item % 2 === 0;
    }
}

Then modify the ArrayFilter class to receive this policy:

 class StrategyArrayFilter
{
    protected array $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function filter(FilterStrategyInterface $strategy): array
    {
        return array_filter($this->data, [$strategy, 'apply']);
    }
}

How to use:

 $data = [1, 2, 3, 4, 5];
$filter = new StrategyArrayFilter($data);

$result = $filter->filter(new EvenNumberFilter());

print_r($result);

In this way, each filtering logic can be defined separately as a class, implementing a good code organization structure for easy testing and reuse.

4. Dynamic registration filter

If you want to configure filters more flexibly (such as selecting policies based on configuration files), you can add a "factory class" or "service registration mechanism". Here is a simple service registration example:

 class FilterFactory
{
    public static function create(string $type): FilterStrategyInterface
    {
        return match ($type) {
            'even' => new EvenNumberFilter(),
            default => throw new InvalidArgumentException("Unknown filter type: $type")
        };
    }
}

The usage is as follows:

 $filterType = 'even'; // Assume from configuration or user input
$strategy = FilterFactory::create($filterType);

$filter = new StrategyArrayFilter([1, 2, 3, 4, 5]);
$result = $filter->filter($strategy);

print_r($result);

5. Summary

By encapsulating the callback function of array_filter() into a class, we can implement a clearer, easier to test and maintain code structure. This strategy pattern is very suitable for handling complex or variable filtering logic, especially in large applications.