検索フォームやフィルター画面など、ユーザーから受け取った検索パラメータには、実際には使わない空値が含まれていることがよくあります。
そこで、意味のある値だけを抽出し、検索条件として使えるように整形する方法を、array_filter()
と 再利用可能な関数 を使って紹介します。
概要
- 空文字 (
''
)、null、空配列 ([]
)、数値の 0 などの「検索条件として使わない値」を除外したい - ただし、
0
が「有効な条件」である項目(例:is_active = 0
)は除外したくない - フィルター処理を共通関数化し、複数ページ・APIでも使い回したい
完成コード:buildSearchParams() 関数
function buildSearchParams(array $input): array
{
// 1. 許可される値の一覧(ホワイトリスト)
$allowed_status = [0, 1, 9];
$allowed_tags = [1, 2, 3, 4];
$allowed_regions = [10, 20, 30];
$params = [];
// 2. 任意入力項目:trimして文字列の空白を除去
$params['keyword'] = trim($input['keyword'] ?? '');
$params['extra_info'] = trim($input['extra_info'] ?? '');
// 3. 単一選択:値をintに変換してホワイトリストに含まれるか判定
$status = isset($input['status']) ? (int)$input['status'] : null;
if (in_array($status, $allowed_status, true)) {
$params['status'] = $status;
}
$category_id = isset($input['category_id']) ? (int)$input['category_id'] : null;
if ($category_id > 0) {
$params['category_id'] = $category_id;
}
// 4. 明示的に 0 を許可する項目(例:未公開)
$is_active = isset($input['is_active']) ? (int)$input['is_active'] : null;
if (in_array($is_active, [0, 1], true)) {
$params['is_active'] = $is_active;
}
// 5. 複数選択:配列にキャストしてから int に変換 → 許可された値のみ残す
$tags = array_map('intval', (array)($input['tag_ids'] ?? []));
$tags = array_values(array_intersect($tags, $allowed_tags));
if ($tags) {
$params['tag_ids'] = $tags;
}
$regions = array_map('intval', (array)($input['region_ids'] ?? []));
$regions = array_values(array_intersect($regions, $allowed_regions));
if ($regions) {
$params['region_ids'] = $regions;
}
// 6. 空データを除外(is_active の 0 は残す)
return array_filter(
$params,
function ($value, $key) {
if ($key === 'is_active') return true;
return !($value === '' || $value === null || $value === [] || $value === 0);
},
ARRAY_FILTER_USE_BOTH
);
}
各ブロックのポイント解説
1. 許可リスト(ホワイトリスト)を用意する
検索条件として使える値を制限することで、
無効なIDや意図しない数値が混入するのを防ぐことができます。
$allowed_status = [0, 1, 9];
→ 例:ステータスが「公開」「下書き」「削除済み」など
2. 任意入力は trim() のみでOK
テキスト入力は基本的に空白を除去すれば十分です。
$params['keyword'] = trim($input['keyword'] ?? '');
→ 未入力であれば ''
になるので、後の array_filter
で除外されます。
3. 単一の数値入力は intval() と in_array() を併用
GETパラメータは文字列として渡ってくるため、まず整数に変換し、
許容された値かどうかをチェックします。
$status = isset($input['status']) ? (int)$input['status'] : null;
in_array(..., true)
によって型比較(===)を強制し、"0"
のような文字列を除外できます。
4. 0 を意味のある値として許可したい場合
例:is_active = 0
は「無効」の意味があるので、除外してはいけません。
そのため、後段のフィルターで特別扱いするようにします。
if (in_array($is_active, [0, 1], true)) {
$params['is_active'] = $is_active;
}
5. 複数選択肢は「キャスト→フィルタ」の2段階
$_GET['tag_ids']
が単一か複数か不明なときも(array)
キャストで安定化intval()
で文字列数値を強制的に整数化array_intersect()
で不要なID(例:99など)を削除
$tags = array_map('intval', (array)($input['tag_ids'] ?? []));
6. 最後に不要値を一括除外(ただし例外キーは残す)
この部分が今回のポイントです。
return array_filter(
$params,
function ($value, $key) {
if ($key === 'is_active') return true;
return !($value === '' || $value === null || $value === [] || $value === 0);
},
ARRAY_FILTER_USE_BOTH
);
ARRAY_FILTER_USE_BOTH
により「キー」も条件に使える- 特定のキー(例:is_active)を例外的に残すことが可能
- 一般的な空要素(
''
,null
,[]
,0
)は削除されます
使用例
$searchParams = buildSearchParams($_GET);
この $searchParams
をそのままSQLやAPIに渡すことで、
無駄のない、精度の高い検索条件として活用できます。
応用・拡張アイデア
- 許容値リスト(ホワイトリスト)を関数外から渡すようにするとより汎用的になります
- 除外対象キーを複数指定したい場合は、配列で持って
in_array($key, $exempt_keys)
にする - LaravelやSlimでは、この関数をサービスクラスやヘルパークラスに配置するとより自然です
まとめ
array_filter()
とARRAY_FILTER_USE_BOTH
の組み合わせで、値とキーを柔軟に評価可能- 「0」を除外したくないケースでは、キーによる例外処理が非常に有効
- 関数化すれば、再利用性・可読性・保守性が大きく向上
コメント