【PHP8.x】filter_input関数の使い方

作成日: 更新日:

『filter_input関数は、GETやPOSTなどで外部から送信されたデータを取得し、指定されたフィルタを適用して検証(バリデーション)や無害化(サニタイズ)を実行する関数です』 この関数は、$_GET$_POSTといったスーパーグローバル変数から直接データを取得する点でfilter_var関数とは異なります。第1引数でINPUT_GETINPUT_POSTなどの定数を指定し、どの入力ソースからデータを取得するかを決定します。第2引数には取得したい変数名を指定します。第3引数には、適用したいフィルタの種類をFILTER_VALIDATE_EMAIL(メールアドレス形式の検証)やFILTER_SANITIZE_SPECIAL_CHARS(特殊文字の無害化)といった定数で指定します。この関数を利用することで、ユーザーからの入力を受け取る際に、クロスサイトスクリプティング(XSS)などのセキュリティ脆弱性を防ぐための処理を簡潔に記述できます。指定した変数が存在しない場合はnullを、フィルタリングに失敗した場合はfalseを返すため、入力値の有無や妥当性を厳密に判定することが可能です。スーパーグローバル変数を直接使用するよりも安全なデータ取得方法として推奨されています。

基本的な使い方

構文(syntax)

filter_input(int $type, string $variable_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed

引数(parameters)

int $type, string $var_name, int $filter = FILTER_DEFAULT, array|int $options = 0

  • int $type: 取得する入力の種類を指定する整数 (例: INPUT_GET, INPUT_POST)。
  • string $var_name: 取得したい変数名を指定する文字列。
  • int $filter = FILTER_DEFAULT: 入力に適用するフィルターを指定する整数。デフォルトでは、入力の型に基づいて自動的にフィルターが選択されます。
  • array|int $options = 0: フィルターのオプションを指定する配列または整数。

戻り値(return)

mixed

引数で指定されたフィルタリング済みの入力値、またはフィルタリングに失敗した場合は false を返します。入力値が存在しない場合は null が返されます。

サンプルコード

PHP filter_input_arrayで一括検証・無害化する

<?php

/**
 * このスクリプトは、HTMLフォームから送信された複数の値を
 * filter_input_array() を使って一括で検証・無害化(サニタイズ)するサンプルです。
 *
 * フォームを送信すると、フィルタリングされた結果がテキストで表示されます。
 */

// HTTPリクエストがPOSTメソッドの場合にのみ、データ処理を実行します。
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 検証とサニタイズのルールを定義する配列。
    // キーはフォームの<input>要素のname属性に対応します。
    $filter_definitions = [
        'user_name' => [
            'filter' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, // XSS対策: 特殊文字をHTMLエンティティに変換
        ],
        'email' => [
            'filter' => FILTER_VALIDATE_EMAIL, // メールアドレスの形式として有効か検証
        ],
        'age' => [
            'filter' => FILTER_VALIDATE_INT, // 整数であるか検証
            'options' => [
                'min_range' => 18,        // オプション: 18歳以上であるか
                'max_range' => 100,       // オプション: 100歳以下であるか
                'default'   => null,      // 検証失敗時のデフォルト値は null とする
            ],
        ],
        'agreed_terms' => [
            'filter' => FILTER_VALIDATE_BOOLEAN, // "1", "true", "on", "yes" を true に、それ以外を false に変換
            'flags'  => FILTER_NULL_ON_FAILURE, // 検証失敗時(値が存在しない場合など)に false ではなく null を返す
        ],
    ];

    // filter_input_array() を実行し、POSTされたデータを一括処理します。
    $processed_inputs = filter_input_array(INPUT_POST, $filter_definitions);

    // 結果をプレーンテキストとして整形して表示します。
    header('Content-Type: text/plain; charset=utf-8');
    echo "--- filter_input_array() の処理結果 ---\n\n";
    print_r($processed_inputs);
    echo "\n--- 解説 ---\n";
    echo "user_name:    入力値から特殊文字が無害化されました。\n";
    echo "email:        有効なメール形式ならその値が、無効なら false が返されます。\n";
    echo "age:          18~100の有効な整数ならその数値が、無効なら null が返されます。\n";
    echo "agreed_terms: チェックがあれば true、なければ null が返されます (FILTER_NULL_ON_FAILURE 指定のため)。\n";

    // この後のHTMLは表示しないように、ここでスクリプトを終了します。
    exit;
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>filter_input_array サンプルフォーム</title>
    <style>
        body { font-family: sans-serif; line-height: 1.6; padding: 20px; max-width: 600px; margin: auto; }
        .form-group { margin-bottom: 1rem; }
        label { display: block; font-weight: bold; margin-bottom: 0.5rem; }
        input[type="text"], input[type="email"], input[type="number"] { width: 100%; padding: 8px; box-sizing: border-box; }
        button { padding: 10px 20px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>ユーザー情報入力</h1>
    <p>このフォームを送信すると、入力内容が <code>filter_input_array()</code> によって処理されます。</p>
    <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="post">
        <div class="form-group">
            <label for="user_name">名前(危険な入力例)</label>
            <input type="text" id="user_name" name="user_name" value="<script>alert('test');</script>">
        </div>
        <div class="form-group">
            <label for="email">メールアドレス(無効な入力例)</label>
            <input type="email" id="email" name="email" value="invalid-email-address">
        </div>
        <div class="form-group">
            <label for="age">年齢(範囲外の入力例)</label>
            <input type="number" id="age" name="age" value="17">
        </div>
        <div class="form-group">
            <input type="checkbox" id="agreed_terms" name="agreed_terms" value="1" checked>
            <label for="agreed_terms" style="display: inline;">利用規約に同意する</label>
        </div>
        <div class="form-group">
            <button type="submit">送信して結果を確認</button>
        </div>
    </form>
</body>
</html>

filter_input_array()関数は、HTMLフォームなどから一度に送信された複数の外部からの入力値を、まとめて検証(バリデーション)したり、無害化(サニタイズ)したりするための関数です。これにより、安全でないデータがプログラムで使われるのを防ぎ、セキュリティを向上させることができます。

第1引数には、どの種類の入力を対象とするかを指定します。このサンプルコードではINPUT_POSTを指定しており、POSTメソッドで送信されたデータを処理対象としています。他にGETリクエストのデータを対象とするINPUT_GETなどがあります。

第2引数には、各入力値に適用するフィルタリングのルールを定義した配列を渡します。この配列のキーは入力項目名に対応し、値にはフィルタの種類や、数値の範囲といった詳細なオプションを指定します。例えば、FILTER_VALIDATE_EMAILはメールアドレスの形式を検証し、FILTER_SANITIZE_FULL_SPECIAL_CHARSは特殊文字を安全なHTMLエンティティに変換します。

戻り値として、フィルタリング処理後の値が格納された配列が返されます。検証に成功した場合はその値が、ルールに合わず失敗した場合はfalsenullが返るため、安全性が確認されたデータだけをその後の処理で扱うことが可能になります。

filter_input_arrayは、フォームなど外部からの入力を安全に受け取るための重要な関数です。検証に失敗するとfalseや、オプション指定によりnullが返るため、その後の処理ではif ($processed_inputs['email'] === false)のように厳密な比較(===)が必須です。==で比較すると、0や空文字列と区別できずバグの原因になります。FILTER_VALIDATE系は形式が正しいかチェックする目的、FILTER_SANITIZE系は危険な文字を除去・変換する目的で使い分けます。また、フィルタ定義にない入力値は結果に含まれないため、受け取りたい値はすべて定義してください。

PHP filter_input で外部入力を安全に処理する

<?php

declare(strict_types=1);

/**
 * filter_input() を使って外部からのGETリクエストを安全に処理するサンプルです。
 *
 * このファイルをWebサーバーに配置し、ブラウザから以下のURLにアクセスして動作を確認してください。
 * (ファイル名が sample.php の場合)
 *
 * ■ 正常な値の例:
 * http://localhost/sample.php?name=Taro%20Yamada&email=taro@example.com
 *
 * ■ 不正な値や無害化が必要な値の例:
 * http://localhost/sample.php?name=<script>alert('XSS')</script>&email=invalid-email
 *
 * ■ パラメータが不足している例:
 * http://localhost/sample.php?name=Taro%20Yamada
 */

// GETリクエストから 'name' パラメータを取得します。
// FILTER_SANITIZE_SPECIAL_CHARS は、HTMLとして特別な意味を持つ文字を無害化(サニタイズ)します。
// パラメータが存在しない場合は null が返ります。
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_SPECIAL_CHARS);

// GETリクエストから 'email' パラメータを取得します。
// FILTER_VALIDATE_EMAIL は、値がメールアドレスとして正しい形式か検証(バリデーション)します。
// 形式が正しくない場合は false が、パラメータが存在しない場合は null が返ります。
$email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL);


// 結果をプレーンテキストとして表示します。
header('Content-Type: text/plain; charset=utf-8');

echo "--- filter_input() の実行結果 ---\n\n";

// 名前の処理結果の表示
echo "[name パラメータの処理]\n";
if ($name === null) {
    echo "結果: name パラメータが指定されていません。\n";
} else {
    // サニタイズされた値が表示されます。
    echo "サニタイズ後の値: " . $name . "\n";
}

echo "\n---\n\n";

// メールアドレスの処理結果の表示
echo "[email パラメータの処理]\n";
if ($email === null) {
    echo "結果: email パラメータが指定されていません。\n";
} elseif ($email === false) {
    // バリデーションに失敗した場合
    echo "結果: 入力値は有効なメールアドレスの形式ではありません。\n";
} else {
    // バリデーションに成功した場合
    echo "検証済みのメールアドレス: " . $email . "\n";
}

PHPのfilter_input()関数は、GETやPOSTリクエストなど、外部から送信されたデータを安全に取得するために使用されます。この関数を使うことで、意図しない値や不正なデータがプログラムに与える影響を防ぐことができます。

第1引数にはデータの取得元(INPUT_GETなど)を、第2引数には取得したい変数名を指定します。第3引数には、データに適用するフィルタの種類を指定します。例えば、サンプルコードで使われているFILTER_SANITIZE_SPECIAL_CHARSは、HTMLタグのような特殊文字を無害な文字列に変換(サニタイズ)します。一方、FILTER_VALIDATE_EMAILは、値がメールアドレスとして正しい形式か検証(バリデーション)します。

この関数の戻り値は、処理内容によって変わる点に注意が必要です。フィルタリングに成功すると処理後のデータが返されます。バリデーションに失敗した場合はfalseが、指定した変数が存在しない場合はnullが返されます。サンプルコードのように、戻り値を厳密に判定することで、それぞれの状況に応じた適切な処理を実装できます。このようにfilter_input()は、外部からの入力を安全かつ簡単に扱うための重要な関数です。

filter_input関数は、ユーザーからの入力といった外部の値を安全に扱うために使います。値を無害化する「サニタイズ」と、形式が正しいか検証する「バリデーション」の2つの役割があります。最も注意すべき点は戻り値の判定です。パラメータが存在しない場合は null、バリデーションに失敗した場合は false が返ります。これらを正しく区別するため、サンプルコードのように === を用いて型まで含めた厳密な比較をすることが非常に重要です。$_GET$_POST などのスーパーグローバル変数を直接参照するよりも、この関数を使うことで意図しない値の混入を防ぎ、より安全な処理を実装できます。

【PHP8.x】filter_input関数の使い方 | いっしー@Webエンジニア