今まで勉強した一つの区切りとして、一言コメントフォームを作ってみました。
フォームからコメントを投稿して、データベースに登録、表示するといった簡単なものです。
形こそそれなりになりましたが、重大な問題点ができてしまいました。
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:更新日時