PHPの入力フォームからセッションを利用してエラーチェックがない場合
次の確認画面にページ遷移させたいと思っています。
POSTでやった場合は、エラーチェック後確認画面へページ推移しましたが
入力データを確認画面で確認できなかったのでセッションでやってみようと考えました。
しかし、上手く動作せずに躓いてしまいました。
下記がソースコードです。
どこがソースコードとして悪いのかが現在分かりません。
何卒宜しくお願い致します。
inform.php
<?php //SESSIONの開始 session_start(); //POSTだったらエラーチェック if($_SERVER["REQUEST_METHOD"] == 'POST') { $error = array(); $name = trim($_SESSION['name']); $len = strlen($name); if(empty($_POST['name'])|| $len == 0) { $error[] = "<p>名称は、必須項目です。</p>"; }elseif($len < 50){ $name = preg_replace('/[ ]+$/u', '', $name); $name = mb_convert_kana($name, 'K', 'UTF-8'); $name = str_replace("\t", '', $$name); $name = str_replace('"','”',$name); }else { $error[] = "<p> 名称は、50文字まで入力ok</p>"; } $kana = trim($_SESSION['kana']); $len = strlen($kana); if(empty($_SESSION['kana']) || $len == 0){ $error[] = "<p>フリガナは、必須項目です。入力して下さい。</p>"; } elseif($len < 50) { $kana = preg_replace('/[ ]+$/u', '', $kana); $kana = mb_convert_kana($kana, 'K', 'UTF-8'); $kana = str_replace("\t", '', $kana); $kana = str_replace('"','”',$kana); }else{ $error[] = "<p>フリガナは、50文字まで入力ok</p>"; } $memo = trim($_SESSION['memo']); $len = strlen($memo); if($len < 1000) { $memo = preg_replace('/[ ]+$/u', '', $memo); $memo = mb_convert_kana($memo, 'K', 'UTF-8'); $memo = str_replace("\t", '', $memo); $memo = str_replace('"','”',$memo); }else{ $error[] = "<p>名称は、1000文字まで入力ok</p>"; } $sq = trim($_SESSION['sq']); $len = strlen($sq); if($len < 50) { $sq = preg_replace('/[ ]+$/u', '', $sq); $sq = mb_convert_kana($sq, 'K', 'UTF-8');s $sq = str_replace("\t", '', $sq); $sq = str_replace('"','”',$sq); }else{ $error[] = "<p>名称は、50文字まで入力ok</p>"; } if(!count($error)) { header("Location:http://locathost/php/confirm.php"); exit(); } } if(count($error)) { foreach ($error as $message) { print($message); } } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"/> <title>カテゴリの登録</title> </head> <body> <h1>登録フォーム</h1></body> </html><div id="form"> <form method="POST" action="<?=basename(__FILE__)?>"> <p> 名称(必須)<br/> <input type="text" name="name" value="<?=$name?>"> </p> <p> フリガナ(必須)<br/> <input type="text" name="kana" value="<?=$kana?>"> </p> <p> メモ<br/> <textarea name="memo" cols="80" rows="4" value="<?=$memo?>"></textarea> </p> <p> 並び順<br/> <input type="text" name="sq" value="<?=$sq?>"> </p> <p> <input type="submit" value="確認" /> <input type="reset" value="リセット" /> </p> </form> </div> </div>
confirm.php
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>確認画面</title> </head> <body> <form method="POST" action="./done.php"> <?php//セッションの開始
session_start();
$dt = date('Y-m-d H:i:m');
$registrar = "administrator";
$update = "administrator";
//エスケープ処理
$name = htmlspecialchars($_POST['$name'],ENT_QUOTES);
$kana = htmlspecialchars($_POST['kana'],ENT_QUOTES);
$memo = htmlspecialchars($_POST['$memo'],ENT_QUOTES);
$sq = htmlspecialchars($_POST['$sq'],ENT_QUOTES);
$_SESSION['name'] = $name;
$_SESSION['kana'] = $kana;
$_SESSION['memo'] = $memo;
$_SESSION['sq'] = $sq;
?>
<?php //次の登録完了画面へ飛ばす print "<p>入力はこれでよろしいですか?</p>"; print "<p>名称:$name</p>"; print "<p>フリガナ:$kana</p>"; print "<p>メモ:$memo</p>"; print "<p>更新日時:$dt</p>"; print "<p>更新者:$registrar</p>"; print "<p>登録日時:$dt</p>"; print "<p>登録者:$update</p>"; print "<p>並び順:$sq</p>"; ?></form> </body> </html><input type="hidden" name="name" value="<?=$name?>"> <input type="hidden" name="kana" value="<?=$kana?>"> <input type="hidden" name="memo" value="<?=$memo?>"> <input type="hidden" name="sq" value="<?=$sq?>"> <input type="submit" value="登録" /> <input type="button" onclick="history.back()" value="戻る" />
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
TamaMyu様、返信遅くなり申し訳ありません。
時間が掛かりましたが、なんとか出来ました。
DBの重複は、SELECTで重複チェックをしてその後rowCountを利用して
重複の場合は、エラーメッセージを出力できました。
セッション変数は、セッションにいれてない変数入れている変数がないように全て
セッションに格納してみました。
連想配列、var_dump関数について有難うございます。
最後になりましたが、アドバイス有難うございました。
投稿2014/12/23 15:06
総合スコア12
0
コメントありがとうございます。
memoとsqのセッション変数代入がおかしいとありました。
ソースコードをよく見ていると代入してあったりなかったりでおかしかったので
修正しました。
入力エラー表示もbodyの中で出力するようにしてみました。
入力エラー表示でエラーがない場合処理が終了しているのでここで判定する意味は、ないと
記載があるのですが一般的に入力エラーのチェックは、どこでするのでしょうか?
confirm.phpでのパラメータ埋め込みは、不要と記載がありますが
この埋め込みは、以下の部分でしょうか?
$name = htmlspecialchars($_SESSION['name'], ENT_QUOTES);
$kana = htmlspecialchars($_SESSION['kana'], ENT_QUOTES);
$memo = htmlspecialchars($_SESSION['memo'], ENT_QUOTES);
$sq = htmlspecialchars($_SESSION['sq'], ENT_QUOTES);
このソースコードは、エスケープ処理するために記述しました。
それともパラメータの埋め込みというのは、以下の部分でしょうか?
<form method="GET" action="./done.php"> <?php //次の登録完了画面へ飛ばす print "<p>入力はこれでよろしいですか?</p>"; print "<p>名称:$name</p>"; print "<p>フリガナ:$kana</p>"; print "<p>メモ:$memo</p>"; print "<p>更新日時:$dt</p>"; print "<p>更新者:$registrar</p>"; print "<p>登録日時:$dt</p>"; print "<p>登録者:$update</p>"; print "<p>並び順:$sq</p>"; ?> <input type="hidden" name="name" > <input type="hidden" name="kana" > <input type="hidden" name="memo" > <input type="hidden" name="sq" > <input type="submit" value="登録" /> <input type="button" onclick="history.back()" value="戻る" /> </form>DBのデータ重複チェックですが、テーブルでは、ユニークキーを設定してあります。
SELECTで重複するデータがないかは、調べて実装したいと思います。
今は、入力フォームから確認画面にデータを持っていき、確認画面で入力されたデータを
表示できるようにしたいのですが、例えば、名称とフリガナを入力して
確認画面に遷移してもこの2つの項目のところが空欄になってしまいます。
issetを利用し未定義なのか未定義ではないのか調べる部分で
現状のソースコードではどのように書くべきかわかりません。
$error = array(); $name = trim($_POST['name']); $len = strlen($name); if(empty($_POST['name'])|| $len == 0) { $error[] = "<p>名称は、必須項目です。</p>"; }elseif($len < 50){ $name = preg_replace('/[ ]+$/u', '', $name); $name = mb_convert_kana($name, 'K', 'UTF-8'); $name = str_replace("\t", '', $$name); $name = str_replace('"','”',$name); }else { $error[] = "<p> 名称は、50文字まで入力ok</p>"; } $kana = trim($_POST['kana']); $len = strlen($kana); if(empty($_POST['kana']) || $len == 0){ $error[] = "<p>フリガナは、必須項目です。入力して下さい。</p>"; } elseif($len < 50) { $kana = preg_replace('/[ ]+$/u', '', $kana); $kana = mb_convert_kana($kana, 'K', 'UTF-8'); $kana = str_replace("\t", '', $kana); $kana = str_replace('"','”',$kana); }else{ $error[] = "<p>フリガナは、50文字まで入力ok</p>"; } $memo = trim($_POST['memo']); $len = strlen($memo); if($len < 1000) { $memo = preg_replace('/[ ]+$/u', '', $memo); $memo = mb_convert_kana($memo, 'K', 'UTF-8'); $memo = str_replace("\t", '', $memo); $memo = str_replace('"','”',$memo); }else{ $error[] = "<p>名称は、1000文字まで入力ok</p>"; } $sq = trim($_POST['sq']); $len = strlen($sq); if($len < 50) { $sq = preg_replace('/[ ]+$/u', '', $sq); $sq = mb_convert_kana($sq, 'K', 'UTF-8'); $sq = str_replace("\t", '', $sq); $sq = str_replace('"','”',$sq); }else{ $error[] = "<p>名称は、50文字まで入力ok</p>"; } //入力チェック抜けたらconfirm.phpへリダイレクト if(!count($error)) { header("http://localhost/confirm.php"); exit(); }
}
//POSTでは無い。ここでセッション変数が未定義かチェックする
//未定義だったら初期値(空文字)を代入
if(!isset($_SESSION['name'])) {
$_SESSION['name'] = '';
}elseif(!isset($_SESSION['kana'])) {
$_SESSION['kana'] = '';
}elseif(!isset($_SESSION['memo'])) {
$_SESSION['memo'] = '';
}elseif(!isset($_SESSION['sq'])) {
$_SESSION['sq'] = '';
}
//エラーだったときのメッセージを表示
if(count($error)) {
foreach ($error as $message) {
print($message);
}
}
?>
<h1>登録フォーム</h1>
</body> </html><div id="form"> <form method="POST" action="<?=basename(FILE)?>"> <p> 名称(必須)<br/> <input type="text" name="name" value="<?=$name?>"> </p> <p> フリガナ(必須)<br/> <input type="text" name="kana" value="<?=$kana?>"> </p> <p> メモ<br/> <textarea name="memo" cols="80" rows="4" value="<?=$memo?>"></textarea> </p> <p> 並び順<br/> <input type="text" name="sq" value="<?=$sq?>"> </p> <p> <input type="submit" value="確認" /> <input type="reset" value="リセット" /> </p> </form> </div> </div>
inform.phpでsq,memoのセッション代入部分を修正して、入力チェックのエラー部分を
bodyの中に記述しました。
他のphpファイルは、まだ触ってないです。
宜しくお願い致します。
投稿2014/11/01 17:00
総合スコア12
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
あくまで一例ですが、以下のようにするといいと思います。
inform.phpですが、まず、最初に、
POSTの場合に、セッション変数にPOSTパラメータを代入し、
POSTでない場合に、セッション変数が未定義の場合にセッション変数に初期値(空文字列)を代入してください。ここで未定義のものがあった場合は初期アクセスと判断し、入力チェックはスルーしてください。
その後、入力チェックを行ってください。
入力チェックで問題がなければconfirm.phpにリダイレクトしてください。$error
にエラー内容を入れていると思いますが、count($error)
で入力エラー有無が判別できると思います。
初期アクセスと入力エラーはそのままフォームを表示します。
confirm.phpでは、POSTパラメータは来ないので、セッション変数をエスケープして画面を表示するだけです。
done.phpでは元々エスケープしていたはずです。bindValue
でエスケープされます。HTMLのエスケープとは異なります。htmlspecialchars
などは使用してはいけません。ただし、何か画面に表示する場合は別途必要になります。
ここもconfirm.phpと同様に、POSTパラメータは来ないので、セッション変数を使用します。
なお、同じセッション変数に代入しているようです。これでは後のもので上書きされてしまうので、パラメータごとに別のセッション変数に代入する必要があります。連想配列にして1つのセッション変数に入れる方法もあります。
投稿2014/10/21 00:28
総合スコア1356
0
ご回答ありがとうございます。
done.phpは、以下のようになっています。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>登録完了画面</title> </head> <body> <?php//DBの設定情報 require_once realpath(__DIR__) . 'DbManager.php';
//DB命令
try {
$dt = date('Y-m-d H:i:m'); $db = getDb(); $registrar = "administrator"; $update = "administrator"; $stt = $db->prepare('INSERT INTO カテゴリ(`ID`,`名称`,`カナ`,`メモ`,`登録日時`,`登録者`,`更新日時`,`更新者`,`並び順`) VALUES(NULL,:name, :kana, :memo,:datetime,:registrar, :datetime, :update, :sq)'); $stt->bindValue(':name', $_POST['name']); $stt->bindValue(':furigana', $_POST['kana']); $stt->bindValue(':memo', $_POST['memo']); $stt->bindValue(':datetime', $dt); $stt->bindValue(':registrar', $registrar); $stt->bindValue(':datetime', $dt); $stt->bindValue(':update', $update); $stt->bindValue(':alignment_sq', $_POST['sq']); $stt->execute(); if($stt->rowCount() > 0) { header('Location:http://localhost/php/inform.php'); exit(); }else{ echo "重複してるから登録できません。"; } $db = NULL;
//例外処理のエラー時の処理
} catch(PDOException $e) {
die("エラーメッセージ:{$e->getMessage()}");
}
?>
view.phpは、以下のようになっております。
<?php //DB接続情報 require_once realpath(__DIR__) . 'DbManager.php'; ?> <html> <head> <title>カテゴリテーブル中身表示</title> <h1>カテゴリ中身表示</h1> </head> <body> <table border="1"> <tr> <th>ID</th><th>名称</th><th>カナ</th><th>メモ</th><th>登録日時</th><th>登録者</th><th>更新日時</th><th>更新者</th><th>並び順</th> </tr> <?phptry {
//DBへの接続の確率
$db = getDb();
//SELECT命令の実行
$stt = $db->prepare('SELECT * FROM カテゴリ');
$stt->execute();
//結果セットの内容を順に出力 while($row = $stt->fetch(PDO::FETCH_ASSOC)) {
?>
<tr>
<td><?php e($row[ID]); ?></td>
<td><?php e($row[名称]); ?></td>
<td><?php e($row[カナ]); ?></td>
<td><?php e($row[メモ]); ?></td>
<td><?php e($row[登録日時]); ?></td>
<td><?php e($row[登録者]); ?></td>
<td><?php e($row[更新日時]); ?></td>
<td><?php e($row[更新者]); ?></td>
<td><?php e($row[並び順]); ?></td>
<?php } $db = NULL; }catch(PDOException $e) { die("エラーメッセージ: ($e->getMessage()}"); } ?> </table> </body> </html></tr>
セッションについてですが、BODYタグより上に記述したり修正をしてみます。
宜しくお願い致します。
投稿2014/10/11 03:06
総合スコア12
0
セッション変数への格納をするところと、参照するところがつながっていないと思います。
confirm.phpからの遷移先はdone.phpとなっているようですが、このソースはどうなっているでしょうか?
inform.phpでconfirm.phpへのリダイレクトをしているようですが、この時はまだセッション変数への格納をしていないようなので、POSTされたパラメータは消えてしまいます。confirm.phpには何のデータも送られないと思います。
あと別の問題として、session_startはHTTPボディの出力より前にないと動かないと思います。
具体的に言うとconfirm.phpでsession_startより前にHTMLを出力しているので、セッションが消えてしまうと思います。
セッション変数への格納時も、エスケープしてしまうと後の処理で困るのではないかと思います。
投稿2014/10/09 22:13
総合スコア1356
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2014/10/12 07:01
2014/10/15 11:20
2014/10/15 12:13
2014/10/15 12:22
2014/10/19 14:30
2014/10/20 07:40
2014/10/20 07:49
2014/10/20 07:51
2014/10/20 15:20
2014/10/21 00:54
2014/10/22 13:54
2014/10/22 14:01
2014/10/22 14:26
2014/10/24 07:32
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。