【PHP8.x】filter_input()関数の使い方
filter_input関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『filter_input関数は、GETやPOSTなどで外部から送信されたデータを取得し、指定されたフィルタを適用して検証(バリデーション)や無害化(サニタイズ)を実行する関数です』
この関数は、$_GETや$_POSTといったスーパーグローバル変数から直接データを取得する点でfilter_var関数とは異なります。第1引数でINPUT_GETやINPUT_POSTなどの定数を指定し、どの入力ソースからデータを取得するかを決定します。第2引数には取得したい変数名を指定します。第3引数には、適用したいフィルタの種類をFILTER_VALIDATE_EMAIL(メールアドレス形式の検証)やFILTER_SANITIZE_SPECIAL_CHARS(特殊文字の無害化)といった定数で指定します。この関数を利用することで、ユーザーからの入力を受け取る際に、クロスサイトスクリプティング(XSS)などのセキュリティ脆弱性を防ぐための処理を簡潔に記述できます。指定した変数が存在しない場合はnullを、フィルタリングに失敗した場合はfalseを返すため、入力値の有無や妥当性を厳密に判定することが可能です。スーパーグローバル変数を直接使用するよりも安全なデータ取得方法として推奨されています。
構文(syntax)
1filter_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でセキュリティ対策をする
1<?php 2 3/** 4 * ユーザー入力を安全に処理するサンプル関数。 5 * 6 * filter_input関数を使用して、GETリクエストから取得したデータを 7 * バリデーション(検証)およびサニタイズ(無害化)し、 8 * セキュリティ脆弱性(例: SQLインジェクション、XSS)を防ぎます。 9 */ 10function processSecureUserInput(): void 11{ 12 // GETリクエストから'id'パラメータを取得し、整数としてバリデートします。 13 // FILTER_VALIDATE_INT は、値が有効な整数でない場合は false を返します。 14 // -> これにより、期待するデータ型であることを保証し、 15 // 不正な値によるSQLインジェクションなどのリスクを低減します。 16 $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); 17 18 if ($id === false || $id === null) { 19 echo "IDは無効な値、または指定されていません。<br>"; 20 } else { 21 // IDが安全な整数であることを確認できます。 22 echo "安全なID: " . $id . "<br>"; 23 } 24 25 echo "<br>"; 26 27 // GETリクエストから'search'パラメータを取得し、特殊文字をサニタイズします。 28 // FILTER_SANITIZE_SPECIAL_CHARS は、HTMLタグや特殊文字をエスケープします 29 // (例: < を < に変換)。 30 // -> これにより、クロスサイトスクリプティング (XSS) 攻撃を防ぎます。 31 $searchQuery = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS); 32 33 if ($searchQuery === null || $searchQuery === false) { 34 echo "検索クエリは無効な値、または指定されていません。<br>"; 35 } else { 36 // 検索クエリがXSS対策済みの文字列であることを確認できます。 37 echo "安全な検索クエリ: " . $searchQuery . "<br>"; 38 } 39} 40 41// この関数を実行して、ユーザー入力の処理をシミュレートします。 42// このスクリプトをウェブサーバーに配置し、ブラウザで以下のURLを試して動作を確認できます: 43// 1. 通常のアクセス: http://localhost/your_script.php?id=123&search=hello 44// 2. 悪意のある入力例: http://localhost/your_script.php?id=abc&search=<script>alert('XSS');</script> 45// 3. パラメータなしの場合: http://localhost/your_script.php 46processSecureUserInput(); 47
PHPのfilter_input関数は、外部からのユーザー入力(GET、POST、クッキーなど)を安全に取得するための重要な機能です。この関数を介することで、データの検証(バリデーション)や無害化(サニタイズ)を簡単に行い、SQLインジェクションやクロスサイトスクリプティング(XSS)といったセキュリティ脆弱性からアプリケーションを保護します。
第一引数$typeには、INPUT_GETやINPUT_POSTなどで入力元を指定します。第二引数$var_nameは、取得したい変数の名前を指定します。そして第三引数$filterでは、FILTER_VALIDATE_INTで整数を検証したり、FILTER_SANITIZE_SPECIAL_CHARSで特殊文字を無害化したりと、適用するフィルターを選べます。戻り値はフィルター処理後の値ですが、検証に失敗した場合はfalse、指定の入力が存在しない場合はnullを返します。これにより、入力が意図した形式であるかを確認できます。
サンプルコードでは、GETリクエストの'id'パラメータをFILTER_VALIDATE_INTで整数として検証しています。これにより、数値以外の不正な値が混入するのを防ぎ、SQLインジェクションのリスクを軽減します。また、'search'パラメータはFILTER_SANITIZE_SPECIAL_CHARSで特殊文字を無害化しています。これは、悪意のあるスクリプトが埋め込まれるクロスサイトスクリプティング(XSS)攻撃からアプリケーションを保護するために重要です。このように、filter_input関数を適切に利用することで、セキュリティを考慮した堅牢なアプリケーション開発が可能になります。
filter_input関数は、ユーザーからの入力が安全であることを確認する上で非常に重要です。この関数の戻り値は、入力が存在しない場合はnull、バリデーションに失敗した場合はfalseとなるため、常に両方を厳密にチェックする必要があります。
FILTER_VALIDATE_INTのように入力を特定の型に強制するフィルタは、SQLインジェクションなどのデータ型に起因する脆弱性を防ぎます。また、FILTER_SANITIZE_SPECIAL_CHARSはHTML特殊文字を安全な形式に変換し、クロスサイトスクリプティング(XSS)攻撃から保護します。
これらのフィルタを適切に使い分け、全てのユーザー入力を無条件に信用せず、必ず安全な形に処理することが、堅牢なシステムを構築するための基本的な注意点です。常にセキュリティを意識した入力処理を心がけましょう。
PHP filter_input_arrayで一括検証・無害化する
1<?php 2 3/** 4 * このスクリプトは、HTMLフォームから送信された複数の値を 5 * filter_input_array() を使って一括で検証・無害化(サニタイズ)するサンプルです。 6 * 7 * フォームを送信すると、フィルタリングされた結果がテキストで表示されます。 8 */ 9 10// HTTPリクエストがPOSTメソッドの場合にのみ、データ処理を実行します。 11if ($_SERVER['REQUEST_METHOD'] === 'POST') { 12 // 検証とサニタイズのルールを定義する配列。 13 // キーはフォームの<input>要素のname属性に対応します。 14 $filter_definitions = [ 15 'user_name' => [ 16 'filter' => FILTER_SANITIZE_FULL_SPECIAL_CHARS, // XSS対策: 特殊文字をHTMLエンティティに変換 17 ], 18 'email' => [ 19 'filter' => FILTER_VALIDATE_EMAIL, // メールアドレスの形式として有効か検証 20 ], 21 'age' => [ 22 'filter' => FILTER_VALIDATE_INT, // 整数であるか検証 23 'options' => [ 24 'min_range' => 18, // オプション: 18歳以上であるか 25 'max_range' => 100, // オプション: 100歳以下であるか 26 'default' => null, // 検証失敗時のデフォルト値は null とする 27 ], 28 ], 29 'agreed_terms' => [ 30 'filter' => FILTER_VALIDATE_BOOLEAN, // "1", "true", "on", "yes" を true に、それ以外を false に変換 31 'flags' => FILTER_NULL_ON_FAILURE, // 検証失敗時(値が存在しない場合など)に false ではなく null を返す 32 ], 33 ]; 34 35 // filter_input_array() を実行し、POSTされたデータを一括処理します。 36 $processed_inputs = filter_input_array(INPUT_POST, $filter_definitions); 37 38 // 結果をプレーンテキストとして整形して表示します。 39 header('Content-Type: text/plain; charset=utf-8'); 40 echo "--- filter_input_array() の処理結果 ---\n\n"; 41 print_r($processed_inputs); 42 echo "\n--- 解説 ---\n"; 43 echo "user_name: 入力値から特殊文字が無害化されました。\n"; 44 echo "email: 有効なメール形式ならその値が、無効なら false が返されます。\n"; 45 echo "age: 18~100の有効な整数ならその数値が、無効なら null が返されます。\n"; 46 echo "agreed_terms: チェックがあれば true、なければ null が返されます (FILTER_NULL_ON_FAILURE 指定のため)。\n"; 47 48 // この後のHTMLは表示しないように、ここでスクリプトを終了します。 49 exit; 50} 51 52?> 53<!DOCTYPE html> 54<html lang="ja"> 55<head> 56 <meta charset="UTF-8"> 57 <title>filter_input_array サンプルフォーム</title> 58 <style> 59 body { font-family: sans-serif; line-height: 1.6; padding: 20px; max-width: 600px; margin: auto; } 60 .form-group { margin-bottom: 1rem; } 61 label { display: block; font-weight: bold; margin-bottom: 0.5rem; } 62 input[type="text"], input[type="email"], input[type="number"] { width: 100%; padding: 8px; box-sizing: border-box; } 63 button { padding: 10px 20px; cursor: pointer; } 64 </style> 65</head> 66<body> 67 <h1>ユーザー情報入力</h1> 68 <p>このフォームを送信すると、入力内容が <code>filter_input_array()</code> によって処理されます。</p> 69 <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>" method="post"> 70 <div class="form-group"> 71 <label for="user_name">名前(危険な入力例)</label> 72 <input type="text" id="user_name" name="user_name" value="<script>alert('test');</script>"> 73 </div> 74 <div class="form-group"> 75 <label for="email">メールアドレス(無効な入力例)</label> 76 <input type="email" id="email" name="email" value="invalid-email-address"> 77 </div> 78 <div class="form-group"> 79 <label for="age">年齢(範囲外の入力例)</label> 80 <input type="number" id="age" name="age" value="17"> 81 </div> 82 <div class="form-group"> 83 <input type="checkbox" id="agreed_terms" name="agreed_terms" value="1" checked> 84 <label for="agreed_terms" style="display: inline;">利用規約に同意する</label> 85 </div> 86 <div class="form-group"> 87 <button type="submit">送信して結果を確認</button> 88 </div> 89 </form> 90</body> 91</html>
filter_input_array()関数は、HTMLフォームなどから一度に送信された複数の外部からの入力値を、まとめて検証(バリデーション)したり、無害化(サニタイズ)したりするための関数です。これにより、安全でないデータがプログラムで使われるのを防ぎ、セキュリティを向上させることができます。
第1引数には、どの種類の入力を対象とするかを指定します。このサンプルコードではINPUT_POSTを指定しており、POSTメソッドで送信されたデータを処理対象としています。他にGETリクエストのデータを対象とするINPUT_GETなどがあります。
第2引数には、各入力値に適用するフィルタリングのルールを定義した配列を渡します。この配列のキーは入力項目名に対応し、値にはフィルタの種類や、数値の範囲といった詳細なオプションを指定します。例えば、FILTER_VALIDATE_EMAILはメールアドレスの形式を検証し、FILTER_SANITIZE_FULL_SPECIAL_CHARSは特殊文字を安全なHTMLエンティティに変換します。
戻り値として、フィルタリング処理後の値が格納された配列が返されます。検証に成功した場合はその値が、ルールに合わず失敗した場合はfalseやnullが返るため、安全性が確認されたデータだけをその後の処理で扱うことが可能になります。
filter_input_arrayは、フォームなど外部からの入力を安全に受け取るための重要な関数です。検証に失敗するとfalseや、オプション指定によりnullが返るため、その後の処理ではif ($processed_inputs['email'] === false)のように厳密な比較(===)が必須です。==で比較すると、0や空文字列と区別できずバグの原因になります。FILTER_VALIDATE系は形式が正しいかチェックする目的、FILTER_SANITIZE系は危険な文字を除去・変換する目的で使い分けます。また、フィルタ定義にない入力値は結果に含まれないため、受け取りたい値はすべて定義してください。
PHP GETリクエストの安全な取得とフィルタリング
1<?php 2 3/** 4 * HTTP GETリクエストからパラメータを安全に取得し、表示する関数。 5 * 6 * この関数は、filter_input() を使用してGETリクエストのデータを受け取り、 7 * フィルタリング(検証やサニタイズ)を適用して、安全な値を取得する方法を示します。 8 * 9 * 動作を確認するには、スクリプトにURLパラメータを追加してアクセスしてください。 10 * 例: http://localhost/your_script.php?username=Alice&age=25&email=alice@example.com 11 * 12 * @return void 13 */ 14function processFilteredGetRequest(): void 15{ 16 echo "GETリクエストパラメータの取得とフィルタリングの例\n"; 17 echo "URLに '?username=Alice&age=25&email=alice@example.com' のようにパラメータを追加して動作を確認してください。\n"; 18 echo "--------------------------------------------------\n"; 19 20 // 'username' パラメータを文字列として取得(サニタイズ) 21 // 注意: FILTER_SANITIZE_STRING は PHP 8.1 で非推奨になりました。 22 // 現代のウェブアプリケーションでは、このフィルタの代わりに、 23 // HTML出力時にはhtmlspecialchars()、データベース挿入時にはプリペアドステートメントなど、 24 // 出力コンテキストに応じた適切なエスケープ処理が推奨されます。 25 $username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_STRING); 26 27 if ($username === false || $username === null) { 28 echo "ユーザー名: パラメータ 'username' が無効か、存在しません。\n"; 29 } else { 30 // HTMLに出力する際は、XSS対策のためにhtmlspecialchars()を使用することが推奨されます。 31 echo "ユーザー名: " . htmlspecialchars($username, ENT_QUOTES, 'UTF-8') . "\n"; 32 } 33 34 // 'age' パラメータを整数として取得(バリデーション) 35 // 0から120の範囲で検証するオプションも適用 36 $age = filter_input( 37 INPUT_GET, 38 'age', 39 FILTER_VALIDATE_INT, 40 ['options' => ['min_range' => 0, 'max_range' => 120]] 41 ); 42 43 if ($age === false || $age === null) { 44 echo "年齢: パラメータ 'age' が無効か、範囲外です。\n"; 45 } else { 46 echo "年齢: " . $age . "\n"; 47 } 48 49 // 'email' パラメータをメールアドレスとして検証 50 $email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL); 51 52 if ($email === false || $email === null) { 53 echo "メールアドレス: パラメータ 'email' が無効か、存在しません。\n"; 54 } else { 55 echo "メールアドレス: " . htmlspecialchars($email, ENT_QUOTES, 'UTF-8') . "\n"; 56 } 57 58 // 存在しないパラメータの例 59 $city = filter_input(INPUT_GET, 'city', FILTER_SANITIZE_STRING); // 仮にフィルタは適用 60 if ($city === false || $city === null) { 61 echo "都市: パラメータ 'city' が存在しません。\n"; 62 } else { 63 echo "都市: " . htmlspecialchars($city, ENT_QUOTES, 'UTF-8') . "\n"; 64 } 65} 66 67// 関数を実行してGETリクエスト処理を開始 68processFilteredGetRequest(); 69 70?>
filter_input関数は、GETやPOSTなどの外部からの入力データを安全に取得し、検証やサニタイズ(無害化)を行うためのPHPの重要な関数です。Webアプリケーションでは、ユーザーからの入力値をそのまま使用するとセキュリティ上の脆弱性につながる可能性があるため、この関数による適切なフィルタリングが不可欠となります。
第一引数$typeには、どの種類の入力データを受け取るか指定します。例えば、GETリクエストの場合はINPUT_GETを使用します。第二引数$var_nameには、取得したいパラメータの名前を文字列で指定します。第三引数$filterは適用するフィルタの種類を示し、例えば文字列として無害化するFILTER_SANITIZE_STRINGや、整数として妥当性を検証するFILTER_VALIDATE_INTなどがあります。オプションとして第四引数$optionsを使用すると、数値の範囲指定といったより詳細な検証ルールを設定できます。
戻り値はmixed型で、フィルタリングに成功した場合はその値が返されますが、パラメータが存在しない場合やフィルタリングに失敗して無効と判断された場合はnullまたはfalseが返されます。そのため、必ず戻り値をチェックして処理を進める必要があります。
サンプルコードでは、usernameを文字列としてサニタイズし、ageを0から120の範囲の整数として検証、emailをメールアドレスとして検証する例を示しています。特にusernameのようにウェブページに出力する可能性がある値は、filter_inputでの基本的なサニタイズに加えて、クロスサイトスクリプティング(XSS)対策のためにhtmlspecialchars()関数などで適切にエスケープ処理を行うことが推奨されます。この関数を使いこなすことで、より安全で信頼性の高いシステムを構築できます。
filter_input関数は、GETリクエストなどの外部からの入力を安全に取得し、検証やサニタイズを行う際に利用します。パラメータが存在しない、またはフィルタリングの結果が無効だった場合、falseまたはnullを返すため、必ずこれらの戻り値をチェックして適切にエラー処理を行ってください。
特に、PHP 8.1で非推奨となったFILTER_SANITIZE_STRINGの使用は避け、HTML出力時にはXSS対策としてhtmlspecialchars()を適用するなど、用途に応じた適切なエスケープ処理を個別に行うことが非常に重要です。FILTER_VALIDATE_INTのように、値の型や範囲を厳密に検証できるフィルターを積極的に活用し、不正な入力からシステムを保護することを心がけましょう。
PHP filter_input で外部入力を安全に処理する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * filter_input() を使って外部からのGETリクエストを安全に処理するサンプルです。 7 * 8 * このファイルをWebサーバーに配置し、ブラウザから以下のURLにアクセスして動作を確認してください。 9 * (ファイル名が sample.php の場合) 10 * 11 * ■ 正常な値の例: 12 * http://localhost/sample.php?name=Taro%20Yamada&email=taro@example.com 13 * 14 * ■ 不正な値や無害化が必要な値の例: 15 * http://localhost/sample.php?name=<script>alert('XSS')</script>&email=invalid-email 16 * 17 * ■ パラメータが不足している例: 18 * http://localhost/sample.php?name=Taro%20Yamada 19 */ 20 21// GETリクエストから 'name' パラメータを取得します。 22// FILTER_SANITIZE_SPECIAL_CHARS は、HTMLとして特別な意味を持つ文字を無害化(サニタイズ)します。 23// パラメータが存在しない場合は null が返ります。 24$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_SPECIAL_CHARS); 25 26// GETリクエストから 'email' パラメータを取得します。 27// FILTER_VALIDATE_EMAIL は、値がメールアドレスとして正しい形式か検証(バリデーション)します。 28// 形式が正しくない場合は false が、パラメータが存在しない場合は null が返ります。 29$email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL); 30 31 32// 結果をプレーンテキストとして表示します。 33header('Content-Type: text/plain; charset=utf-8'); 34 35echo "--- filter_input() の実行結果 ---\n\n"; 36 37// 名前の処理結果の表示 38echo "[name パラメータの処理]\n"; 39if ($name === null) { 40 echo "結果: name パラメータが指定されていません。\n"; 41} else { 42 // サニタイズされた値が表示されます。 43 echo "サニタイズ後の値: " . $name . "\n"; 44} 45 46echo "\n---\n\n"; 47 48// メールアドレスの処理結果の表示 49echo "[email パラメータの処理]\n"; 50if ($email === null) { 51 echo "結果: email パラメータが指定されていません。\n"; 52} elseif ($email === false) { 53 // バリデーションに失敗した場合 54 echo "結果: 入力値は有効なメールアドレスの形式ではありません。\n"; 55} else { 56 // バリデーションに成功した場合 57 echo "検証済みのメールアドレス: " . $email . "\n"; 58} 59
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 などのスーパーグローバル変数を直接参照するよりも、この関数を使うことで意図しない値の混入を防ぎ、より安全な処理を実装できます。