質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.57%

お問い合わせフォームのバリデーション部分の共通化

解決済

回答 5

投稿

  • 評価
  • クリップ 1
  • VIEW 827

test.shiro2018

score 16

PHP初心者でお問い合わせフォームを作成しています。
手探りで一度作ってみたのですが、共通化ができていないのでそこを改善できないか考えています。

・実現したいこと
具体的には、バリデーション部分のコードをまとめられないかと考えていますが方法が分かりません。

例 ↓このような部分です
if ($conf_data["name"] === "") {
$err_msg["name"] = "お名前を入力してください";
}

if ($conf_data["namekana"] === "") {
$err_msg["namekana"] = "ふりがな(お名前)を入力してください";
}

↓バリデーション部分のコードになります

  $err_msg = array();
  if ($conf_data["name"] === "") {
    $err_msg["name"] = "お名前を入力してください";
  }

  if ($conf_data["namekana"] === "") {
    $err_msg["namekana"] = "ふりがな(お名前)を入力してください";
  }

  if ($conf_data["corp"] === "") {
    $err_msg["corp"] = "勤務先または団体名を入力してください";
  }

  if ($conf_data["corpkana"] === "") {
    $err_msg["corpkana"] = "ふりがな(勤務先または団体名)を入力してください";
  }

  if ($conf_data["zip"] === "") {
    $err_msg["zip"] = "郵便番号を入力してください";
  } else if (!preg_match("/^[0-9]+$/", $conf_data["zip"])) {
    $err_msg["zip"] = "郵便番号はハイフンなしの半角数値で入力してください。(0000000)";
  }

  if (empty($conf_data["pref"])) {
    $err_msg["pref"] = "都道府県を選択してください";
  } else if (!array_key_exists($conf_data["pref"],$prefs)){
    $err_msg["pref"] = "都道府県の選択が正しくありません";
  }

  if ($conf_data["address"] === "") {
    $err_msg["address"] = "住所を入力してください";
  }

  if (($conf_data["tel1"] === "") && ($conf_data["tel2"] === "") && ($conf_data["tel3"] === "")) {
    $err_msg["tel1"] = "電話番号を入力してください";
  } else if (($conf_data["tel1"] === "") || ($conf_data["tel2"] === "") || ($conf_data["tel3"] === "")) {
    $err_msg["tel2"] = "電話番号をすべて入力してください";
  } else if (!preg_match("/^[0-9]+$/", $conf_data["tel1"]) || !preg_match("/^[0-9]+$/", $conf_data["tel2"]) || !preg_match("/^[0-9]+$/", $conf_data["tel3"])) {
    $err_msg["tel3"] = "電話番号を正しく入力してください";
  }

  if (($conf_data["fax1"] !== "") || ($conf_data["fax2"] !== "") || ($conf_data["fax3"] !== "")) {
    if (($conf_data["fax1"] === "") || ($conf_data["fax2"] === "") || ($conf_data["fax3"] === "")) {
      $err_msg["fax1"] = "FAX番号をすべて入力してください";
    } else if (!preg_match("/^[0-9]+$/", $conf_data["fax1"]) || !preg_match("/^[0-9]+$/", $conf_data["fax2"]) || !preg_match("/^[0-9]+$/", $conf_data["fax3"])) {
      $err_msg["fax2"] = "FAX番号を正しく入力してください";
    }
  }

  if ($conf_data["email"] === "") {
    $err_msg["email"] = "メールアドレスを入力してください";
  } else if (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $conf_data["email"])) {
    $err_msg["email"] = "正しくないメールアドレスの可能性があります";
  }

  if ($conf_data["contact_reason"] === "") {
    $err_msg["contact_reason"] = "お問い合わせカテゴリを選択してください";
  } else if (!array_key_exists($conf_data["contact_reason"],$contact_reason_array)) {
    $err_msg["contact_reason"] = "お問い合わせカテゴリの選択が正しくありません";
  }

  if ($conf_data["message"] === "") {
    $err_msg ["message"] = "お問い合わせ内容を入力してください";
  }

分かりにくい質問で申し訳ありません。何か方法があれば教えていただけると助かります。
よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2018/11/06 15:00

    まだ質問が「受付中」になっていますが、「ベストアンサー」を選び「解決済」にされてはいかがでしょうか。

    キャンセル

回答 5

checkベストアンサー

+1

フレームワークは何を使われていますか?
使っているフレームワークによっては標準のバリデーションクラス群があるので
それを使うといいと思います。

なければ自前でvalidationクラスを作成し
必須チェック(...を入力してください統一。項目名を引数)
電話番号チェック
メールアドレスチェック
数値チェック
日付チェック
等標準的なチェックfunctionを設けて、それを使うようにすればいいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/05 10:38

    フレームワークは今回は使っていません。
    自前でvalidationクラスを作れたらと思い、まずは必須チェックで試してみたのですがどのようにクラスを作っていけばよいのか苦戦しており上手くいっておりません(ーー;)

    キャンセル

  • 2018/11/05 10:59

    別でクラスファイルを切って作ればいいと思います。
    ```
    <?php

    class Validate
    {

    public static function checkRequired( $colName, $val)
    {

    // $valを使ってチェック処理
       $errors=$colName . ”は必須です";
    return $errors;
    }

    public static function checkNumber($colName, $val)
    {
    // チェック処理
    return $error;
    }

    public static function checkPhoneNumber($colName, $val,$mobileFlg,$hyfunFlg)
    {
    // チェック処理
    return $error;
    }
    public static function checkFormatDate($colName, $val)
    {
    // チェック処理
    return $error;
    }

    }

    ```
    使う時はphp側からValidate::checkRequired(引数)
    で使ったらいいと思います。namespaceとかはご自分で適当に切って頂いて。

    キャンセル

  • 2018/11/06 14:06

    ご丁寧にありがとうございます。実装したところ上手くいきました!
    使いこなせるように学習していきます!

    キャンセル

  • 2018/11/06 14:11

    よかったです^^

    キャンセル

+1

おなじロジックでバリデートするならリストをまとめておけばよいでしょう

$conf_data=["name"=>"aaa","namekana"=>"bbb","corp"=>""];
$list=["name"=>"お名前","namekana"=>"ふりがな(お名前)","corp"=>"勤務先または団体名","corpkana"=>"ふりがな(勤務先または団体名)"];

foreach($list as $key=>$val){
  $err_msg[$key]="";//初期化
  if(!isset($conf_data[$key]) or $conf_data[$key] === "") {
    $err_msg[$key] = $val."を入力してください";
  }
}

print_r($err_msg);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/05 10:34

    回答ありがとうございます。
    すみません、何度も聞いてしまい申し訳ないのですが、
    $conf_data配列の"name"=>"aaa"の部分はお名前とかふりがな(お名前)ということになるのでしょうか?

    キャンセル

  • 2018/11/05 10:37

    > $conf_data配列の"name"=>"aaa"の部分はお名前とかふりがな(お名前)ということになるのでしょうか?

    わかりにくくてスミマセン。検証用のサンプルデータです。
    nameとnamekanaに適当なデータがはいっていて
    corpが空、corpkanaは宣言さえされていない状態を示しています。

    $conf_dataは質問者さんが適当に指定してあげてください

    キャンセル

  • 2018/11/05 11:37

    ご丁寧にありがとうございます。
    上手くいきました!自分でも様々な方法を身につけられるように今後も学習していきたいと思います!

    キャンセル

+1

共通以外のところを引数で渡した関数を作ると良いです。

※未検証 簡素化のため$_POSTで受け取らせています。

//type :チェックタイプ 配列
//name :入力名称
//prefix :エラーメッセージにつける接頭辞
function validation($types=[],$name=null,$prefix=""){
  $err = [];
  if(count($types) === 0 || $name = null || !array_key_exists($name,$_POST)) return [];

  $value = $_POST[$name];
  forech($types as $type){
    switch($type){
      case 0://必須
        if($value == ""){
            $err[] = $prefix."入力してください";
        }
        break;
      case 1://tel
        if(!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $value)){
            $err[] = $prefix."正しく入力してください";
        }
        break;
      //チェックパターンを追加していく
    }    
  }
  return $err;
}

呼び出す側

$err_msg["name"] = validation([0],"name","お名前を");
$err_msg["kana"] = validation([0],"kana","お名前(カナ)を");
$err_msg["tel"] = validation([0,1],"tel","電話番号を");

var_dump($err_msg);

こんな感じで。
typeのところを数字ではなくチェック名称にしてパターンを書いていくとか
validation()の引数を増やしていくとかすると
最大文字数とか複雑なチェックも追加していけると思います。

基本的には「変数」をうまく使うことです。
共通であるところと共通でないところを整理して、
共通でないところを引数で変数として使うことで幾らでも作りこんでいけます。
(最大文字数のチェックも項目により文字数の制限数は変わりますが、チェック処理自体は変わりません)

今回は項目毎にvalidation()を呼び出すように作りましたが、
入力項目自体を配列で設定ファイルで持っておけば、その入力項目親名だけ渡せばそのフォームの入力チェックを全て行うようにも作れます。

ひとまず参考まで。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/06 17:49

    回答いただきありがとうございます。とてもすっきりしているコードですね!
    switchを使ったコードは書いたことがなかったので今後の学習の参考にさせていただきます!

    キャンセル

  • 2018/11/06 18:06

    工夫次第で如何様にもできるということがわかっていただけたらと

    キャンセル

+1

ご質問のコードを踏襲しながら整理してみました。
全体を見れるならもっと詰められる部分はあると思います。
//長くなっちゃいましたね。(汗

$items = array(
'name'=>'お名前',
'namekana'=>'ふりがな(お名前)',
'corp'=>'勤務先または団体名',
'corpkana'=>'ふりがな(勤務先または団体名)',
'zip'=>'郵便番号',
'pref'=>'都道府県',
'address'=>'住所',
'tel'=>'電話番号',
'fax'=>'FAX番号',
'email'=>'メールアドレス',
'contact_reason'=>'お問い合わせカテゴリ',
'message'=>'お問い合わせ内容');

$validates = array(
'name'=>'is_empty',
'namekana'=>'is_empty',
'corp'=>'is_empty',
'corpkana'=>'is_empty',
'zip'=>'is_empty,no_zip',
'pref'=>'bad_choice',
'address'=>'is_empty',
'tel'=>'tel_check',
'fax'=>'tel_check',
'email'=>'is_empty,not_mail',
'contact_reason'=>'bad_choice',
'message'=>'is_empty');

function is_empty($val, $nam) {
  $msg = '';
  if ($val === '') {
    $msg = $nam . 'を入力してください';
  }
  return $msg;
}

function no_zip($val, $nam) {
  $msg = '';
  if (!preg_match("/^[0-9]+$/", $val)) {
    $msg = $nam . 'はハイフンなしの半角数値で入力してください。(0000000)';
  }
  return $msg;
}

function bad_choice($val, $nam, $cands) {
  $msg = '';
  if (empty($val)) {
    $msg = $nam . 'を選択してください';
  } else if (!array_key_exists($val, $cands)) {
    $msg = $nam . 'の選択が正しくありません';
  }
  return $msg;
}

function get_val3($data, $itm) {
  $item1 = $itm . '1';
  $item2 = $itm . '2';
  $item3 = $itm . '3';
  return array($data[$item1], $data[$item2], $data[$item3]);
}

function tel_check($vals, $nam) {
  $msg = '';
  $f1 = ($vals[0] === '');
  $f2 = ($vals[1] === '');
  $f3 = ($vals[2] === '');
  if ($f1 && $f2 && $f3) {
    $msg = $nam . 'を入力してください';
  } else if ($f1 || $f2 || $f3) {
    $msg = $nam . 'をすべて入力してください';
  } else {
    foreach ($vals as $v) {
      if (!preg_match("/^[0-9]+$/", $v) {
        $msg = $nam . 'を正しく入力してください';
        break;
      }
    }
  }
  return $msg;
}

function not_mail($val, $nam) {
  $msg = '';
  if (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $val) {
    $msg = '正しくない' . $nam . 'の可能性があります';
  }
  return $msg;
}

$err_msg = array();

foreach ($items as $key=>$item_name) {
  $valids = explode(',', $validates[$key]);
  if ($valids[0] == 'tel_check') {
    $msg = tel_check(get_val3($conf_data, $key), $item_name);
    if (!empty($msg)) $err_msg[$key] = $msg;
    continue;
  }
  if ($valids[0] == 'bad_choice') {
    $cands = ($key == 'pref') ? $prefs : $contact_reason_array;
    $msg = bad_choice($conf_data[$key], $item_name, $cands);
    if (!empty($msg)) $err_msg[$key] = $msg;
    continue;
  }
  foreach ($valids as $valid) {
    $msg = $valid($conf_data[$key], $item_name);
    if (!empty($msg)) {
      $err_msg[$key] = $msg;
      braek;
    }
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

使い回し、というのは、別ページでもということでしょうか?
例えば
validation.phpfunctionでまとめておいて必要な時にinclude_onceして使うのはどうでしょうか?

function name_chk($name){
    if ($name == "") {
    $msg = "お名前を入力してください";
    return $msg;
    }
}

使用側

$err_msg['name'] = name_chk($conf_data['name']);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/06 17:51

    回答いただきありがとうございます。
    お問い合わせフォームなので送信の前に同じ内容のエラーチェックを使いたいと考えておりました!
    出来れば、クラス等で汎用性の高いコードを書いてみたいと思いまして。。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る