validationの処理を一括にまとめる

ECサイトにおけるユーザー登録や商品登録の画面を作成するにあたって、入力フォームのバリデーションが必要になってきます。しかし、フォームの種類が多くなると一つずつバリデーションをするのが面倒なので、「未入力の場合」、「文字数制限がある場合」などと処理をまとめて記述する方法をメモします。
## 作りたいもの
- ユーザ登録画面
- 名前、メールアドレス、住所、パスワード、　クレジットカード番号を入力させる
- 全て入力必須、名前は50文字以内、メールアドレスはメール形式、パスワードは8文字以上、クレジットカード番号は16桁の数字というバリデーションを設ける
- `validation.php`という別のファイルを作成し、そこで処理を定義する。

## validation処理の実装

`validation.php`に以下のようにvalidationクラスを定義します。

```php
<?php
//バリデーションクラス
class Validation{
  //コンストラクタ
  function validate($input_control,$input_data){
     $result = array();//チェック結果配列
     foreach($input_control as $control_name=>$info){
        //入力情報が存在するか
        if(array_key_exists($control_name,$input_data)){

             $value = $input_data[$control_name];
             $rules = explode("|",$info["rule"]);//バリデーションルールの引き出し
             foreach($rules as $r){ //指定されたルールをループ
               $rule = explode("-",$r); //ルール設定の切り出し
               $rule_name = $rule[0]; //ルール名
               if(count($rule)>=2){
                 $rule_setting = $rule[1]; //ルール設定
               }

               switch($rule_name){
                  //入力空の場合
                  case "empty":
                      if($this->empty_check($value)){
                         $result[$control_name] = $info["name"].'を入力してください。';

                      }
                      break;

                 //最大文字数のチェック
                  case "max":
                      if($this->max_check($value,$rule_setting)){
                         $result[$control_name] = $info["name"].'は'.$rule_setting.'文字以内で入力してください。';

                      }
                      break;

                  case "email":
                      if($this->email_format_validation($value)){
                        $result[$control_name] = '正しいメールアドレスを入力してください。';


                      }
                      break;
                  case "password":
                      if($this->password_length($value)){
                          $result[$control_name] = 'パスワードは8文字以上にしてください。';

                    }
                    break;


                  case "credit":
                      if($this->credit_number($value)){
                        $result[$control_name] = 'クレジット番号を正しく入力してください。';
                      }
                      break;

               }

             }
        }
     }
     return $result;
  }

  //空のチェック
  private function empty_check($value = ""){
      return empty($value);
  }
  //入力文字数のチェック
  private function max_check($value = "",$max = 50){
      return mb_strlen($value) > $max;
  }
  private function password_length($value="") {

      // パスワード文字数チェック(8文字以上か)
      return preg_match("/^[a-zA-Z1-9]{1,7}$/", $value);

  }

  private function email_format_validation($value) {

        // メールアドレス形式チェック
        return !(filter_var($value, FILTER_VALIDATE_EMAIL));

      }
  private function credit_number($value){
    // カード番号
        return !(preg_match('/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13}|(?:2131|1800|35[0-9]{3})[0-9]{11})$/', $value));

  }
}
```

ユーザ登録画面(`user_register.php`)で使用する際には以下のように記述します。

```php
<?php
    require_once 'validation.php';


    session_start();

//登録ボタンが押された時の処理
    if($_SERVER["REQUEST_METHOD"]==="POST" &&  $_SERVER['HTTP_REFERER']=="http://localhost/EC/user_register.php"){
      //対象コントロール→バリデーションルール

      $input_control=[
       "name"=>[
                "name"=>"氏名",
                "rule"=>"empty|max-50"
               ],
       "email"=>[
                "name"=>"メールアドレス",
                "rule"=>"empty|email"
               ],
      "adress"=>[
                "name"=>"住所",
                "rule"=>"empty"
                ],
       "password"=>[
                "name"=>"パスワード",
                "rule"=>"empty|password"
               ],
      "creditNum"=>[
                "name"=>"クレジットカード番号",
                "rule"=>"empty|credit"
              ]
            ];


        $val = new Validation();
        $result = $val->validate($input_control,$_POST);
      if(!(empty($result))){
        //エラーがある場合の処理
        ?>
        <div class="errors">
        <?php
        echo "test";


        foreach($result as $error){
          echo $error;
          echo '<br>';
        }
        if($_POST['password']!=$_POST['passwordConfirm']){
          echo "パスワードが一致しません。";
        }
        ?>
        </div>
        <?php
          $name = $_POST['name'];
          $email = $_POST['email'];
          $adress = $_POST['adress'];
          $password = $_POST['password'];
          $passwordConfirm = $_POST['passwordConfirm'];
          $creditNum = $_POST['creditNum'];

      }else{
//バリデーションを通過した場合はセッションに値を格納し確認画面へ遷移
        $_SESSION = $_POST;

        header('Location:user_confirm.php');
        exit;
      }
```

氏名のバリデーションを例に挙げると、"name"=>[
                "name"=>"氏名",
                "rule"=>"empty|max-50"
               ]
となっており、"rule"の連想配列に`validation.php`で作成したルール名を｜を挟んで列挙するだけで適用できます。
`validation.php`で使用されているexplode関数は、カンマなどの文字によって区切った文字列を指定した配列に代入することが出来ます。使い方としては
`explode(区切り文字,入力文字)`
と使うことで配列が返ってきます。