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

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

ただいまの
回答率

90.35%

  • PHP

    21239questions

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

  • 正規表現

    829questions

    正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

自作掲示板に正規表現の削除機能を実装したい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 272

naberius

score 3

自作掲示板に投稿番号とパスワードを入力して投稿を削除できる機能を実装しようとしたのですがファイル内から投稿番号とパスワードを検索するところが上手くいきません。
ゴールはファイルの中からPOSTされた投稿番号とパスワードに一致する行を探して空白を挿入して削除することです。
現象としてはエラー文は出ず投稿番号欄とパスワード欄の文字が消えて他は何も変わらないといった状態です。
正規表現を使っているんですがどなたか助言をお願いします。
機能のところだけ載せようかと思ったのですが全体があった方がいいかと思い載せました。見づらくてすみません。

<?php
ini_set('display_errors', 1);
//アクセスカウンターの部分
$filename = 'counter.dat';

$fp1 = fopen($filename, "r+");
flock($fp1,LOCK_EX);
$count = fgets($fp1,32);
$count++;
fseek($fp1, 0);
fputs($fp1, $count);
flock($fp1, LOCK_UN);
fclose($fp1);
//ここまでアクセスカウンター

//定義系
$err_msg1 = "";
$err_msg2 = "";
$err_msg3 = "";
$message = "";
$name = (isset($_POST["name"]) === TRUE) ?$_POST["name"]:"";
$comment = (isset($_POST["comment"]) === TRUE) ?trim($_POST["comment"]):"";
$_POST["date"] = date('Y/m/d H:i:s');
$color = isset($_POST["color"]) ? $_POST["color"] : '';
$password = (isset($_POST["password"]) === TRUE) ?trim($_POST["password"]):"";

//ここまで定義系


//入力の判定と書き込み
if(isset($_POST["send"]) === TRUE){
  if($name === "")$err_msg1 = '名前を入力してください';

  if($comment === "")$err_msg2 = 'コメントを入力してください';

  if($password === "" || mb_strlen($_POST["password"]) > 4 || !ctype_digit($_POST["password"]))
    $err_msg3 = 'パスワードを4字以下の数字で設定してください';

    if($err_msg1 === "" && $err_msg2 === "" && $err_msg3 ===""){
      $fp2 = fopen("data.txt", "a+");
      $file = file("data.txt");
      $number = count($file)+1;
      fwrite($fp2, $number."\t".$name."\t".$comment."\t".date('Y/m/d H:i:s')."\t".$color."\t".$password."\r\n");
      fclose($fp2);
        $message = '書き込みに成功しました';
      }
}
//ここまでエラー文&ファイル書き込み

//ファイル読み込み
$fp3 = fopen("data.txt", "r");

$dataArr = array();
while($res = fgets($fp3)){
    $tmp = explode("\t", $res);
    $arr = array(
        "number"=>$tmp[0],
        "name"=>$tmp[1],
        "comment"=>$tmp[2],
        "date"=>$tmp[3],
        "color"=>$tmp[4],
        "password"=>$tmp[5]
    );

    $dataArr[] = $arr;
}
//ここまでファイル読み込み

//削除機能
if(isset($_POST["delete"]) === TRUE){
  $fp4 = fopen("data.txt", "r+");
  $file = file("data.txt");
  $sakujo = $_POST["sakujo"];
  $pass = $_POST["pass"];
  $pattern = "/^($sakujo).($pass)$/";

if(preg_match($pattern, $file) === 1){
    preg_replace($pattern, "", $file);
    $message = '削除しました';
  }else{
    $message = '<font color="red">この投稿は削除できません</font>';
  }
  fclose($fp4);
}

//ここまで削除機能
$fp4 = fopen("data.txt", "r+");
$file = file("data.txt");
var_dump($file);
fclose($fp4);
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.ong/TR/html4/loose.dtd">
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>掲示板</title>
    </head>
    <body bgcolor="#9999FF">
        <table border="1">
            <tr><td><?php echo $count;?></td></tr>
        </table>
        <h1><center>一行掲示板</center></h1>
        <h3><center>思いつくまま、一言メッセージをどうぞ。</center></h3>
        <h5><center>パスワードを設定し自分の投稿を削除することができます。</center></h5>
            <?php echo $message; ?>
        <center><table border="2" bgcolor="#9999FF">
          <form action="" method="POST">
              <tr>
                <td>名前</td><td><input type="text" name="name" value="<?php echo $name;?>"></td>
              </tr>
              <?php echo '<font color="red">'.$err_msg1.'</font>';?><br>
              <tr>
                <td>コメント</td><td><textarea name="comment" row="4" cols="40" value="<?php echo $comment;?>"></textarea></td>
              </tr>
              <?php echo '<font color="red">'.$err_msg2.'</font>';?><br>

              <tr>
                <td>
                  <label for="color">文字の色</label>
                  <select name="color">
                    <option value="#000000" selected>黒</option>
                    <option value="#FFFFFF">白</option>
                    <option value="#FF0000">赤</option>
                    <option value="#0000FF">青</option>
                    <option value="#00FF00">緑</option>
                    <option value="#660099">紫</option>
                    <option value="#FF3300">橙</option>
                  </select>
                </td>
                <td>パスワード<input type="password" name="password"></td>
                <?php echo '<font color="red">'.$err_msg3.'</font>';?>
                <td><input type="submit" name="send" value="クリック"></td>
              </tr>
          </form>
        </table></center>
          <br>
        <hr>
          <br>
        <dl>
            <?php foreach($dataArr as $data):?>
              <p><span><?php
              echo '['.$data["number"].']';
              ?></span>
                <span>
                  <font color="<?php echo htmlspecialchars($data["color"], ENT_QUOTES, 'UTF-8');?>">
                    <?php echo htmlspecialchars($data["name"], ENT_QUOTES, 'UTF-8');?>
                  </font>
                </span> > <span>
                  <font color="<?php echo htmlspecialchars($data["color"], ENT_QUOTES, 'UTF-8');?>">
                    <?php echo htmlspecialchars($data["comment"], ENT_QUOTES,'UTF-8');?>
                  </font>
                </span>
                <span>(<?php echo $data["date"];?>)</span>
              </p>
            <?php endforeach;?>
        </dl>
        <br>
        <hr>
        <br>
        <center><table border="2" bgcolor="#9999FF">
          <form action ="" method="POST">
            <tr>
              <td>投稿番号</td><td><input type="text" name="sakujo" required></td>
            </tr>
            <tr>
              <td>パスワード</td><td><input type="password" name="pass" required></td>
            </tr>
            <tr><td></td>
              <td><input type="submit" value="削除" name="delete"></td>
            </tr>
          </form></table></center>
    </body>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • mts10806

    2018/07/10 14:45

    「うまく動作しない」「うまくいかない」では何が起きているか伝わりません。「○○のようになるはずなのに××となってしまう」のような形で「ゴール」と「現象(エラーメッセージなども含む)」を明確にしてください。https://teratail.com/help/question-tips#questionTips3-4-1

    キャンセル

  • naberius

    2018/07/10 14:51

    ゴールはファイルの中からPOSTされた投稿番号とパスワードに一致する行を探して空白を挿入して削除することです。現象としてはエラー文は出ず投稿番号欄とパスワード欄の文字が消えて他は何も変わらないといった状態です。わかりづらくてすみません。

    キャンセル

回答 3

checkベストアンサー

+1

いろいろ誤解されているソースに見えます。
まず、

$fp4 = fopen("data.txt", "r+");
$file = file("data.txt");
var_dump($file);
fclose($fp4);


このfopen()fclose()は必要ありません。file()で、内部でOpenとCloseを勝手にやってくれています。

次に、file()で取り出した値は、ファイル内部のポインタをリアルタイムに保持しているわけではなく、単に書き込まれているデータと同じものを配列にブチ込んでいるだけです。
なので

$file = file("data.txt");
$file = null;


としても、ファイルの中身が空になるわけではありません。

やるとすると、$fileの中身を書き換えたあと、mode "w"でfopen()し、中身をごっそり書き換えると言う形ですかね。
ただ、これだとほぼ同時にアクセスされている方がいるとデータが壊れる(失われる)可能性もありますので、おすすめできません。

普通はDBを使うべき案件ですが、あえてファイルでやるとすると、投稿1つずつを1ファイルに格納する方がいいと思います。
/data/post/001.txt /data/post/002.txt ・・・など
投稿が増えると管理が大変ですが、そのあたりは最初に読み込むのは10件までとするなどして制御していくしかないですね。

ちなみに、TAB区切りやカンマ区切りのデータの読み書きについてはfputcsv() fgetcsv()などの便利な関数もあります。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/10 15:27

    なるほど・・・それでエラーは出ずとも機能しなかったんですね。
    ありがとうございます。検討してみます。

    キャンセル

0

正規表現に関して

$pattern = "/^($sakujo)\t.+\t($pass)$/";


こんな感じでしょうか?

.は任意の1文字にしかマッチしないので.+として任意の文字列にマッチする必要があります。

また、 ($sakujo)\t としておかないと

1\t(name1)\t(comment1)\t(date1)\t(color1)\t(password)
10\t(name2)\t(comment2)\t(date2)\t(color2)\t(password)


というような場合に 10のほうも検索に引っかかってしまいます。

最後の ($password) 側も同様に \t($password)
passwordが test だった場合、このままだと t でも削除できてしまいます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/10 15:17

    タグとセットにする発想がなくて目から鱗でした!ありがとうございます!
    ただやはり投稿が消せなかったです。
    正規表現だとできないってことはないですよね・・・?

    キャンセル

  • 2018/07/10 15:34

    kunaiさんの回答にもあるように、他に原因があります。
    そちらを参考になさって、ファイルの書き換えで対応したい場合は
    https://teratail.com/questions/2451
    などに既に回答がありますので参考にしてみてはいかがでしょう。

    キャンセル

  • 2018/07/10 15:38

    ありがとうございます!参考にさせていただきます!

    キャンセル

0

前回答者の内容を元に、「正規表現チェッカー」で、自分が望むチェックが出来ているか、調べながら試行錯誤するといいかもです。

http://okumocchi.jp/php/re.php

あと正規表現のマッチだけでは、該当ファイル行は消せないので、これも前回答者の内容通り、行ごと消したファイルを新たに一時的に作成しリネーム等するか、本ファイルを上書きするか、なりで、ロックを掛けて更新する必要がありますね。

投稿が同じタイミングだったので、前回答に便乗する形になってしまい、すみません。。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/10 15:28

    こんな便利なものがあったんですね!
    ありがとうございます!活用させていただきます!

    キャンセル

  • 2018/07/10 15:33 編集

    私が回答を書いている間にいろいろ更新があったようで、追記訂正しました。
    「正規表現がうまくいかない」のではなく「投稿をファイルから消したい」という内容のようですので、これは正規表現だけの問題ではないです。
    2番目に回答された方の回答も参考になると思います。

    キャンセル

  • 2018/07/10 15:35

    そうですね。。。
    どういう風にするか少し考えてみます。

    キャンセル

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

  • PHP

    21239questions

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

  • 正規表現

    829questions

    正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。