PHPでフォーム値などを一括で入力チェックするクラスを作りました

手軽に使える入力値チェッククラスが欲しかったので、（車輪の再発明と言われそうですが）作ってみました。

# 履歴
- 2017.01.25 メソッド名の__をとりました

# 用途

## プログラム前半でのセキュリティ対策
$_REQUESTなどの内容を定義と一緒に渡して、プログラム前半における異常値検出に使えます。
プログラム前半での防御的な使い方では、異常値があったら強制的にプログラムを終了する方法がおすすめです。

## フォーム入力値チェック
フォーム入力値のチェック機構として使うこともできます。この場合、エラー内容をキーから抽出し、画面表示することもできます。

# 動作環境
PHP 5.6.24の環境で動作確認しました。

# コード
```PHP:CheckInput.php
<?php
/**
 * 変数の一括チェック
 *
 * Author:   mhagita http://qiita.com/mhagita
 * License:  http://creativecommons.org/licenses/MIT/ MIT
 */
class CheckInput
{
    public function __construct() {
    }

    /**
     * チェックの実施
     */
    public function check($parameters, $conditions) {
        $errors = array();
        foreach ($conditions as $key => $condition) {
            // 評価する値の抽出
            $value = "";
            if (isset($parameters[$key])) {
                $value = $parameters[$key];
            }

            // チェック条件の初期化
            $max = (isset($condition["max"]) ? $condition["max"] : null);
            $min = (isset($condition["min"]) ? $condition["min"] : null);
            $type = (isset($condition["type"]) ? $condition["type"] : null);
            $disallowWhitespace = (isset($condition["disallowWhitespace"]) ? $condition["disallowWhitespace"] : null);
            $disallowZenkaku = (isset($condition["disallowZenkaku"]) ? $condition["disallowZenkaku"] : null);
            $required = (isset($condition["required"]) ? $condition["required"] : null);

            // 必須チェック
            if (!$this->checkRequired($value, $required)) {
                $errors[$key]["required"] = "必ず入力してください";
                continue;
            }

            // max文字数チェック
            if (!$this->checkMax($value, $max)) {
                $errors[$key]["max"] = "{$max}文字以下で入力してください";
                continue;
            }

            // min文字数チェック
            if (!$this->checkMin($value, $min)) {
                $errors[$key]["min"] = "{$min}文字以上で入力してください";
                continue;
            }

            // 全角文字チェック
            if (!$this->checkZenkaku($value, $disallowZenkaku)) {
                $errors[$key]["disallowZenkaku"] = "全角文字を含めず入力してください";
                continue;
            }

            // 空白文字チェック
            if (!$this->checkWhitespace($value, $disallowWhitespace)) {
                $errors[$key]["disallowWhitespace"] = "スペースを含めず入力してください";
                continue;
            }

            // 形式チェック
            if (!$this->checkType($value, $type)) {
                $errors[$key]["type"] = "正しい形式で入力してください";
                continue;
            }
        }

        if (count($errors) > 0) {
            return $errors;
        } else {
            return false;
        }
    }

    /**
     * 必須チェック
     */
    protected function checkRequired($value, $required) {
        if ($value == "") {
            if ($required) {
                return false;
            }
        }
        return true;
    }

    /**
     * max文字数チェック
     */
    protected function checkMax($value, $max) {
        if ($value == "") return true;
        if ($max) {
            $mb_length = mb_strlen($value, "UTF-8");
            if ($max < $mb_length) {
                return false;
            }
        }
        return true;
    }

    /**
     * min文字数チェック
     */
    protected function checkMin($value, $min) {
        if ($value == "") return true;
        if ($min) {
            $mb_length = mb_strlen($value, "UTF-8");
            if ($min > $mb_length) {
                return false;
            }
        }
        return true;
    }

    /**
     * 全角文字チェック
     */
    protected function checkZenkaku($value, $disallowZenkaku) {
        if ($value == "") return true;
        if ($disallowZenkaku) {
           $mb_length = mb_strlen($value, "UTF-8");
           if ($mb_length != strlen($value)) {
              return false;
           }
        }
        return true;
    }

    /**
     * 空白文字チェック
     */
    protected function checkWhitespace($value, $disallowWhitespace) {
        if ($value == "") return true;
        if ($disallowWhitespace) {
            if (strpos($value, " ") !== false || strpos($value, "　") !== false) {
                return false;
            }
        }
        return true;
    }

    /**
     * 形式チェック
     */
    protected function checkType($value, $type) {
        $error = false;
        switch ($type) {
            // アルファベット
            case "alphabet":
            case "a":
                if (!preg_match('/^[a-z]*$/i', $value)) {
                    $error = true;
                }
                break;
            // 数字
            case "numeric":
            case "n":
                if (!preg_match('/^[0-9]*$/i', $value)) {
                    $error = true;
                }
                break;
            // アルファベットと数字
            case "alphabet&numeric":
            case "an":
                if (!preg_match('/^[a-z0-9]*$/i', $value)) {
                    $error = true;
                }
                break;
            // アルファベットと数字と記号
            case "alphabet&numeric&symbols":
            case "ans":
                if (!preg_match('/^[a-z0-9\!\"\#\$\%\&\'\(\)\=\-\^\~\`\@\[\{\+\;\*\:\]\}\,\<\.\>\/\?\_]*$/i', $value)) {
                    $error = true;
                }
                break;
            // Eメール（Eメール形式の正規表現判定については諸説あるため、各自調査の上利用してください）
            case "email":
                if (!preg_match('/^([a-z0-9\+_\-\.\(\)\^\=\*\&\%\#\!]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i', $value)) {
                    $error = true;
                }
                break;
            // URL
            case "url":
                if (!preg_match('/^https?\:\/\/[a-z0-9\/\:\%\#\$&\?\(\)~\.\=\+\-]+$/i', $value)) {
                    $error = true;
                }
                break;
            // 電話番号
            case "tel":
                if (!preg_match('/^[0-9\-\+]*$/i', $value)) {
                    $error = true;
                }
                break;
            // その他
            default:
                break;
        }
        return !$error;
    }
}
```

# 使い方
checkメソッドに、チェックしたい値と定義を渡します。
checkの戻り値がfalseの場合はエラーなしで、連想配列が返ってきた場合はエラーが発生したと判断します。
詳しくは以下の通りです。

```PHP
// 連想配列で値を渡す
$test = array(
	"param1" => "24a423s24a42324a42324a42324a42324a42324a42324a42324a42324a423",
	"param2" => "sssAsss2s#あssssss",
);

// 評価内容を定義
$conditions = array(
	"param1" => array(
		"required" => null, // true->必須
		"max" => 20, // 最大文字数
		"min" => null, // 最小文字数
		"type" => "numeric", // 許容形式（null / alphabet / numeric / alphabet&numeric / alphabet&numeric&symbols / email / url / tel）
		"disallowWhitespace" => true, // 空白文字を禁止するか
		"disallowZenkaku" => true, // 全角文字を禁止するか
	),
	"param2" => array(
		"required" => null,
		"max" => 27,
		"min" => 12,
		"type" => "alphabet&numeric&symbols",
		"disallowWhitespace" => null,
		"disallowZenkaku" => null,
	),
);
$CheckInput = new CheckInput();
$errors = $CheckInput->check($test, $conditions);
var_dump($errors);
> array(1) {
>  ["param1"]=>
>   array(1) {
>     ["type"]=>
>     string(42) "正しい形式で入力してください"
>   }
> }
```

# 注意点

- メールアドレスの正規表現チェックについては、完全なものではありません。私の想定する使い方で、実用上十分と思える範囲での実装に過ぎません。必要に応じて調査の上、ご利用下さい。