🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

1783閲覧

掲示板のF5等更新時、二重投稿の防止方法について

MakotoIshizawa

総合スコア32

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2019/10/01 09:13

前回の質問した時に、編集機能をつけようとしていました。
編集機能の質問
テスト用に別のファイルを作り、ものすごく単純化したものから順にテストしていき、
編集したい投稿内容をフォームに入力済みで表示させる事が出来ました。

ただ、二重投稿防止のために書いたheader関数があるとvar_dumpで
$ret_array
$Hname
$hensyuNO
を見るとNULLになってしまいます。
どうしてなのかちゃんと理解できないまま、header関数を消すと、うまく表示されました。
(テスト時header関数は使ってなくて最後に足すと、それまで正常だった表示ができなくなりました)
header関数はなくして他の方法で二重投稿を防止したほうが良いのでしょうか。
それとも、header関数のままでも動作させる方法があるのでしょうか。
以下の記事を試そうと思っていますが、header関数でも出来るならそのまま使いたいです。
https://tenderfeel.xsrv.jp/php/412/

コードは以下です。(PHP5.2.4)

php

1<?php 2/*もしポストで送信されたら以下の処理を行いGET送信でリダイレクトする(更新時の二重書き込み防止)*/ 3if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) { /*もしPOSTで送信されたら*/ 4 5 /*フォームで送信された値を受け取り、テキストファイルに保存する。 6 その際1行ごとに「{番号}<>{名前}<>{コメント}<>{投稿された時間}」と言う形で保存する*/ 7 //変数の定義 8 $filename = "keijiban.txt"; /*保存するファイル*/ 9 $name = $_POST[ 'name' ]; /*投稿者の名前*/ 10 $comment = $_POST[ 'comment' ]; /*投稿するコメント*/ 11 $date = date( "Y-m-d H:i" ); /*投稿日時*/ 12 $search = array( "\r\n", "\r", "\n", "<>" ); //置き換え時の検索文字 13 $replace = array( "<<改行>>", "<<改行>>", "<<改行>>", "&lt;&gt;" ); //置き換える文字 14 $deleteNO = $_POST[ 'deleteNO' ]; //削除番号の変数定義 15 16 17 //投稿番号の定義 18 if ( is_file( $filename ) ) { /*ファイルの存在確認。*/ 19 //最後の行にプラス1 20 $ret_array = file( $filename ); 21 $lastline = $ret_array[ count( $ret_array ) - 1 ]; 22 $num = explode( '<>', $lastline ); 23 $lastnum = $num[ 0 ] + 1; 24 } else { /*ファイルが無かった場合変数の定義を1とする*/ 25 $lastnum = 1; 26 } 27 28 //書き込み内容 29 $hozon = $lastnum . "<>" . str_replace( $search, $replace, $name ) . "<>" . str_replace( $search, $replace, $comment ) . "<>" . $date . "\n"; 30 31 //投稿部分 32 if ( !empty( $name ) && !empty( $comment ) ) { /*もし名前とコメントが送信されたら*/ 33 $fp = fopen( $filename, "a" ); /*追記モードでファイルを開く*/ 34 if ( flock( $fp, LOCK_EX ) ) { /*ロックする*/ 35 fwrite( $fp, $hozon ); /*指定したファイルに追記モードで書き込み*/ 36 } 37 flock( $fp, LOCK_UN ); 38 fclose( $fp ); 39 } 40 41 //削除部分 42 if ( !empty( $deleteNO ) ) { //もし、削除番号がポスト送信されたら 43 $ret_array = file( $filename ); //ファイルを配列として読み込む 44 $fp = fopen( $filename, "w" ); 45 if ( flock( $fp, LOCK_EX ) ) { 46 foreach ( $ret_array as $value ) { //ループ 47 $bangou = explode( "<>", $value ); //<>で分割し投稿番号取り出す 48 if ( $deleteNO !== $bangou[ 0 ] ) { //もし読み込んだ番号と送信した番号が違ったら 49 fwrite( $fp, $value ); //ファイルに書き込む 50 } 51 } 52 } 53 flock( $fp, LOCK_UN ); //ロック開放 54 fclose( $fp ); 55 } 56 57 //編集部分 58$filename = "keijiban.txt"; 59$hensyuNO = $_POST[ 'hensyuNO' ]; //編集番号の定義 60if ( !empty( $hensyuNO ) ) { //もし編集用の番号が送信されたら 61 $ret_array = file( $filename ); //ファイルを配列として読み込む 62 foreach ( $ret_array as $value ) { //ループ 63 $bangou = explode( "<>", $value ); //<>で分割し投稿番号取り出す 64 if ( $hensyuNO == $bangou[ 0 ] ) { //送信と書き込みの番号が同じなら 65 $Hno = $bangou[ 0 ]; 66 $Hname = $bangou[ 1 ]; 67 $Hcomment = $bangou[ 2 ]; 68 $Hdate = $bangou[ 3 ]; 69 } 70 } 71} 72 header( 'Location: keijiban.php',true, 303 ); 73 exit; 74} 75?> 76<!doctype html> 77<html lang="ja"> 78<head> 79<meta charset="utf-8"> 80<title>簡易掲示板</title> 81<script> 82window.addEventListener('DOMContentLoaded', function(){ 83 document.querySelector('#delbtn').addEventListener('click',function(e){ 84 if(!confirm('本当に削除しますか?')){ 85 alert('キャンセルされました'); 86 e.preventDefault(); 87 } 88 }); 89}); 90</script> 91</head> 92 93<body> 94 <?php 95var_dump( $ret_array ); 96echo "<br>\n"; 97var_dump( $Hname ); 98echo "<br>\n"; 99var_dump( $hensyuNO ); 100echo "<br>\n"; 101?> 102<!--投稿フォーム--> 103<form method="post" > 104 <label for="name-field">お名前<span style="color: red;">【必須】</span><br> 105 </label> 106 <input type="text" name="name" id="name-field" required="required" value="<?php echo $Hname; ?>"> 107 <label for="comment">コメント<span style="color: red;">【必須】</span></label> 108 <br> 109 <textarea name="comment" cols="30" rows="3" id="comment" required="required"><?php 110 echo $Hcomment; 111 ?> 112</textarea> 113 <input type="submit" value="投稿"> 114</form> 115<!--削除番号指定用フォーム--> 116<form method="post" name="sakujo"> 117 <label for="deleteNO" >削除対象番号</label> 118 <input type="text" name="deleteNO" id="deleteNO" > 119 <input name="btn" type="submit" value="削除" id="delbtn"                                                                                                                                                                                                                                                                > 120</form> 121 122<!--編集番号指定用フォーム--> 123<form method="post"> 124 <label for="hensyuNO" >編集対象番号</label> 125 <input type="text" name="hensyuNO" > 126 <input type="submit" value="編集"                                                                > 127</form> 128<?php 129$filename = "keijiban.txt"; 130$search = array( "<<改行>>", "&lt;&gt;" ); //置き換え時の検索文字 131$replace = array( "<br>", "<>" ); //置き換える文字 132 133if ( is_file( $filename ) ) { //ファイルの存在確認 134 $ret_array = file( $filename ); //配列として読み込む 135 if ( empty( $ret_array ) === false ) { //配列があれば 136 foreach ( $ret_array as $value ) { //ループ 137 $bunkatu = explode( "<>", $value ); //<>で分割する 138 foreach ( $bunkatu as $value2 ) { //ループ 139 echo str_replace( $search, $replace, $value2 ) . "<br>\n"; //投稿内容を表示(<<改行>>と&lt;&gt;を<br>と<>に置き換える) 140 } 141 } 142 } else { //配列がなければ 143 echo "まだ投稿はありません"; //「まだ投稿がありません」と表示させる 144 } 145} else { //ファイルが存在しなければ 146 echo "まだ投稿はありません"; //「まだ投稿がありません」と表示させる 147} 148?> 149</body> 150</html> 151 152

テストで使用したものは以下です。

php

1<?php 2 3if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) { //もしPOSTで送信されたら 4 5 //編集部分 6 $filename = "keijiban.txt"; 7 $hensyuNO = $_POST[ 'hensyuNO' ]; //編集番号の定義 8 if ( !empty( $hensyuNO ) ) { //もし編集用の番号が送信されたら 9 $ret_array = file( $filename ); //ファイルを配列として読み込む 10 foreach ( $ret_array as $value ) { //ループ 11 $bangou = explode( "<>", $value ); //<>で分割し投稿番号取り出す 12 if ( $hensyuNO == $bangou[ 0 ] ) { //送信と書き込みの番号が同じなら 13 $Hno = $bangou[ 0 ]; 14 $Hname = $bangou[ 1 ]; 15 $Hcomment = $bangou[ 2 ]; 16 $Hdate = $bangou[ 3 ]; 17 } 18 } 19 } 20 21 header( 'Location: tesuto.php', true, 303 ); 22 exit; 23} 24?> 25<!doctype html> 26<html> 27<head> 28<meta charset="utf-8"> 29<title>テスト</title> 30</head> 31 32<body> 33<?php 34var_dump( $ret_array ); 35echo "<br>\n"; 36var_dump( $Hname ); 37echo "<br>\n"; 38var_dump( $hensyuNO ); 39echo "<br>\n"; 40 ?> 41<form method="post" > 42 <label for="name-field">お名前<span style="color: red;">【必須】</span><br> 43 </label> 44 <input type="text" name="name" id="name-field" required="required" value="<?php echo $Hname;?>"> 45 <label for="comment"> コメント<span style="color: red;">【必須】</span> </label> 46 <br> 47 <textarea name="comment" cols="30" rows="3" id="comment" required="required"><?php 48 echo $Hcomment; 49 ?> 50</textarea> 51 <input type="submit" value="投稿"> 52</form> 53<form method="post"> 54 <label for="hensyuNO" >編集対象番号</label> 55 <input type="text" name="hensyuNO" > 56 <input type="submit" value="編集"> 57</form> 58</body> 59</html>

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

流れ的にはこんな感じで処理して下さい

PHP

1<?PHP 2session_start(); 3$hoge=filter_input(INPUT_POST,"hoge"); 4if(!is_null($hoge)){ 5 $_SESSION["hoge"]=$hoge; 6 header('Location:'.$_SERVER['SCRIPT_NAME']); 7 exit; 8}else{ 9 $hoge=isset($_SESSION["hoge"])?$_SESSION["hoge"]:null; 10} 11var_dump($hoge); 12?> 13<form method="post"> 14<input type="text" name="hoge" value="123"> 15<input type="submit"> 16</form>

投稿2019/10/01 09:46

yambejp

総合スコア116661

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MakotoIshizawa

2019/10/01 10:05 編集

ありがとうございます。 今丁度Sessionについて調べていまして試したところ失敗していました。 これから教えていただいたものを試し、細かく理解していきたいと思います。 今日は時間がなくなってしまいました。 明日試してみます。 ありがとうございました。
MakotoIshizawa

2019/10/02 09:54 編集

新たにテスト用にファイルを作って、教えていただいたコードをコピペし効果を確かめました。 次に、変数名を変えて正しく動くことを確認。 次に、ファイル名も変数に加え、ループと番号の取り出しをして確認。 やりたいことは一応できましたがなぜか、$ret_arrayと$bangouがnullになってしましました。 どうしてかわかりますでしょうか?
yambejp

2019/10/02 09:46

ソースは質問文に追記されることをおすすめします
MakotoIshizawa

2019/10/02 09:55 編集

その後元のコードに組み込んで効果を見てみました。 なぜかテスト用の方で送信した番号の名前とコメントが表示されてしまいました。 そしてvar_dumpした変数の中身はテスト用で送信されたものが表示され$bangouのみnullでした
MakotoIshizawa

2019/10/02 10:03

文字が多すぎるということなので新たに質問します
MakotoIshizawa

2019/10/03 04:07

一応、教えていただいたコード自体で成功し、編集機能だけ取り出し、試して成功したのでベストアンサーにしておきます。 元のファイルでの組み込みは次回の質問に引き継ぎます。 いつも助けて頂きありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問