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

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

ただいまの
回答率

89.64%

PHPでフォームでエラーメッセージが出た時にデータがそのまま残るようにしたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,896

dog57

score 119

入力フォーム→確認フォーム→登録完了
という上記の画面を作成しています。

確認フォームでバリデーションを行い
リダイレクトで入力フォームにエラーメッセージを表示させているのですが、

入力フォームでエラーメッセージが出たときに
データをそのまま残すにはどうしたらよいでしょうか?(チェックボックス)

ちなみに、確認フォームから戻るボタンで入力フォームに戻る時のデータは保持できています。

ご教授よろしくお願いします。

registration_form.html

  <!-- インラインチェックボックス 趣味 -->
        <div class="form-group">
            <label class="control-label col-md-4" for="checkbox">趣味 <span class="label label-info">任意</span></label>
            <div class="col-md-4">
              <div class="checkbox">
                  <label class="checkbox-inline">
                      <input name="hobby['baseball']" type="checkbox" value="野球" {% if hobby.baseball is defined %} checked {% endif %}> 野球
                    </label>
                    <label class="checkbox-inline">
                      <input name="hobby['football']" type="checkbox" value="サッカー" {% if hobby.football is defined %} checked {% endif %} > サッカー
                    </label>
              </div>
            </div>
          </div>

registration_form.php 登録フォーム

<?php
// 開発時にこれを書かないのはNG
ini_set('display_errors', true);
error_reporting(E_ALL);

session_start();

// 文字化けを治す
header("Content-type: text/html; charset=utf-8");

// 変数の定義(初期化)
$name = "";
$email = "";
$password = "";
$tel = "";
$prefectures = "";
$hobby = "";
$gender = "";
$contact = "";

$errorMsg = '';



// エラーメッセージ
if (isset($_SESSION['errorMsg'])) {

  if (count($errorMsg) >= 1) {
    $errorMsg = $_SESSION['errorMsg'];
  }
}

//
// 確認フォームから戻った時のデータ保持
//

// name の入力データ保持
if (isset($_SESSION['email'])) {

  if ($_SESSION['name'] === $_SESSION['name']) {
    $name = $_SESSION['name'];

  }
}

//email の入力データの保持
if (isset($_SESSION['email'])) {

  if ($_SESSION['email'] === $_SESSION['email'] & isset($_SESSION['email'])) {
    $email = $_SESSION['email'];

    }
  }


//password の入力データの保持
if (isset($_SESSION['password'])) {

  if ($_SESSION['password'] === $_SESSION['password'] & isset($_SESSION['password'])) {
    $password = $_SESSION['password'];

  }
}


//tel の入力データの保持
if (isset($_SESSION['tel'])) {

  if ($_SESSION['tel'] === $_SESSION['tel'] & isset($_SESSION['tel'])) {
    $tel = $_SESSION['tel'];

  }
}

//prefectures の入力データの保持
if (isset($_SESSION['prefectures'])) {

  if ($_SESSION['prefectures'] === $_SESSION['prefectures'] & isset($_SESSION['prefectures'])) {
    $prefectures = $_SESSION['prefectures'];

  }
}

// hobby の入力データの保持
if (isset($_SESSION['hobby'])) {

  if ($_SESSION['hobby'] === $_SESSION['hobby'] & isset($_SESSION['hobby'])) {
    $hobby = $_SESSION['hobby'];

  }
}


// gender の入力データの保持
if (isset($_SESSION['gender'])) {

  if ($_SESSION['gender'] === $_SESSION['gender'] & isset($_SESSION['gender'])) {
    $gender = $_SESSION['gender'];

  }
}

// contact の入力データの保持
if (isset($_SESSION['gender'])) {

  if ($_SESSION['contact'] === $_SESSION['contact'] & isset($_SESSION['contact'])) {
    $contact = $_SESSION['contact'];

  }
}





//
// Twig
//


// Composerで作成されたautoload.phpを読み込む
require_once('../vendor/autoload.php');
// Twig_loader_Filesystemを使う。registration_form.phpからのtemplatesディレクトリを指定。(相対パス)
$loader = new Twig_Loader_filesystem('../templates');
// $loaderをTwigの環境設定として twig instance を生成
$twig = new Twig_Environment($loader);



// render
echo $twig->render('registration_form.html', array(

  'name' => $name,
  'email' => $email,
  'password' => $password,
  'tel' => $tel,
  'prefectures' => $prefectures,
  'hobby' => $hobby,
  'gender' => $gender,
  'contact' => $contact,

  'errorMsg' => $errorMsg


  )
);

confirm.php 確認フォーム

/ 開発時にこれを書かないのはNG
ini_set('display_errors', TRUE);
error_reporting(E_ALL);

session_start();


// 文字化けを治す
header("Content-type: text/html; charset=utf-8");

// 変数の定義(初期化)
$name = "";
$email = "";
$password = "";
$tel = "";
$prefectures = "";
$hobby = "";
$gender = "";
$contact = "";
$string = "";


$date = date_default_timezone_set('Asia/Tokyo');


$form_Content = array($name, $email, $password, $tel, $prefectures, $hobby, $gender, $contact);

// エラーメッセージの配列の初期化
$errorMsg = array();
// セッション変数の初期化
$_SESSION['errorMsg'] = array();
// 初期化



// XSS対策 サニタイズ(無毒化)
function h($string) {

    if(is_array($string)){
        return array_map("h", $string);

    } else {

        return htmlspecialchars($string, ENT_QUOTES, "UTF-8");
    }
}

  // XSS対策 (hrefやsrcの値がURLか確認する)
  function urlCheck($form_Content) {
      if (!preg_match("/^(https?:.+)$/", $form_Content)) {
          return $errorMsg[] = "不正を検知しました。";
      } else {
          return true;
      }
  }



// POST時
if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') == 'POST') {


    $_SESSION["name"] = filter_input(INPUT_POST, 'name');
    $_SESSION["email"] = filter_input(INPUT_POST, 'email');
    $_SESSION["password"] = filter_input(INPUT_POST, 'password');
    $_SESSION["tel"] = filter_input(INPUT_POST, 'tel');
    $_SESSION["prefectures"] = filter_input(INPUT_POST, 'prefectures');
    $_SESSION["hobby"] = filter_input(INPUT_POST, 'hobby', FILTER_DEFAULT,FILTER_REQUIRE_ARRAY);
    $_SESSION["gender"] = filter_input(INPUT_POST, 'gender');
    $_SESSION["contact"] = filter_input(INPUT_POST, 'contact');

    $name  = $_SESSION["name"];
    $email  = $_SESSION["email"];
    $password  = $_SESSION["password"];
    $tel  = $_SESSION["tel"];
    $prefectures  = $_SESSION["prefectures"];
    $hobby  = $_SESSION["hobby"];
    $gender = $_SESSION["gender"];
    $contact  = $_SESSION["contact"];



//
// 未入力チェック
//

// エラーメッセージの配列の初期化
$errorMsg = array();

// 名前の未入力チェック
if (empty($_SESSION["name"])) {
    $errorMsg[] = "名前を入力してください。";
}

// メールアドレスの未入力チェック
if (empty($_SESSION["email"])) {
    $errorMsg[] = "メールアドレスを入力してください。";
}

// パスワードの未入力チェック
if (empty($_SESSION["password"])) {
    $errorMsg[] = "パスワードを入力してください。";
}

// 電話番号の未入力チェック
if (empty($_SESSION["tel"])) {
    $errorMsg[] = "電話番号を入力してください。";
}

// 都道府県の未入力チェック
if ($_SESSION["prefectures"] == "選択") {
    $errorMsg[] = "都道府県を選択してください。";
}

  //
  // 文字数チェック
  //

  // 名前の文字数チェック
  if (strlen($_SESSION["name"]) >= 60) {
    $errorMsg[] = "氏名が長すぎます。";
  }

  // パスワード文字数チェック(8文字以上か)
  if (preg_match("/^[a-zA-Z1-9]{1,7}$/", $_SESSION["password"])) {
      $errorMsg[] = "パスワードは8文字以上で入力してください。";
  }

  // 電話番号の文字数チェック(10文字 or 11文字)
  if (strlen($_SESSION["tel"]) >= 1 && strlen($_SESSION["tel"]) <= 9 && preg_match("/^[0-9]+$/", $_SESSION["tel"])) {
      $errorMsg[] = "電話番号は10文字か11文字で入力してください。";
  } elseif (strlen($_SESSION["tel"]) >= 12 && preg_match("/^[0-9]+$/", $_SESSION["tel"])) {
      $errorMsg[] = "電話番号は10文字か11文字で入力してください。";
  }

  //
  // 形式チェック
  //

  // メールアドレス形式チェック
  if (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $_SESSION["email"]) && $_SESSION["email"] !== "") {
      $errorMsg[] = "メールアドレスに間違いがあります。";
  }

  // 電話番号の形式チェック
  if (preg_match("/[-]+/", $_SESSION["tel"])) {
      $errorMsg[] = "電話番号はハイフンなしで入力してください。";
  }

  //
  // 半角英数字チェック
  //

  // 電話番号の数字チェック
  if (!preg_match("/[0-9]/", $_SESSION["tel"]) && $_SESSION["tel"] !== "") {
    $errorMsg[] = "電話番号は半角数字で入力してください。";
  }


  // 電話番号の全角チェック Todo
  //if (strlen($tel) !== mb_strlen($tel, "UTF-8")) {
    //  $errorMsg[] = "電話番号に全角が含まれています。";
  //}


  if (count($errorMsg) >= 1) {
      $_SESSION['errorMsg'] = $errorMsg;

      header("location: registration_form.php");
      exit;

  }

}



//
// Twig
//

// Composerで作成されたautoload.phpを読み込む
require_once ('../vendor/autoload.php');
// Twig_loader_Filesystemを使う。confirm.phpからのtemplatesディレクトリを指定。(相対パス)
$loader = new Twig_Loader_filesystem('../templates');
// $loaderをTwigの環境設定として twig instance を生成
$twig = new Twig_Environment($loader);


// render
echo $twig->render('confirm.html', array (

   'name' => $name,
   'email' => $email,
   'password' => $password,
   'tel' => $tel,
   'prefectures' => $prefectures,
   'hobby' => $hobby,
   'gender' => $gender,
   'contact' => $contact,

   'errorMsg' => $errorMsg,
   'string' => $string


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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2018/02/10 12:33

    ビュー部分よりもPOSTされた情報をどのように処理されているかが分かるコントローラ部分(PHPの処理)の方が大事だったりします。提示ソースはビュー部分だけなのでPHP側のソースもご提示いただけますか?

    キャンセル

  • dog57

    2018/02/10 13:31

    追記いたしました。

    キャンセル

回答 2

checkベストアンサー

+2

確認フォームに POST された内容を入力フォームへ差し戻します。
差し戻しに使うのは、POST を使うことが多いです。

registration_form.html を見ると、すでにデータが渡ればチェックが切り替わる仕組みは入っています。
ので差し戻しの仕組みと、正しい変数を与えてあげてください。

ちなみに、戻るボタンを使用した場合は、ブラウザに保存された内容を表示しているだけなので、「データが保持されている」というのはちょっと違います。

コードが追記されたので
差し戻しに POST ではなく、session を使用していますね。
で、ざっと見た感じでは、データは戻されています。
{% if hobby.baseball is defined %}
が動作していないのであれば、
・twig にデータが渡っているか?
を取っ掛かりに、切り分けをすれば良いです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/10 10:56

    エラー(バリデーション)が出た時に、同時にそのままデータを保持させるためにはどうしたらよいでしょうか?

    キャンセル

  • 2018/02/10 11:01

    書いたとおりです。
    差し戻しに使うのは、POST を使うことが多いです。

    キャンセル

  • 2018/02/11 09:23

    コードが追記されたので、回答に反映しました。

    キャンセル

+1

フィルターは第三引数のみなので

$_SESSION["hobby"] = filter_input(INPUT_POST, 'hobby', FILTER_DEFAULT,FILTER_REQUIRE_ARRAY);

だと、第四引数に配列以外が設定されているから false やら null が帰ってきてるかとおもいますよ

第三引数が int $filter となっているのでフィルタに設定できる型であれば

# 説明用のコード ノーテストのため間違えてる恐れもあり
$_SESSION["hobby"] = filter_input(INPUT_POST, 'hobby', FILTER_DEFAULT | FILTER_REQUIRE_ARRAY);

のような感じになるかと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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