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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

568閲覧

php  1つのファイルでフォーム作成と表示をする

suzu6331

総合スコア1

PHP

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2022/07/20 07:37

編集2022/07/20 10:18

前提

phpで1つのファイルでフォームを作成するプログラムを作っているのですが、表示名の下のテキストのところが表示されません

実現したいこと

フォームにメッセージを入力したら表示する

発生している問題・エラーメッセージ

特にありません

該当のソースコード

php

1<?php 2function h($input) { 3 return htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); 4} 5 6$msgs = array(); 7$text = ''; 8 9 10try{ 11 $file = new SplFileObject('hogehoge.txt', 'cb+'); 12 13 if(isset($_POST['text']) && is_string($_POST['text'])) { //初回起動時に非表示 14 $file->ftruncate(0); 15 $file->fwrite($_POST['text']); 16 } else { 17 $text = ''; 18 while (!$file->eof()) { 19 $text .= $file->fgets(); 20 } 21 } 22 23} catch (Exception $e) { 24 25 $m = 'エラー: ' . $e->getMessage(); 26 $msgs[] = '<div style="color:red;">' . h($m) .'</div>'; 27 28} 29 30/*表示*/ 31foreach ($file as $line) { 32 if ($line == false) continue; 33 echo "$line<br>", PHP_EOL; 34} 35 36$msg = implode(PHP_EOL, $msgs) . PHP_EOL; 37?> 38<!DOCTYPE html> 39<head> 40<meta charset="UTF-8" /> 41<title>サンプル</title> 42</head> 43<body> 44<?php echo $msg; ?> 45<form action="<?=basename($_SERVER['SCRIPT_NAME'])?>" method="post"> 46 47 48表示名 49<div><input type="text" name="text" rows="10" cols="30"><br> 50<?php echo h($text); ?> 51</div> 52 53一言メッセージ 54<div><textarea id="t_message" name="text1" rows="10" cols="30"> 55<?php echo h($text); ?></textarea> 56</div> 57 58<div><input type="submit" value="送信" /></div> 59</form> 60</body> 61</html> 62 63ソースコード

試したこと

・現在表示名の出力はできているのですが、一言メッセージの出力ができないです。

補足情報(FW/ツールのバージョンなど)

・テキストファイルはMeryを使用しています
・字が汚くて申し訳ないのですが出力したい形式はこんな感じです。
表示名は一行、一言メッセージは複数行入力可能なフォームです。送信を押すと表示名の上に入力した結果が表示されるようにしたいです。
イメージ説明
・ページの更新をした後送信したメッセージを消したいのですが何かやり方はありますか?

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

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

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

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

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

m.ts10806

2022/07/20 07:39

form開始が二重になってるのは意図的ですか?転記ミスですか?実際にそういうコードを書いてしまったのですか?
suzu6331

2022/07/20 07:48

おそらく <form action="<?=basename($_SERVER['SCRIPT_NAME'])?>" method="post"> のところですよね?ここは間違えて書いてしまいました。
m.ts10806

2022/07/20 07:52

質問は編集できますので、一度手元のコードを修正して確認してみてください。 formタグは入れ子にできないのでリクエストが想定の通り構成されない可能性もあります
退会済みユーザー

退会済みユーザー

2022/07/20 07:56

表示名も一言メッセージも同じ $text が使われているし、id="t_message" name="text" がダブってるし、function hとfunction h1って同じでわざわざ分ける意味がないし、コピペが過ぎる
退会済みユーザー

退会済みユーザー

2022/07/20 09:39

コードが粗雑で、そもそもどういう機能を実現したいのかを第三者が把握しづらい状況になっている。どういう入力項目を設けて、それぞれどういう入力欄にしたいのかを明記してほしい。
suzu6331

2022/07/20 10:01

多くのご指摘ありがとうございます。今内容を修正しました。 またご不明な点がありましたら、教えてください。
guest

回答1

0

ベストアンサー

要点:
1)ファイルへの書き込み処理と読み込み処理は分離しよう。
2)表示名と一言メッセージを別々に受け取れるように、name属性につける名前をユニークにしよう。
3)ファイルから読み込んだメッセージを表示するのを、もうひと工夫しよう。

1)について。

$file = new SplFileObject('hogehoge.txt', 'cb+');
は微妙。
第2パラメータのmodeについてはfopenと同じで、
「c+」だとファイルをオープンしてファイルポインターがファイルの先頭から始まってしまう。
cはcreateのcなので、この場合はappendのaを使うといい。
「a+」でアクセスした時、ファイルポインターはファイルの末尾になり追記する形になる。
ただし、書き込みしたあとに読み出しするときは、意識的にファイルポインターをファイルの先頭に移動しないといけないので、
SplFileObject::fseekで(0, SEEK_SET)とかしないとね。
それと、ファイルをオープンしたらSplFileObject::flockにて排他ロックするのを忘れずに。
同じタイミングで複数のアクセスがあるとファイルが壊れます。
また、クローズするのを忘れずに。クローズしなくてもphpの処理終わりで閉じるけれども、少しでもファイルアクセスしている時間を短くするために。

2)について。

気づいたようでtextとtext1にしてあるようだけど、
わかりやすくpost_nameとpost_msgとか、入力しやすく、見間違いも生じないものを使うことをおすすめする。
まぁ、textとtext1だとして、
表示名のところで<?php echo h($text); ?>、一言メッセージのところで<?php echo h($text); ?>ってなってるから、2箇所で同じものを表示しようとするよ。
$textって変数にどこかで初期化してあるかというと、
冒頭で$text = '';として、while()ループで詰めてるよね。
これについては後でもう一度触れる。

3)について。

ファイルへの書き込みがうまくいくようになったら、
次は書き込んだメッセージが改行もされずダラダラと横につながって表示されるはず。
while()ループでfgets()で得たものを$textに連結しているけど、
そもそもSplFileObject::fgetsってファイルに改行コードがあることが前提なんだけど、
fwrite($_POST['text']);では表示名と一言メッセージのどちらを書き込むつもりかな。
一言メッセージの方だとすると、textarea要素では「改行込み」の文字列なので、
一度の投稿分じゃなく、一度の投稿での改行までで区切られちゃう。
どっちをどう表示するのかわからなかったので、もう一度仕様を明確にして見直ししてほしい。

また、foreach()ループで$fileに対してアクセスしているけど、
$fileはSplFileObjectのインスタンスであって配列データではないのでうまくいかないはず。

最終的にどうするのかわからないけど、
ファイルに書き込むときには、書き込むデータの中にデータの区切りになる文字が含まれていないことと、
書き込むデータの末尾にデータの区切りになる文字をつけることを忘れないようにしたい。
1行コメントであれば、データの区切りは改行コードでいいので、
fwrite()するときにPHP_EOLとか改行コードを加えて書き込めばいい。
複数行テキストだとすると、受信したテキストに改行コードが含まれているので、
改行コードを含んだまま記録してしまうとデータの区切りの改行コードとの区別がつかなくなる。
fgets()では読み出しには使えない。
受信したテキストに含まれる改行コードをキーボード入力できない別の文字で置き換えてしまう方法もあるし、
改行コードを含んだまま書き込む前提で区切り方を別途工夫することもあるかもしれない。

で、htmlでは改行コードを含んだテキストをそのまま出力すると改行コードは無視されてしまうから、
<br>」を挟んで改行位置を明示するとか、
<pre>」で等幅フォントになるけど改行を踏まえた表示をさせるか。

変数名に複数形を使うときのルールを気をつけてね。
配列など複数のデータを含むときだけにしたほうがいいよ。

同じ変数名を全体で使いまわしすると、
どの時点で何のデータが入っているかわかりにくくなるから、
用途が変わるなら適宜変数名を変えること。

投稿2022/07/20 11:26

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問