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

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

ただいまの
回答率

90.13%

【php】一言コメントフォームがうまく動きません。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,022

nakamura03

score 23

今まで勉強した一つの区切りとして、一言コメントフォームを作ってみました。
フォームからコメントを投稿して、データベースに登録、表示するといった簡単なものです。
形こそそれなりになりましたが、重大な問題点ができてしまいました。
1、コメント投稿すると、コメントが表示されなくなってしまう。
2、コメントを表示する部分を、無理矢理表示場所ちかくに<?php ?>で囲んでもって来ると、コメントは表示されるが、リロードの度にコメントが投稿されてしまう。
データベースにインサートはちゃんとできています。取り出しもきちんとできているのですが、表示がうまくいっていないようです。
ちなみに、ローカル環境ですと、ちゃんと動くのですが、レンタルサーバーにアップするとダメでした。

どこが間違っているのでしょうか。
よろしくご指導ください。

<?php
session_start();
require_once 'conf.php';
require_once 'encode.php';
if (!isset($_SESSION["name"])) {
  $_SESSION['return'] = $_SERVER["REQUEST_URI"];
}

// コメントする人の情報を取得
if(!empty($_SESSION['name']) && !empty($_SESSION['userid'])){
    try{
    $c = $config['pdo'];
    $pdo = new PDO($c['dsn'], $c['username'], $c['password']);
        $stmt = $pdo->prepare('
SELECT name,picture,type 
FROM members 
WHERE id = :id
');
            $stmt->bindParam(':id', $_SESSION['userid'], PDO::PARAM_STR);
            $stmt->execute();
            $pdo = NULL;
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
$row = $stmt->fetch(PDO::FETCH_ASSOC);
}

// コメントを取り出す
try{
    $c = $config['pdo'];
    $pdo = new PDO($c['dsn'], $c['username'], $c['password']);
        $stmt = $pdo->prepare('
SELECT comments.*, members.id, members.name,members.picture, members.type 
FROM comments, members 
WHERE comments.userid=members.id 
ORDER BY comments.created 
DESC LIMIT 10
');
            $stmt->execute();
            $pdo = NULL;
    } catch (PDOException $e) {
        echo $e->getMessage();
    }

// コメントをインサートする。
if(!empty($_POST['comment']) && !empty($_POST['submit'])){
    try{
    $c = $config['pdo'];
    $pdo = new PDO($c['dsn'], $c['username'], $c['password']);
        $stmt = $pdo->prepare('
INSERT INTO comments(comment, userid) 
VALUES(:comment, :userid)
');
            $stmt->bindParam(':comment', h($_POST['comment']), PDO::PARAM_STR);
            $stmt->bindParam(':userid', h($_SESSION['userid']), PDO::PARAM_INT);
            $stmt->execute();
            $pdo = NULL;
header("Location: " . h($_SERVER['PHP_SELF']));
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
}
?>


<?php if (!empty($_SESSION["name"])): ?>
<div>
    <form action="" method="post">
    <dl class="inputform">
        <dt><br><?php echo $_SESSION['name']; ?>さん、メッセージをどうぞ</dt>
        <dd>
        <textarea name="comment" cols="50" rows="5"></textarea>
        <div><input type="submit" name="submit" value="投稿する"></div>
        </dd>
    </dl>
    </form>
</div>


<?php else: ?>
<div>
<p>メッセージを残す場合は、<a href="login.php">ログイン</a>してください。</p>
</div>
<?php endif; ?>

<div class="comments">

    <?php while($comment = $stmt->fetch(PDO::FETCH_ASSOC)): ?>
    <div class="comment">
    <?php if($comment['type']): ?>
    <img src="data:<?php echo$comment['type']; ?>;base64,<?php echo base64_encode($comment['picture']); ?>" />
    <?php else: ?>
    <img src="noimage.jpg">
    <?php endif; ?>
    <?php print sprintf('<p>%s<b>(%s)</b></p><p><span style="date">%s</span></p>',h($comment['comment']),h($comment['name']),h($comment['created'])); ?>
    </div>
    <?php endwhile; ?>
</div>


conf.php
<?php
/* 設定 */
$config = [
    'pdo' => [
        // SQL_CALC_FOUND_ROWS を利用するのでMySQL前提
        'dsn'  => 'mysql:dbname=****;host=localhost;charset=utf8',
        'username' => '****',
        'password' => '****',
    ],
];


encode.php
<?php
/* htmlspecialchars のラッパーを定義 */
function h($str) {
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
function m($string) {
    if (is_array($string)) {
        return array_map("m", $string);
    } else {
        return htmlspecialchars($string, ENT_QUOTES);
    }
}

構造:
comments
id:コメント番号
comment: コメント内容
userid: コメントを記入した人のid。SESSIONで取得。
created:作成日時

members
id: ユーザー番号
name:ユーザー名
password:パスワード
picture:画像データ
type:画像タイプ
created:登録日時
modified:更新日時
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m6u

    2015/10/01 12:29

    データベースに保持しているcommentsとmembersの構造も示して欲しいです。

    キャンセル

  • nakamura03

    2015/10/01 12:35

    失礼いたしました。追記いたしました。

    キャンセル

回答 1

0

処理順について、
コメントを登録→(登録したものも含めて)コメントを取得→表示、
という流れが自然なように思います。
登録処理と結果表示について、
コメント登録処理ページで結果も表示してしまうと
ページのリロード(再表示)で再投稿してしまうので、
コメント登録ページは登録のみにして結果ページにリダイレクトさせると
ページ枚数は増えますがシンプルに解決できそうです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/10/01 16:17

    登録、取得、表示の順番、直しました。ありがとうございます。
    1ページで行うことは不可能なのでしょうか……できれば、ページを変えたくないのですが……

    キャンセル

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

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

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