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

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

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

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

Q&A

4回答

182閲覧

掲示板、コメントの際のエラーの回避の仕方を知りたい!

aiued

総合スコア5

PHP

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

0グッド

0クリップ

投稿2020/01/15 03:40

編集2020/01/15 03:42

前提・実現したいこと

簡単な掲示板を作成したいと思っており、コメント、削除フォームを作りたいと思っています。また、削除の際例えば

1 番号 名前 コメント…
2 番号 名前 コメント
3 
4
....

と並んでいて、2を消したとする。そして次にコメントするときは

1 番号
3
4
5

となるようにしたいです。
(つまり、1 3 4 4という番号の振り分けにならないようにしたいです)

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

Notice: Only variables should be passed by reference in /public_html/rensyuuyou.php on line 42 Notice: A non well formed numeric value encountered in /public_html/rensyuuyou.php on line 42

一番最初のコメントが上手くいきません、

1///時間 /
2/名前/コメント/時間/

となる(2以降はちゃんと表示できます)

また、上記のエラー文がずっと表示されてしまいます。

該当のソースコード

<meta charset="utf-8"> </head> <body> <form method="post" action="rensyuuyou.php"> <input type="text" name="name" placeholder="名前"> <br> <input type="text" name="comment" placeholder="コメント"> <input type="submit"> <br> </form> <form method="post" action="rensyuuyou.php"> <input type="text" name="deleteNo" placeholder="削除番号" > <input type="submit" name="delete"value="削除"> </form> <br> <?php $filename = "rensyuuyou.txt"; //コメント欄が空でない場合条件分岐 if( !empty($_POST["comment"])) { if(file_exists($filename)){ $name = $_POST["name"]; $comment = $_POST["comment"]; $count=end(file($filename))+1; }else{ $count = 1; } $date = date("Y年m月d日 h時i分"); //まとめました、これで番号名前~の情報がある。 $NewData=$count."<>".$name."<>".$comment."<>".$date."\n"; //テキストファイルに書き込み! $fp = fopen($filename, "a"); fwrite($fp, "$NewData"); fclose($fp); //新しい定義ブラウザ表示のための } //条件分岐、削除番号入力 if(isset($_POST["deleteNo"])) { $delete = $_POST["deleteNo"]; $delCon = file($filename); //新しい定義付け echo "削除しました。"."<br>"; $fp=fopen($filename,"w"); for($i= 0; $i<count($delCon); $i++){ //ループ処理 $delfile = explode("<>", $delCon[$i]); //定義付け if($delfile[0]!= $delete) { fwrite($fp,$delCon[$i]); } } fclose($fp); } if(file_exists($filename)){ $lines = file($filename); //ループ処理。 foreach($lines as $line){ //表示! $hyouzi = explode("<>", $line); echo $hyouzi[0]."/".$hyouzi[1]."/".$hyouzi[2]."/".$hyouzi[3]."/"."<br>"; } } ?> </body> </html>

試したこと

元々数のカウントを $count = count(file($filename))+1; を使っていて。それだと指定番号を削除した後にコメントすると番号が重複してしまうのでendに変えたところ問題が発生しました。また、最初の方ですとエラー文は出ません。1番目のコメントもしっかり表示されます。

テキストの行数の総数+1($count = count(file($filename))+1)から、最後の番号を取得し+1するべきだというのは分かっているのですが。ここからどう直すべきなのか、わからない為アドバイス頂けないかと質問致しました。どうぞよろしくお願いいたします。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

m.ts10806

2020/01/15 03:45

前の質問に懸念点として書いておいたことが今回そのまま現れてますが、そのあたりは考慮してみました? 正直なところ、テキストでデータを管理するアプリケーションをいくら頑張ってもほとんど実務で活きないので早いところデータベースに移行した方が良いと思うのですけど。
aiued

2020/01/15 03:51

データベースのことですよね…?すみません、勉強するにあたってまずはテキストベースでやり方を覚えて進めるのが良いのではないのかと勝手に思っていました。うまく理解していなくてごめんなさい!ちゃんと調べてみます。ご指摘、感謝致します…!
m.ts10806

2020/01/15 03:53

あと、せっかく、IDE入れたのですからコードフォーマット機能使いましょう。 かっこの対応付けがめちゃくちゃなのでバグの温床になりえます。
aiued

2020/01/15 04:01

IDEの使い方もまだ把握できていませんでしたが、今後使いこなせていた方が良いので。これをきっかけに頑張って使い方調べてみます…!アドバイス、とても助かります。
m.ts10806

2020/01/15 04:08

どのIDEを入れられたのかにもよります。さっと使えるのはEclipseですね。ツールの設計が古めなのと初めからたくさん機能が入っているので動作が重たいのはありますが。
guest

回答4

0

php

1<?php 2 $next_num = 1; 3 if (file_exists($filename)) { 4 $lines = file($filename); 5 foreach ($lines as $row) { 6 $item = explode("<>", $row); 7 if ($next_num < $item[0]) { 8 $next_num = $item[0]; 9 } 10 } 11 $next_num++; 12 }

こういうことなんじゃないかなと、さらっと書いてみた。

掲示板データの番号を保持しているカラムが$item[0]なら、
それの最大値を求めて、+1して使えばいいってこと。

別なやり方として、「削除した番号を永久に再利用しない」のであれば、
発番専用のデータファイルを別途持って、
採番するたびに+1して記録してから使うという。

ただし、これも気になる点があって、
新しい投稿番号が決まってからファイルに記録するまでの間、
同時アクセスが発生したりすると番号がかぶる可能性があるので、
ファイルの排他ロックを駆使して
一連の処理(採番して記録する)の間に他の処理を差し止めることも必要。
そんなの、適当にネットで事例を探せば見つかりそうだから自分で調べてみてほしい。

同時アクセスは、例えばパソコン2台やパソコンとスマホを並べて、
同じページを開いて、一斉に送信すればどうなるかって試せるので、
説明を聞くよりも先にやってみるといいよ。

他にもファイル破損しそうな話として、
投稿データにデータファイル上のデリミタ「<>」が含まれていたらどうするかとか。
説明を聞くよりも先にやってみるといいよ。

で、テキストファイルをデータファイルにして作り込むシステムなんて今どき無いので、
そこの処理方法をどんなに頑張っても、
エンジニア同士の「そういえばそういうこともやったっけなー」くらいの話題にしかならないので、
RDBMS(いわゆるデータベース)の使い方を覚える方に時間を割くべきだと進言したいです。
発番の管理をデータベースに任せたり、排他ロックのようなことも割とわかりやすくて。

投稿2020/01/15 03:57

編集2020/01/15 04:12
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

tanat

2020/01/15 04:00

最後の行が削除されちゃった場合に、最後の行の番号が再利用されちゃわないです?
退会済みユーザー

退会済みユーザー

2020/01/15 04:03

仕様をどう捉えるか次第ですな。データファイル上にかぶらなきゃいいって考えもあるし、削除した番号は永久に再利用しないって考え方もあるし。
tanat

2020/01/15 04:10

ああ、なるほど。 確かに質問からだと番号が被らない事だけが要件の様にも見えますね。
guest

0

DBに移行するのが一番です。
PHPからテキストを扱うことはないことはないですが、今回のような考慮が大量に必要なデータの読み書きではないように思います。

DBに敷居の高さを感じているのならその考えは改めた方が良いと思います。自身でテキストで管理するよりも簡潔な記述で読み書きできるようになります。
外部の仕組みなのでそこは「SQL」という別の言語を覚える必要はありますが、実務においてはほぼ発生するので初めから覚えるつもりでPHPを学習しましょう。

もし何がなんでもテキストでデータ管理をすすめる書籍やスクールを利用しているのでしたら今すぐ切りましょう。今回のようなことで悩んでいる時間の無駄になります。

で、なくても
IDのように「一意となるもの」に対して「MAX+1」で取るのは悪手です。
12345

5を削除

1234

新しく登録

12345

果たしてこれで良いのか?
IDであれば12346となるのが正しいと思いませんか?
なくなったから詰めるということはありえません。

これを実現するには「シーケンス管理」が必要です。要は「現在の番号」を管理しておく別のテーブルが必要ということですね。
データベースにおいてはそのシーケンスを取得、付与(管理)する機能がはじめからあります。
テキストの場合は自分で作る必要があります。

投稿2020/01/15 04:04

m.ts10806

総合スコア80850

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

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

0

PHP 7.0.x から PHP 7.1.x への移行

Notice: A non well formed numeric value encountered in %s on line %d

無効な文字列による算術演算の通知

数値形式ではない文字列を使って、数値を期待する演算 (+ - * / ** % << >> | & ^ や、これらを用いた代入演算) を行おうとしたときに、 E_WARNING あるいは E_NOTICE レベルのエラーが発生するようになりました。 E_NOTICE が発生するのは、文字列が数値で始まっていながら非数値で終わる場合で、 E_WARNING が発生するのは文字列中に数値が含まれない場合です。

比較的新しい php で実装された通知ですね。
上記の通り、文字列を演算しようとして怒られています。
該当箇所を適切に数値にしてやると良いです。

キャストとか型変換とキーワードで

投稿2020/01/15 03:47

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/01/15 03:48

新しくもないかw
aiued

2020/01/15 03:56

なるほど…わかりやすい…!ありがとうございます!つまりちゃんと計算できるものを用意しろってことですよね…、コード見直します!
guest

0

いくつか方法がありますが、

ぱっと思いつく範囲で簡単なのは
0. 削除する際に実際に削除するのではなく、削除済みを示すデータを追記しておいて、
表示するときにそのデータがあった場合は無いものとして扱う
0. 掲示板データとは別のファイルに最終行の番号を記録しておいて、データを追記するときはその番号+1で採番し、その後別ファイルの番号も更新する

のどちらかなと思います。


元も子も無い話になりますが、ファイルベースの簡易掲示板でこの辺りを苦労するのはあんまりお勧め出来ないというか、PHPに慣れるくらいの効能しかありません。(独自形式のファイルをデータベースの代替として使う事って、業務でも趣味でもほぼ無いケースです。)

機能的に物足りなくなってきたのであれば、RDBMS(MySQLやPostgreSQL等)を使った掲示板を作ってみることをお勧めします。(多くのRDBMSではこの質問で悩んでいるようなことがRDBMSの機能として提供されます)

投稿2020/01/15 03:50

編集2020/01/15 04:01
tanat

総合スコア18713

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

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

aiued

2020/01/15 04:03

ありがとうございます!勉強不足でした、アドバイスとてもありがたいです。 つまり、他の方にもご指摘頂きました通りデータベースというのを使ってやってみるのが良いということでしょうか…?調べてみます。
tanat

2020/01/15 04:09

そうですね。 PHP+MySQLでシステムを構築するような入門書籍(出来るだけ新しいもの)やweb教材を探してみるのが良いかと思いますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問