PHPでは、 array_filter()は、渡すコールバック関数に基づいて配列をフィルタリングできる非常に強力な関数です。ただし、複数の場所で同様のフィルタリングロジックが使用される大規模なプロジェクトまたはシナリオでは、各コールポイントに匿名関数を直接書き込むことはコードの再利用とメンテナンスに信頼できません。この記事では、array_filter()のフィルタリングロジックを再利用可能なコンポーネントにカプセル化する方法を紹介して、コードをよりエレガントで保守可能にします。
まず、最も基本的な使用法を見てみましょう。
$data = [1, 2, 3, 4, 5];
// 偶数を除外します
$filtered = array_filter($data, function($item) {
return $item % 2 === 0;
});
print_r($filtered);
上記のコードは簡単ですが、複数の場所で「偶数のフィルタリング」のロジックが必要な場合は、コードの複製の問題に直面します。
一般的に使用されるフィルタリングロジックをクラスにカプセル化し、統一されたインターフェイスを介して呼び出すことができます。
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);
}
}
使い方:
$data = [1, 2, 3, 4, 5];
$filter = new ArrayFilter($data);
$result = $filter->filter(function ($item) {
return $item % 2 === 0;
});
print_r($result);
ロジックをさらに切り離すために、フィルター条件を「戦略クラス」にカプセル化できます。
interface FilterStrategyInterface
{
public function apply($item): bool;
}
class EvenNumberFilter implements FilterStrategyInterface
{
public function apply($item): bool
{
return $item % 2 === 0;
}
}
次に、 ArrayFilterクラスを変更して、このポリシーを受信します。
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']);
}
}
使い方:
$data = [1, 2, 3, 4, 5];
$filter = new StrategyArrayFilter($data);
$result = $filter->filter(new EvenNumberFilter());
print_r($result);
このようにして、各フィルタリングロジックはクラスとして個別に定義でき、簡単なテストと再利用のために優れたコード組織構造を実装できます。
フィルターをより柔軟に構成する場合(構成ファイルに基づいてポリシーを選択するなど)、「ファクトリークラス」または「サービス登録メカニズム」を追加できます。簡単なサービス登録例は次のとおりです。
class FilterFactory
{
public static function create(string $type): FilterStrategyInterface
{
return match ($type) {
'even' => new EvenNumberFilter(),
default => throw new InvalidArgumentException("Unknown filter type: $type")
};
}
}
使用法は次のとおりです。
$filterType = 'even'; // 構成またはユーザー入力から仮定します
$strategy = FilterFactory::create($filterType);
$filter = new StrategyArrayFilter([1, 2, 3, 4, 5]);
$result = $filter->filter($strategy);
print_r($result);
array_filter()のコールバック関数をクラスにカプセル化することにより、コード構造をより明確で簡単にテストし、維持できるように実装できます。この戦略パターンは、特に大規模なアプリケーションでは、複雑なまたは可変フィルタリングロジックを処理するのに非常に適しています。