楽に検証!値をチェックしてくれるfilter関数

今回はバリデート関数をご紹介します。
いままではフォームの値をチェックするときってだいたいpreg_match関数などでチェックしていたのですが検証専用の関数がありました。
filter関数です。pregでチェックしなくても検証してくれるので楽です。

emailとかの精度になるとどこまで許容するかが問題になるのですが、携帯アドレスのようにアカウントにドットが複数つくとエラーになります。
各フィルターは実際に試したほうがよさそうですね。どれをスルーしてどれを止めるか。デモページで確認してみてください。


スポンサーリンク

filter_var関数

バリデート関係や除去関係の関数が含まれています。それぞれの関数を見ていきましょう。下記はマニュアルに例を付け足したものです。

true/falseチェック

filter_var(チェックしたい値, FILTER_VALIDATE_BOOLEAN, オプション)

1
2
3
4
5
$bool = 0;
$value = filter_var($bool, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
var_dump($value);
 
=> boolean false

標準では”1″、”true”、”on” および “yes” の場合に TRUE、それ以外の場合にFALSEを返します。
オプションのFILTER_NULL_ON_FAILUREが設定されている場合は、FALSが返されるのは “0”、”false”、”off”、”no” および “” の場合のみとなります。
それ以外の値についてはNULLを返します。例ではオプション付きです。

IPアドレスチェック

filter_var(チェックしたいIP, FILTER_VALIDATE_IP, オプション)

1
2
3
4
5
$ip = '127.0.0.1';
$value = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
var_dump($value);
 
=> string '127.0.0.1' (length=9)

値がIPアドレスであるかどうかを検証します。trueの場合IPを出力します。falseはfalseを出力します。
オプションでIPv4あるいはIPv6のみの指定、 プライベートアドレスや予約済みアドレスではないことの指定もできます。

・FILTER_FLAG_IPV4
IPv4形式のIPアドレスを許可します。

・FILTER_FLAG_IPV6
IPv6 形式のIPアドレスを許可します。

・FILTER_FLAG_NO_PRIV_RANGE
IPv4プライベート領域 10.0.0.0/8, 172.16.0.0/12 および 192.168.0.0/16を許可しません。FD あるいは FC ではじまる IPv6アドレスを許可しません。

・FILTER_FLAG_NO_RES_RANGE
予約済みのIPv4範囲 0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24 および 224.0.0.0/4.を許可しません。このフラグはIPv6アドレスには適用されません。

URL判定

filter_var(チェックしたい値, FILTER_VALIDATE_URL, オプション)

1
2
3
4
$url = 'https://www.php-fan.org/';
$value = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED);
 
=> string 'https://www.php-fan.org/' (length=23)

URLが正しいかどうかの判定します。

・FILTER_FLAG_PATH_REQUIRED
URLで、パス部分を必須とします。このオプションをつけるとhttp://sample.comだとダメです。最後にスラッシュ’/’がないので。

・FILTER_FLAG_QUERY_REQUIRED
URLで、クエリ文字列を必須とします。getで取得できる状態であるかどうかですね。http://www.sample.com/test?sample=okの用な感じですね。

1
2
3
4
5
$url = 'وhttps://www.php-fan.org/فعفثز';
$value = filter_var($url, FILTER_SANITIZE_URL));
var_dump($value);
 
=> string 'https://www.php-fan.org/' (length=23)

・FILTER_SANITIZE_URL
英字、数字および $-_.+!*'(),{}|\\^~[]`<>#%”;/?:@&= 以外のすべての文字を取り除きます。英語じゃない場合(ロシア語、日本語、フランス語など)だと取り除くようですね。

E-mail判定

filter_var(チェックしたいemail, FILTER_VALIDATE_EMAIL)

email形式の厳密な定義は複雑です。RFC5322として定義されているので確認しておきましょう。よく使われているパターンが以下の通り。厳密の言うと簡易的な扱いになります。

1
2
3
4
$pattern = "/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/"
if (preg_match($pattern, $email) {
  echo 'ok';
}

filter_varの関数を使った場合は以下の通りです。

1
2
3
4
5
$email = 'test@sample.com';
$value = filter_var($email, FILTER_VALIDATE_EMAIL);
var_dump($value);
 
=> string 'test@sample.com' (length=15)

値がe-mail形式であるかどうかを検証します。falseならfalse、trueならアドレスを出力します。

一般的にはこんな感じで使います。

1
2
3
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
 echo "emailアドレスの形式ではありません";
}
1
2
3
4
5
$email = '(test@sample.com)';
$value = filter_var($email, FILTER_SANITIZE_EMAIL);
var_dump($value);
 
=> string 'test@sample.com' (length=15)

FILTER_SANITIZE_EMAIL
英字、数字および !#$%&’*+-/=?^_`{|}~@.[] 以外のすべての文字を取り除きます。

数値検証

浮動小数点型
filter_var(チェックしたい数値, FILTER_VALIDATE_FLOAT, オプション)

1
2
3
4
5
$float = '3,250';
$value = filter_var($float, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND);
var_dump($value);
 
=> float 3250

値が float(浮動小数点型) であるかどうかを検証します。

・FILTER_FLAG_ALLOW_THOUSAND
カンマ (,) を数値の桁区切り文字として許可します。

1
2
3
4
5
$float = '12.3"584"';
$value = filter_var($float, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump($value);
 
=> string '12.3584' (length=7)

数字、+- および オプションで .,eE 以外のすべての文字を取り除きます。
・FILTER_FLAG_ALLOW_FRACTION
ピリオド (.) を数値の小数点として許可します。

・FILTER_FLAG_ALLOW_THOUSAND
カンマ (,) を数値の桁区切り文字として許可します。

・FILTER_FLAG_ALLOW_SCIENTIFIC
e あるいは E を、 科学記法の数値として許可します。

整数型
filter_var(チェックしたい数値, FILTER_VALIDATE_INT, オプション)

1
2
3
4
5
$int = '012345678';
$value = filter_var($int, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL);
var_dump($value);
 
=> boolean false

値が整数であるかどうか、オプションで指定した範囲内にあるかどうかを検証します。

・FILTER_FLAG_ALLOW_OCTAL
8進数の許可。ゼロ (0) で始まる入力を八進数とみなします。 ゼロの後には 0-7 しか続けることができません。

・FILTER_FLAG_ALLOW_HEX
16進数の許可。0x あるいは 0X で始まる入力を十六進数とみなします。 後に続けられる文字は a-fA-F0-9 だけです。

1
2
3
4
5
$int = '12.3"584"';
$value = filter_var($int, FILTER_SANITIZE_NUMBER_INT);
var_dump($value);
 
=> string '123584' (length=6)

数字、プラス記号、マイナス記号以外のすべての文字を取り除きます。

エンコード

URLエンコード
filter_var(チェックしたい値, FILTER_SANITIZE_ENCODED)

1
2
3
4
5
$enc = 'URLエンコードします-end';
$value = filter_var($enc, FILTER_SANITIZE_ENCODED);
var_dump($value);
 
=> string 'URL%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%97%E3%81%BE%E3%81%99-end' (length=79)

・FILTER_FLAG_STRIP_LOW
コードが 32 未満の文字を除去します。

・FILTER_FLAG_STRIP_HIGH
コードが 127 より大きい文字を除去します。

・FILTER_FLAG_ENCODE_LOW
コードが 32 未満のすべての文字をエンコードします。

・FILTER_FLAG_ENCODE_HIGH
コードが 127 より大きいすべての文字をエンコードします。

サニタイズ

filter_var(チェックしたい値, FILTER_SANITIZE_FULL_SPECIAL_CHARS, オプション)

1
2
3
4
5
6
$char = "<script>alert('アラートです!')</script>";
$value = filter_var($char, FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES);
 
var_dump($value);
 
=>string '&#60;script&#62;alert(&#39;アラートです!&#39;)&#60;/script&#62;' (length=71)

htmlspecialchars() に ENT_QUOTES を指定してコールするのと同じです。
クォートのエンコードを無効にするには FILTER_FLAG_NO_ENCODE_QUOTES を設定します。
htmlspecialchars() と同様、このフィルタは default_charset に対応しています。
現在の文字セットで無効な文字となるバイトシーケンスが検出されると文字列全体を拒否し、結果は長さ0の文字列となります。
このフィルタをデフォルトのフィルタとして使う場合は、以下のようにしてデフォルトのフラグを0に設定しましょう。
filter.default = full_special_chars
filter.default_flags = 0

1
2
3
4
5
$char = "<script>alert('アラートです!')</script>";
$value = filter_var($char, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
var_dump($value);
 
=>string 'alert('アラートです!')' (length=30)

タグを取り除きます。オプションで、 特殊文字を取り除いたりエンコードしたりします。

・FILTER_FLAG_ENCODE_AMP
アンパサンド (&) をエンコードします。
FILTER_SANITIZE_STRINGの代わりにFILTER_SANITIZE_STRIPPEDを使っても同じです。

正規表現

正規表現チェックです。pregと同じ感じですね。下記は電話番号の正規表現パターンです。

filter_var(チェックしたい値, FILTER_VALIDATE_REGEXP, array(‘options’ => array(‘regexp’ => チェックパターン)))

1
2
3
4
5
6
$reg = '03-123';
$options = array('options' => array('regexp' => '/^0\d{1,5}-?\d{0,4}-?\d{4}$/'));
$value = filter_var($reg, FILTER_VALIDATE_REGEXP, $options);
var_dump($value);
 
=> boolean false

コールバックフィルター

個人的にはコレが一番使いやすいのかも。
filter_var(コールバック関数の引数, FILTER_CALLBACK, array(‘options’ => コールバック関数名を指定))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function chars_count($str)
{
    $cnt = mb_strlen($str);
    if ($cnt > 10 ) {
        return $str;
    } else {
        return false;
    }
 
}
$callback = "文字列カウント";
$str = filter_var($callback, FILTER_CALLBACK, array('options' => 'chars_count'));
var_dump($str);
 
=> boolean false

オプションで指定した関数でチェックする。optionsの指定した関数(chars_count)で引数が$callbackです。

オプションを配列で取る方法

1
2
3
4
5
6
7
8
9
10
11
12
13
$options = array(
    'options' => array(
        'default' => '値に収まりませんでした。', // フィルタが失敗した場合に返す値
        //その他のオプションをここに書きます
        'min_range' => 0,
        'max_range' => 100,
    ),
    'flags' => FILTER_FLAG_ALLOW_OCTAL,
);
$var = filter_var('200', FILTER_VALIDATE_INT, $options);
var_dump($var);
 
=> string '値に収まりませんでした。' (length=36)

フィルター関数一覧

これで使える関数一覧が出ます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var_dump(filter_list());
 
=>
array
  0 => string 'int' (length=3)
  1 => string 'boolean' (length=7)
  2 => string 'float' (length=5)
  3 => string 'validate_regexp' (length=15)
  4 => string 'validate_url' (length=12)
  5 => string 'validate_email' (length=14)
  6 => string 'validate_ip' (length=11)
  7 => string 'string' (length=6)
  8 => string 'stripped' (length=8)
  9 => string 'encoded' (length=7)
  10 => string 'special_chars' (length=13)
  11 => string 'full_special_chars' (length=18)
  12 => string 'unsafe_raw' (length=10)
  13 => string 'email' (length=5)
  14 => string 'url' (length=3)
  15 => string 'number_int' (length=10)
  16 => string 'number_float' (length=12)
  17 => string 'magic_quotes' (length=12)
  18 => string 'callback' (length=8)

filter_input関数

1
2
3
4
$post = filter_input(INPUT_POST, 'text', FILTER_SANITIZE_SPECIAL_CHARS));
var_dump($post);
 
=> boolean false

指定した名前の変数を外部から受け取り、オプションでそれをフィルタリングする
INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER 、INPUT_ENV

filter_input_array関数

上記の配列パターンです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$args = array(
        'url'   => array(
            'filter' =>  FILTER_VALIDATE_URL, 
            'flags' => FILTER_FLAG_PATH_REQUIRED
            ),
        'email' => FILTER_VALIDATE_EMAIL,
        'tel'   => array(
             'filter' => FILTER_VALIDATE_REGEXP,
             'options' => array('regexp' => '/^0\d{1,5}-?\d{0,4}-?\d{4}$/')
             ),
        'comment' => array(
            'filter' => FILTER_CALLBACK, 
            'options'=> 'count_vale'
            )
        );
        $error = filter_input_array(INPUT_POST, $args);
 
        if (false === $error['url']) {
            $error['url'] = '正しいURLを記入してください';
        } else {
            $error['url'] = '';
        }
        if (false === $error['email']) {
            $error['email'] = '正しいメールアドレスを記入してください';
        } else {
            $error['email'] ='';
        }
        if (false === $error['tel']) {
            $error['tel'] = '正しい電話番号を記入してください';
        } else {
            $error['tel'] = '';
        }
        if (false === $error['comment']) {
            $error['comment'] = '10文字以上1000文字以内で記入してください。';
        } else {
            $error['comment'] = '';
        }

デモサイト

Pocket
LINEで送る

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です