Skip to content

Instantly share code, notes, and snippets.

@yano3nora
Created July 1, 2017 06:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yano3nora/9205f275a02c067038be7ff4b3785c33 to your computer and use it in GitHub Desktop.
Save yano3nora/9205f275a02c067038be7ff4b3785c33 to your computer and use it in GitHub Desktop.
[php: Data-Type Validation] attention on old contents. #php

What is?

phpのような「動的型付け言語」はデータ型の検査が適当になりがち。また、phpはgetやpostで渡された値をそのまま変数として扱えたりするので、便利な反面罠も多い。多くはfatalエラーまではいかないが、できる限りwarningやnoticeエラーを出さないよう丁寧なプログラミングを心がけたい。

phpの特徴も踏まえつ「入力値に対する条件分岐」処理作成時には以下のような値がくることを想定してバリデーションすること。

  • 文字列・数値
  • NULL値
  • 真偽値・配列・オブジェクト
  • 空入力
  • 未定義な値
  • 型違いの値
  • 想定外のGET値
  • 悪質なスクリプト
  • 入力ミス(メアド・URL)
  • スキーム違い(http/https/mailto)

Plactice

比較演算子は == より === を使う

==は型の相互変換を自動で行ってしまう、null と "" が同等となる。下のコードでは文字列の数値変換が起きて true が返る

$bar = "3aaa";
$foo = 3;
if($bar == $foo){ 
    return true;
}else{ 
    return false;
}

出力時エスケープ

htmlspecialcharacters() によるエスケープを出力時に行う。タグだけ取り除くstrip_tagsっていうのも。

function h($str) {
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

isset() / empty()

isset() は未定義 or nullでないかどうかをエラーを出さずに検査する優秀な構文。nullもtrueを返す。 下のコードでは、入力されていないのか、正しく送信されていない(フォームのaction先に直接飛んだ)のか判別できる。

if (!isset($_POST['email'])) {
    $errors[] = 'アドレスが送信されていません';
} elseif ($_POST['email'] === '') {
    $errors[] = 'アドレスが入力されていません';
}

empty() は未定義か、型変換してfalseと同等かどうかを検査する構文。型変換する挙動で 0 や "0" も false になるので利用には注意。DB問い合わせしたのち「未定義か、中身がない」状態を切り分けたいときに !empty() とかで使ったりもする。

is_string() / is_array()

WEBの場合、外部からの入力は「文字列」「配列」の二種類。これについて型検査ができる。

// 文字列検査
if (!isset($_POST['email'])) {
    $errors[] = 'アドレスが送信されていません';
} elseif (!is_string($_POST['email'])) {
    $errors[] = 'アドレスが不正送信されました';
} elseif ($_POST['email'] === '') {
    $errors[] = 'アドレスが入力されていません';
}
// 配列検査
if (!isset($_POST['params']) || !is_array($_POST['params'])) {
    $errors[] = 'パラメータが送信されていません';
} else {
    foreach ($params as $key => $value) {
        if (!is_string($value)) {
            $errors[] = "パラメータ{$key}が不正です";
        }
    }
}

filter_input()

GETやPOSTで受け取る値のインデックスに対して「適切なクエリ・値かどうか」をフィルタリングできる新しめのやつ。キャスト(型指定)での抽出もできる。適切でないときは false が、インデックスが未定義のときはnullが返る。

// 受け取るGETクエリ [ ?a=foo&b[]=bar ]
$a = filter_input(INPUT_GET, 'a'); // "foo"
$b = filter_input(INPUT_GET, 'b'); // false
$c = filter_input(INPUT_GET, 'c'); // null
// キャスト(型指定)あり
$a = (string)filter_input(INPUT_GET, 'a'); // "foo"
$b = (string)filter_input(INPUT_GET, 'b'); // ""
$c = (string)filter_input(INPUT_GET, 'c'); // ""
// POSTの未定義や想定外の型の検出
$email = (string)filter_input(INPUT_POST, 'email');

filter_var()

値の中身について有効な形式かどうかを自作の独自フィルタリングにかけられる関数。使い方はリファレンス参照して。

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "正しいEメールアドレスです";
} else {
    echo "Eメールアドレスの形式が不正です";
}

References

$_POST,$_GETを受け取る処理 : http://qiita.com/mpyw/items/2f9955db1c02eeef43ea

PHPでよくあるバリデーション : http://qiita.com/mpyw/items/346f1789ad0e1b969ebc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment