- カテゴリ: PHP
- 掲載バージョン: PHP 8.4(PHP 8.0以降の変更点も記載)
- 名前空間 / FQCN / コマンド:
array_filter(array $array, ?callable $callback = null, int $mode = 0): array - 関連: array_map / array_walk / array_values / Collection::filter / Arr::where
- 変更履歴: PHP 8.0 以降、
$callbackが nullable に対応。また参照渡しパラメータを期待するコールバックを渡すとE_WARNINGが発生するように変更
要点(TL;DR)
- 用途:配列の各要素をコールバックでテストし、trueを返した要素だけを残す
- 最低限:
$result = array_filter($array, fn($v) => $v > 0); - コールバック省略時は「空とみなされる値」(
false/0/''/null/'0'/ 空配列)を除去する簡易フィルタになる - 罠:
- 元のキーが保持されるため連番に穴が空く(再連番は
array_values()) - デフォルトはコールバックに値のみ渡る。キーも使うには
$modeの指定が必要 - コールバック省略時は文字列
'0'も除去される(strlen判定などとは挙動が異なる)
- 元のキーが保持されるため連番に穴が空く(再連番は
概要
array_filter() は配列の各要素をコールバック関数でテストし、true を返した要素だけを新しい配列として返す関数です。コールバックを省略すると「空とみなされる値」を取り除く簡易フィルタとして動作します。フォーム入力から空値を除く、条件に合う要素だけを抜き出す、null を含む配列をクレンジングするといった場面でよく使います。
構文 / シグネチャ
array array_filter(array $array, ?callable $callback = null, int $mode = 0)
$mode に指定できる値
0(既定):コールバックに値のみを渡すARRAY_FILTER_USE_KEY:コールバックにキーのみを渡すARRAY_FILTER_USE_BOTH:コールバックに値, キーの順で渡す
引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$array | array | はい | — | フィルタ対象の配列 |
$callback | ?callable | いいえ | null | 各要素をテストするコールバック。省略時は空とみなされる値を除去 |
$mode | int | いいえ | 0 | コールバックに渡す引数を指定するフラグ |
戻り値:array(条件を満たした要素のみ。元のキーを保持)
例外/副作用:コールバック内で例外を投げればそのまま呼び出し元に伝播する。PHP 8.0 以降、コールバックが参照渡しパラメータを期待している場合は E_WARNING が発生する。元の配列自体は変更しない(非破壊)。
使用例
最小例:条件に合う要素だけ抽出
<?php
$numbers = [1, -2, 3, -4, 5, 0];
$positive = array_filter($numbers, fn($n) => $n > 0);
print_r($positive);
// [0 => 1, 2 => 3, 4 => 5] ※キーは元のまま(1,3,5番目は除外)
// 連番に振り直したい場合
print_r(array_values($positive));
// [1, 3, 5]
コールバック省略:空とみなされる値をまとめて除去
<?php
$values = ['a', '', 0, null, 'b', false, '0', 'c'];
$clean = array_filter($values);
print_r(array_values($clean));
// ['a', 'b', 'c'] ※ '' / 0 / null / false / '0' はすべて除去される
実務例:フォーム入力のクレンジング(キーも条件に使う)
<?php
$request = [
'name' => 'Taro',
'email' => '',
'age' => 0,
'note' => null,
'_token' => 'abc123',
];
// 空文字/nullを除去しつつ、アンダースコア始まりのキー(内部用)も除外
$filtered = array_filter(
$request,
static fn($value, $key) => $value !== '' && $value !== null && !str_starts_with($key, '_'),
ARRAY_FILTER_USE_BOTH
);
print_r($filtered);
// ['name' => 'Taro', 'age' => 0] ※値0の 'age' は条件に一致しないので残る
応用例:array_map と組み合わせて有効なメールだけ取り出す
<?php
$emails = ['a@example.com', 'not-an-email', 'b@example.com', ''];
$validEmails = array_values(array_filter(
$emails,
fn($email) => filter_var($email, FILTER_VALIDATE_EMAIL) !== false
));
print_r($validEmails);
// ['a@example.com', 'b@example.com']
よくある落とし穴・注意
- キーが保持される:フィルタ後も元のキーのまま。連番前提の
foreachやjson_encodeで意図せず連想配列({})になることがある。再連番したいときはarray_values()を挟む。 - 省略時の「空」判定が広い:コールバックなしだと文字列
'0'も除去される。数値の0だけ除きたい・文字列の”0″は残したいといった場合は明示的なコールバックを書く。 - $mode の渡し忘れ:キーで判定したいのに
$modeを省略すると、コールバックには値しか渡らずキーを参照できない。 - ARRAY_FILTER_USE_BOTH の引数順:
function($value, $key)の順で渡る。キー→値の順だと誤解して逆に書いてしまうミスが多い。 - 非破壊:
array_filter()は元の配列を変更しない。変数への再代入を忘れると呼び出し結果が反映されない。
代替・関連APIとの比較
array_map():要素を変換する(1:1で件数は変わらない)。要素を絞り込みたいならarray_filter、値を作り変えたいならarray_map。両方必要なら組み合わせる。array_walk():配列を参照渡しで書き換える副作用系の関数。要素を間引く用途には向かない。- Laravel
Collection::filter():メソッドチェーンで書ける版。Laravelアプリでコレクションを扱っているならCollection::filter()の方が他の操作と繋げやすい(filter — コレクション要素を条件で抽出するを参照)。 - Laravel
Arr::where():array_filterと同様にキー・値の両方で判定できるヘルパー。生配列のままLaravelのユーティリティだけ使いたい場合の選択肢。
選定基準:
- 生配列を条件で絞り込みたい →
array_filter() - 絞り込みつつ値も変換したい →
array_filter()+array_map() - 元配列を直接書き換えたい →
array_walk() - Laravelのコレクションチェーンの中で使いたい →
Collection::filter()
テスト例(Pest)
<?php
// tests/ArrayFilterFunctionTest.php
it('filters values with a callback', function () {
$result = array_filter([1, -2, 3, -4], fn($n) => $n > 0);
expect($result)->toBe([0 => 1, 2 => 3]);
});
it('removes falsy values without a callback', function () {
$result = array_filter(['a', '', 0, null, 'b']);
expect(array_values($result))->toBe(['a', 'b']);
});
it('passes value and key with ARRAY_FILTER_USE_BOTH', function () {
$result = array_filter(
['name' => 'Taro', '_token' => 'x'],
fn($value, $key) => !str_starts_with($key, '_'),
ARRAY_FILTER_USE_BOTH
);
expect($result)->toBe(['name' => 'Taro']);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
array_filter(): Argument #1 ($array) must be of type array, string given | 対象が配列でない(null や文字列を渡している) | 渡す前に is_array() で検証、または json_decode($json, true) ?? [] のようにフォールバックを用意 |
フィルタ後を json_encode すると配列でなくオブジェクト({})になる | キーが保持されて連番に穴が空いている | array_values() で再連番してから json_encode |
ARRAY_FILTER_USE_BOTH でキー判定が効かない | コールバックの引数順を「キー, 値」と誤解している | 公式仕様どおり function($value, $key) の順で定義する |
数値の 0 だけ残したいのに消えてしまう | コールバックを省略しているため空判定の対象になっている | 明示的なコールバック(例:fn($v) => $v !== null && $v !== '')を指定する |
参考リンク
- PHP 公式マニュアル:array_filter — 配列を条件でフィルタリング
https://www.php.net/manual/function.array-filter.php - PHP 公式マニュアル:array_map
https://www.php.net/manual/function.array-map.php - PHP 公式マニュアル:array_walk
https://www.php.net/manual/function.array-walk.php - PHP 公式マニュアル:filter_var
https://www.php.net/manual/function.filter-var.php - 本サイト内:filter — コレクション要素を条件で抽出する(Laravel Collection)
https://laravelwren.com/2025/09/03/filter/ - 本サイト内:PHPのexplode関数 — 文字列を区切り文字で配列に分割する
https://laravelwren.com/2025/08/30/explode/

コメント