SESSIONを使用したメールフォームについて - PHPプロ!Q&A掲示板

2839

  • 0P

SESSIONを使用したメールフォームについて

質問日時 / 2010年8月13日 13:03    回答数 / 3件

Questioner:  h032313  このエントリーをはてなブックマークに追加 

キーワード / SESSION    メールフォーム    エラーチェック   

以前http://www.phppro.jp/qa/2824でご質問させていただき、SESSIONにてメールフォームを作成することにしたのですが、困っているとこがあり、再度ご質問させていただきました。

/* form.php */
  1. <?php
  2.   //セッションを開始
  3.   session_start();
  4. ?>
  5. <html>
  6. <body>
  7.  
  8. <form action="complete.php" method="post">
  9. <dl>
  10. <dt>名前</dt>
  11. <dd>
  12. <?php echo $_SESSION['err_name']?>
  13. <input type="text" size="20" name="name" value="<?php echo $_SESSION['name']?>" />
  14. </dd>
  15. <dt>コメント</dt>
  16. <dd>
  17. <?php echo $_SESSION['err_comment']?>
  18. <textarea name="comment" rows="5" cols="40"><?php echo $_SESSION['comment']?></textarea>
  19. </dd>
  20. </dl>
  21. <input type="hidden" name="contact" value="<?php $_SESSION['contact']?>" />
  22. <input type="submit" name="submit" value="確認" />
  23. </form>
  24.  
  25. </body>
  26. </html>

/* complete.php */
  1. <?php  
  2. //セッションを開始
  3. session_start();
  4.  
  5. $name    = $_POST['name'];
  6. $comment = $_POST['comment'];
  7. $contact = $_POST['contact'];
  8.   
  9. if (isset($contact)) {
  10. // 名前欄をチェック
  11. if (empty($name)) {
  12. $_SESSION['err_name'] = "<p>お名前は必須項目です。</p>";
  13. }
  14.  
  15. // 質問・コメント欄をチェック
  16. if (empty($comment)) {
  17.  $_SESSION['err_comment'] = "<p>質問・コメントを入力してください。</p>";
  18. }
  19. if (!count($contact)) {
  20. // POSTされたデータとエラーメッセージをセッション変数に保存
  21. $_SESSION['name']     = $name;
  22. $_SESSION['comment']  = $comment;
  23. $_SESSION['contact']  = $contact;
  24.  
  25. header("Location: form.php");  
  26. exit;  
  27. }
  28. }
  29.  
  30. ?>
  31. <html>
  32. <body>
  33.  
  34. <dl>
  35. <dt>名前</dt>
  36. <dd><?php echo $name?></dd>
  37.  
  38. <dt>内容</dt>
  39. <dd><?php echo nl2br($comment)?></dd>
  40. </dl>
  41. </body>
  42. </html>

以上のソースなのですが、空入力でもcomplete.phpに通ってしまいます。
ページを戻るとエラーが表記されるようになるのですが・・・
まだ勉強して間もないため、違っているとこのソースなどをご教授いただければと思います。

ご面倒かと思いますが、よろしくお願いします。

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01pannna関数の使い方を思いっきり間違えているような… 関数
┣A02magicflute2この意見は投稿者によって削除されました。
┣A03win_phpecho の箇所では忘れずに htmlspecialchars()を使いま
┗A04yuukiこんにちは。 前回はh032313さんのやり方にそって回

回答一覧

並び替え:

A01
answererpannna [8月13日 14:02] (最終編集:8月13日 14:04)

関数の使い方を思いっきり間違えているような…
関数のリファレンスは読んでいますか?

9行目のisset関数は遷移元が入力画面かどうかの判定のようなのですが、、
それよりも$_POST変数のnameとcomment要素をisset関数で存在チェックをかけるほうがいいです。

19行目でcount関数で何かをしようとしていますが、
count関数は「配列の要素数を取得する」関数です。$contact変数は配列ですか?
「名前またはコメントが未入力の場合に入力画面に戻す」という仕様なので、
$contact変数は判定に使える変数ではありません。

typoがあるかもしれませんが、簡単に考えればこのような感じになるかと。

// initialize
unset($_SESSION['err_comment']);
unset($_SESSION['err_name']);
$errFlag = false;

if(!strlen($comment)) {
    $_SESSION['err_comment'] = 'コメント未入力';
    $errFlag = true;
}
if(!strlen($name)) {
    $_SESSION['err_name'] = '名前未入力';
    $errFlag = true;
}
if($errFlag)
    header('Location: xxxxx');

この意見に回答する

ツリーへ TOPへ

A02
answerermagicflute2 [8月14日 01:52]

この意見は投稿者によって削除されました。

ツリーへ TOPへ

A03
answererwin_php [8月16日 21:43] (最終編集:8月16日 21:44)

echo の箇所では忘れずに htmlspecialchars()を使いましょう。
第二引数も忘れずに。form.phpのvalueも。

単純に頭を整理して、$_SESSION['err_name']等がtrueなのかfalseなのかを
判定って考えると


//前出ですが忘れずに
unset($_SESSION['err_name']);
unset($_SESSION['err_comment']);


if($_SESSION['err_name'] or $_SESSION['err_comment']){
header("Location: form.php");
}

もちろんempty()等々きちんとマニュアルを読んで理解したうえで使用
しているならなにも問題ないですが、0をフォームに入力してみた場合
の挙動を見てみてください。

後々この辺を理解しとかないと複雑なフォームを作る際に問題が起きますよ。

この意見に回答する

ツリーへ TOPへ

A04
answereryuuki [8月17日 14:24]

こんにちは。
前回はh032313さんのやり方にそって回答しましたが、今回は別の方法を提示します。
このようなフォームであればわざわざ二つのスクリプトにする必要がないと思うからです。

>以上のソースなのですが、空入力でもcomplete.phpに通ってしまいます。
>ページを戻るとエラーが表記されるようになるのですが・・・

まずif(!count($contact))という判定がおかしいです(エラーは出ないみたいだけど) 。
countは変数に含まれる要素の数をカウントするものなので、やるのであれば
if(count($contact) > 0)です。
しかし、空配列を判定に使うのは微妙です。
また、issetは空変数でtrueを返しますがemptyはfalseを返します。
ここらへんを理解しておかないと後々、訳分からなくなってきますよ。

で、別の方法の提示の件ですが、この手のフォームでわざわざスクリプトを分ける必要はないかと思います。
分けるが故に手間が増えていると感じました。
通常、確認、完了ページと表示を変える場合、その時々に応じてhtmlを書き換えてあげれば良いんです。
僕はこういう場合POSTにmodeという変数を持たせてそこにモードの振り分けを行なう値を入れ込みます。
後はそれをエラー判定に組み込んで制御すればいいんです。
下記のコードでほぼ上手くいくでしょうが、ちゃんと解読して理解してくださいね。
ちなみにテキトーに作ったので抜けはあるかもしれないです。悪しからず。


  1. <?php
  2. //フォーム値格納配列
  3. $form =  array();
  4. //エラー配列
  5. $error =  array();
  6. //html出力用配列
  7. $html =  array();
  8.  
  9. //POST値があれば$formに格納、ついでにエラー判定
  10. if($_POST){
  11.   $form = $_POST;  
  12.   //エラー判定
  13.   if($form['name'] == '' ){
  14.     $error['name'] = '<span style="color:#ff0000;">名前が入力されていません。</span><br />'
  15.   }
  16.   //エラー判定
  17.   if($form['comment'] == '' ){
  18.     $error['comment'] = '<span style="color:#ff0000;">コメントが入力されていません。</span><br />'
  19.   }
  20.   //エラーがあるならモードを変更
  21.   if(count($error) > 0){
  22.     $form['mode'] = '';
  23.   }
  24. }
  25.  
  26. //モード判定
  27. //確認画面、値はhiddenに入れておく
  28. if($form['mode'] == 'comfirm'){
  29.   $html['top_text'] = '宜しければ完了をクリックしてください。';
  30.   $html['name'] = $form['name'].'<input type="hidden" size="20" name="name" value="'.$form['name'].'" />';
  31.   $html['comment'] = $form['comment'].'<input type="hidden" size="20" name="comment" value="'.$form['comment'].'" />';
  32.   $html['next_mode']'complete';
  33.   $html['submit'] = '<input type="submit" name="submit" value="完了する" />';
  34. //完了画面
  35. }elseif($form['mode'] == 'complete'){
  36.   $html['top_text'] = '完了しました。';
  37.   $html['name'] = $form['name'];
  38.   $html['comment'] = $form['comment'];
  39.   $html['submit'] = '<a href="form.php" >戻る</a>';
  40. //通常画面
  41. }else{
  42.   $html['top_text'] = 'フォームに値を入力してください。';
  43.   $html['name'] = $error['name'].'<input type="text" size="20" name="name" value="'.$form['name'].'" />';
  44.   $html['comment'] = $error['comment'].'<textarea name="comment" rows="5" cols="40">'.$form['comment'].'</textarea>';
  45.   $html['next_mode']'comfirm';
  46.   $html['submit'] = '<input type="submit" name="submit" value="確認" />';
  47. }
  48. ?>
  49. <!--表示用html雛形-->
  50. <html>
  51.   <body>
  52.   <form action="form.php" method="post">
  53.     <dl>
  54.       <dt><?php echo $html['top_text']?></dt>
  55.     </dl>
  56.     <dl>
  57.       <dt>名前</dt>
  58.     <dd>
  59.       <?php  echo $html['name']?>
  60.     </dd>
  61.       <dt>コメント</dt>
  62.     <dd>
  63.       <?php  echo $html['comment']?>
  64.     </dd>
  65.     </dl>
  66.     <input type="hidden" name="mode" value="<?php echo $html['next_mode']?>" />
  67.     <?php echo $html['submit']?>
  68.   </form>
  69.   </body>
  70. </html>

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
PHPのHTML埋め込み記述について
 このエントリーをはてなブックマークに追加 
A
$_POST["data"] == "男" ? $val = "checked" : $val = "" ; の意味は以下と同じです。 if($_POST["data"] == "男"){ $val = "checked; } e...

>>続きを読む

kende様のご指摘通り、三項演算子を使用する際には、コードの複雑度などを考慮する必要がありますね。書きやすさと共に可読性も追求したいところですね。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)