在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()的回調函數封裝到類中,我們可以實現更清晰、更易測試和維護的代碼結構。這種策略模式非常適合處理複雜或多變的過濾邏輯,特別是在大型應用中非常有用。