PHP フィルタ


PHP フィルタは、ユーザー入力などの安全でないソースからのデータを検証およびフィルタリングするために使用されます。


PHP フィルタとは?

PHP フィルタは、安全でないソースからのデータを検証およびフィルタリングするために使用されます。

ユーザー入力やカスタムデータをテスト、検証、フィルタリングすることは、Web アプリケーションにとって重要な部分です。

PHP のフィルタ拡張機能は、データフィルタリングをより簡単かつ迅速に行えるように設計されています。


なぜフィルタを使うのか?

ほとんどすべての Web アプリケーションは外部からの入力に依存しています。これらのデータは通常、ユーザーや他のアプリケーション(Web サービスなど)から送られます。フィルタを使用することで、アプリケーションが正しい入力タイプを取得できることを保証できます。

外部データは常にフィルタリングする必要があります!

入力フィルタリングは、アプリケーションセキュリティにおいて最も重要な課題の 1 つです。

外部データとは?

  • フォームからの入力データ
  • Cookies
  • Web services data
  • サーバー変数
  • データベースクエリの結果

関数とフィルタ

変数をフィルタリングするには、次のいずれかのフィルタ関数を使用します:

  • filter_var() - 指定したフィルタを使用して単一の変数をフィルタリングします
  • filter_var_array() - 同じまたは異なるフィルタを使用して複数の変数をフィルタリングします
  • filter_input - 入力変数を取得し、それをフィルタリングします
  • filter_input_array - 複数の入力変数を取得し、同じまたは異なるフィルタを使用してそれらをフィルタリングします

次の例では、filter_var() 関数を使用して整数を検証します:

例

<?php $int = 123; if(!filter_var($int, FILTER_VALIDATE_INT)) { echo("有効な整数ではありません"); } else { echo("有効な整数です"); } ?>

上記のコードは、"FILTER_VALIDATE_INT" フィルタを使用して変数をフィルタリングしています。この整数は有効であるため、上記のコードは次のように出力されます:

非整数の変数(たとえば "123abc")を使用しようとすると、"Integer is not valid" と出力されます。

完全な関数とフィルタの一覧については、次のページを参照してください:PHP Filter リファレンスマニュアル。


Validating と Sanitizing

フィルタには 2 種類あります:

Validating フィルタ:

  • ユーザー入力を検証するために使用します
  • 厳密な形式ルール(URL や E-Mail 検証など)
  • 成功した場合は期待される型を返し、失敗した場合は FALSE を返します

Sanitizing フィルタ:

  • 文字列内の指定した文字を許可または禁止するために使用します
  • データ形式のルールはありません
  • 常に文字列を返します

オプションとフラグ

オプションとフラグは、指定したフィルタに追加のフィルタオプションを追加するために使用します。

フィルタが異なると、オプションとフラグも異なります。

次の例では、filter_var() と "min_range" および "max_range" オプションを使用して整数を検証します:

例

<?php $var=300; $int_options = array( "options"=>array ( "min_range"=>0, "max_range"=>256 ) ); if(!filter_var($var, FILTER_VALIDATE_INT, $int_options)) { echo("有効な整数ではありません"); } else { echo("有効な整数です"); } ?>

上記のコードと同様に、オプションは "options" という名前の連想配列に格納する必要があります。フラグを使用する場合は、配列内に置く必要はありません。

整数は "300" で、指定された範囲内にないため、上記のコードの出力は次のようになります:

有効な整数ではありません

完全な関数とフィルタの一覧については、次のページを参照してください:PHP Filter リファレンスマニュアル。各フィルタで利用可能なオプションとフラグを確認できます。


入力の検証

フォームからの入力を検証してみましょう。

最初に行う必要があるのは、探している入力データが存在するかどうかを確認することです。

次に、filter_input() 関数を使用して入力データをフィルタリングします。

次の例では、入力変数 "email" が PHP ページに渡されます:

例

<?php if(!filter_has_var(INPUT_GET, "email")) { echo("email パラメータがありません"); } else { if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)) { echo "有効な E-Mail ではありません"; } else { echo "有効な E-Mail です"; } } ?>

上記の例のテスト結果は次のとおりです:

例の説明

上記の例では、"GET" メソッドで送信された入力変数 (email) があります:

  1. "GET" タイプの "email" 入力変数が存在するかどうかを確認します
  2. 入力変数が存在する場合、それが有効な e-mail アドレスかどうかを確認します

入力のサニタイズ

フォームから送信された URL をサニタイズしてみましょう。

まず、探している入力データが存在するかどうかを確認します。

次に、filter_input() 関数を使用して入力データをサニタイズします。

次の例では、入力変数 "url" が PHP ページに渡されます:

<?php
if(!filter_has_var(INPUT_GET, "url"))
{
    echo("没有 url 参数");
}
else
{
    $url = filter_input(INPUT_GET, 
    "url", FILTER_SANITIZE_URL);
    echo $url;
}
?>

例の説明

上記の例では、"GET" メソッドで送信された入力変数 (url) があります:

  1. "GET" タイプの "url" 入力変数が存在するかどうかを確認します
  2. この入力変数が存在する場合、それをサニタイズし(不正な文字を削除)、$url 変数に格納します

入力変数が "http://www.ruåånoøøob.com/" のような文字列の場合、サニタイズ後の $url 変数は次のようになります:



複数の入力のフィルタリング

フォームは通常、複数の入力フィールドで構成されます。filter_var または filter_input 関数を繰り返し呼び出すことを避けるために、filter_var_array または filter_input_array 関数を使用できます。

この例では、filter_input_array() 関数を使用して 3 つの GET 変数をフィルタリングします。受け取る GET 変数は、名前、年齢、および e-mail アドレスです:

例

<?php $filters = array ( "name" => array ( "filter"=>FILTER_SANITIZE_STRING ), "age" => array ( "filter"=>FILTER_VALIDATE_INT, "options"=>array ( "min_range"=>1, "max_range"=>120 ) ), "email"=> FILTER_VALIDATE_EMAIL ); $result = filter_input_array(INPUT_GET, $filters); if (!$result["age"]) { echo("年齢は 1 から 120 の間でなければなりません。<br>"); } elseif(!$result["email"]) { echo("E-Mail が不正です<br>"); } else { echo("入力は正しい"); } ?>

例の説明

上記の例には、"GET" メソッドで送信された 3 つの入力変数 (name、age、email) があります:

  1. 入力変数の名前と、指定した入力変数に使用するフィルタを含む配列を設定します
  2. filter_input_array() 関数を呼び出します。引数には GET 入力変数と、先ほど設定した配列を含めます
  3. $result 変数内の "age" と "email" 変数に不正な入力がないかどうかを確認します。(不正な入力がある場合、filter_input_array() 関数を使用した後、入力変数は FALSE になります。)

filter_input_array() 関数の 2 番目の引数は、配列または単一のフィルタ ID にすることができます。

この引数が単一のフィルタ ID の場合、指定したフィルタは入力配列内のすべての値をフィルタリングします。

この引数が配列の場合、その配列は次のルールに従う必要があります:

  • 連想配列である必要があり、含まれる入力変数が配列のキーになります(例: "age" 入力変数)
  • この配列の値はフィルタ ID か、フィルタ、フラグ、オプションを指定した配列でなければなりません

Filter Callback の使用

FILTER_CALLBACK フィルタを使用すると、カスタム関数を呼び出してフィルタとして使用できます。これにより、データフィルタリングを完全に制御できます。

独自のカスタム関数を作成することも、既存の PHP 関数を使用することもできます。

使用するフィルタ関数を、指定オプションで規定された方法に従って指定します。連想配列には、"options" という名前を付けます。

次の例では、カスタム関数を使用してすべての「_」を「.」に変換します:

例

<?php function convertSpace($string) { return str_replace("_", ".", $string); } $string = "www_サンプル_com!"; echo filter_var($string, FILTER_CALLBACK, array("options"=>"convertSpace")); ?>

上記のコードの結果は次のようになります:

例の説明

上記の例では、すべての「_」を「.」に変換します:

  1. 「_」を「.」に置き換える関数を作成する
  2. filter_var() 関数を呼び出します。その引数は FILTER_CALLBACK フィルターと、私たちの関数を含む配列です
その他の拡張