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

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

ただいまの
回答率

87.95%

変数にゴミが入っているということに関する質問

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 163

score 7

今回とあるコードでプログラムを作りました。いわば掲示板のようなもので
'edit_post'という変数が空かどうかということでif文を用いて場合分けを行っております。
今回、$edit =  '';
という$editに空の初期値を与えましたが、今回この初期値がない場合条件分岐が
if(empty($_POST ['edit_post' ]))
ではなくelseのほうに行ってしまいます。調べたところ変数には定義しないとゴミのようなものが入ることがあると書いてあり、原因はこれかもと予想しました。そのため下のほうにあるhtmlの
<input type="hidden" name="edit_post" value="<?php echo $edit; ?>">
で$editになにかゴミのようようなものがあるため"edit_postが値を持ってしまったのかもしれないと考えました。そこでお聞きしたいのは僕の予測は正しいのかということです。もしも違っていた場合はどうしてこうのように空の初期値を与えないとしたのelseに条件分岐してしまうのかも教えていただきたいです。
初心者故、丁寧に解説していただけると幸いです。

<?php
    $filename = "kadai_2_1.txt";
    $editName = '';
    $editComment = '';
    $edit =  '';

    if(isset($_POST[ 'name' ])&&isset($_POST[ 'opinion' ])){
        $name = $_POST[ 'name' ];
        $opinion = $_POST[ 'opinion' ];
        $date = date('Y-m-d H:i:s');





        if(empty($_POST ['edit_post' ])){

            $fp = fopen($filename,"a");
            $fileLaw = file($filename, FILE_IGNORE_NEW_LINES);
            if(count($fileLaw)==0){

                $numSecond = 1;
            }else{
                $line = end($fileLaw);
                $lastNum = explode("<>", $line);
                $numSecond = $lastNum[0]+1;

            }

        fwrite($fp,$numSecond."<>".$name."<>".$opinion."<>".$date."\n");
        fclose($fp);
        }else{
            $fileLaw = file($filename, FILE_IGNORE_NEW_LINES);
            $fp = fopen($filename,"w");
            $editNum = $_POST[ 'edit_post' ];
            for($i = 0; $i < count($fileLaw); $i++){
                $line = explode("<>",$fileLaw[$i]);
                if($editNum == $line[0]){
                    fwrite($fp,$editNum."<>".$name."<>".$opinion."<>".$date."\n");
                }else{
                fwrite($fp,$fileLaw[$i]."\n"); 
                }

                }fclose($fp); 
            }   
    }   

    if(isset($_POST[ 'delete' ])){
        $delete = $_POST[ 'delete' ];
        $fileLaw = file($filename, FILE_IGNORE_NEW_LINES);
        $fp = fopen($filename,"w");

        for($n = 0; $n < count($fileLaw); $n++){
            $line = explode("<>",$fileLaw[$n]);
            $leadNumber =  $line[0];
            if($leadNumber != $delete){

                fwrite($fp,$line[0]."<>".$line[1]."<>".$line[2]."<>".$line[3]."\n");

            }
        }
        fclose($fp);
    }
    if(isset($_POST[ 'edit' ])){
        $edit = $_POST[ 'edit' ];
        $fileLaw = file($filename, FILE_IGNORE_NEW_LINES);
        for($n = 0; $n < count($fileLaw); $n++){
            $line = explode("<>",$fileLaw[$n]);
            $leadNumber =  $line[0];
            if($leadNumber == $edit){
                $editName = $line[1];
                $editComment = $line[2];
            }
        }
    }






?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="" method="POST">
<input type="hidden" name="edit_post" value="<?php echo $edit; ?>">
<p>お名前:
<input type="text" name="name" value="<?php echo $editName; ?>">
</p>
<p>コメント:</p>
<p><textarea name="opinion" cols="50" rows="5"><?php echo $editComment; ?></textarea></p>
<p><input type="submit" name="submitBtn" value="送信"></p>
</form>
<form action="" method="POST">
<p>削除したい番号を指定:</p>
<p><input type="text" name="delete">
<input type ="submit" name="deleteBtn" value="削除"></p>
</form>
</body>
</html>
<form action="" method="POST">
<p>編集したい番号を指定:</p>
<p><input type="text" name="edit">
<input type ="submit" name="editBtn" value="編集"></p>
</form>
<p>以下コメント</p>
<?php
    if(file_exists($filename)){


    $fp = fopen($filename, 'r');
    while (!feof($fp)) {
    $txt = fgets($fp);
    echo $txt.'<br>';
    }          
    }
?>
</body>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2021/06/10 18:35

    var_dumpで確認すればわかることでは?
    「ゴミのようなものが入る」とは何を読みましたか?
    出典明示してください

    キャンセル

  • yohu_gakusei

    2021/06/10 18:53

    返信ありがとうございます。https://ja.wikipedia.org/wiki/%E3%81%94%E3%81%BF_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)
    以下のwikipediaから参照しました。

    キャンセル

  • m.ts10806

    2021/06/10 19:23

    質問編集して本文に追記願います

    キャンセル

回答 1

checkベストアンサー

+3

PHP: empty - Manual
PHP isset, empty, is_null の違い早見表 - Qiita

empty()で判断するの、危険なんだよ。
0が入っていても、''(文字列長ゼロの文字列)が入っていてもemptyとみなされてtrueになっちゃう。

それと、もしも、複数行入力できるtextareaで入力させている時、
改行を含む文字列を受信した時、
そのままデータファイルに出力しちゃうと、
改行コードでデータが途切れてしまうので、
それでデータファイルを破壊するって話はある。

ファイル上、

数字<>名前<>意見<>日付
数字<>名前<>意見<>日付
数字<>名前<>意見<>日付
数字<>名前<>意見<>日付

ってなるのが、

数字<>名前<>意見<>日付
数字<>名前<>意
見<>日付
数字<>名前<>意見<>日付
数字<>名前<>意見<>日付

みたいになる。

そういうときは、改行コードを含むか検査して、別の差し支えない文字に置き換えて使ったりする。
改行コードは、\x0d(CR)や\x0a(LF)あるいは\x0d\x0a(CRLF)など、webブラウザを実行している環境によってコードが変わる可能性もあるので、
それらを含む場合に置き換えるような関数を加える。

PHPで改行コードを統一する関数: CRLF, CR, LF が混在してる文字列を LF に変換するなど - Qiita
↑ この記事で紹介されている、function convertEOL()など参考にして、

$opinion = preg_replace("/\r\n|\r|\n/", '<LF>', $opinion);

とすることで一旦改行コードが無効化されるので、
保存する処理に加えるといいかも。

戻すときは

$opinion = str_replace('<LF>', PHP_EOL, $opinion);

とすることで(PHPを実行している環境に合わせた)改行コードに変わります。
これなら、必ずデータが1行分に収まります。

もう一つ別の手があって、
1行分読み込んで、データ区切りの「<>」で分解したときの個数を判定し、
足りなければ次の1行も読み込んで改行文字を加えたうえで連結します。
ファイルからの読み込み処理が少し煩雑になりますけど、やれない話ではないです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/06/10 18:51

    返信ありがとうございます。なら今回は!issetを用いればうまくいったということでしょうか?

    キャンセル

  • 2021/06/10 18:52

    加筆した方の内容が、根本原因だと思うので、もう一度ご確認を。

    キャンセル

  • 2021/06/10 19:07

    返信ありがとうございます。今回textareaに原因があるとは思いませんでした、確かにおっしゃる通り改行があると番号が表示されないことがわかりました、根本的な解決にはなりませんがなら今回コメントをtextareaではなく名前のフォームのように一行の入力にすればの治るということでしょうか?

    キャンセル

  • 2021/06/10 21:43

    仕様、もしくは、こういう風に作りたい、というもの次第ではないでしょうか。
    改行文字を含めて投稿を受け付けたいのであれば、
    textareaで受け付けた文字入力に含まれる改行コードをファイル保存用に一旦置き換える必要があります。
    それをやりたいかどうか、ではなく、実現したいかどうかで考えてください。

    キャンセル

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

  • ただいまの回答率 87.95%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る