このページにはプロモーションが含まれています。
目次
はじめに
こんにちは。はなまるです!
今回は、PHPとJavaScriptの非同期処理を使った「いいねボタン」を作るための参考プログラムをお伝えします。
非同期処理の流れを確認しよう
はじめに処理の流れを確認しましょう!
STEP
イベントが発生
ブラウザでイベントが発生。クリックイベントなど
STEP
サーバー側へ指示
JavaScriptからリクエスト
STEP
サーバー処理
JavaScriptにデータが返ってくる
STEP
完了後の処理
JavaScriptでの処理をおこなう
動作の確認
クリックするといいねがプラスされて、増えていきます。
いいねが1以上ついているボタンには、ピンク色が付きます。
データベース
テーブル構造テーブル構成は以下のように作りました。
userテーブル
postテーブル
count_tableテーブル
Ajaxの基本構造
Ajaxの雛形は以下のようになります。
var sample = new XMLHttpRequest();
sample.open("GET", "リクエスト送信先のURL");
sample.onreadystatechange = function (e) {
if (sample.readyState === 4) {
if (sample.status === 200) {
// 処理
alert("通信成功");
} else {
alert("通信中...");
}
}
};
sample.send();
「いいね機能」のプログラム
データベース連携にプレースホルダでセキュリティ対策をしていますが、
その他は別途セキュリティ対策が必要です。
like.js
ボタンに色をつけるクラスを付与するプログラムと、
like_countクラスの要素を取得し、1をプラスして上書きするプログラムです。
const postIds = document.querySelectorAll('.likebtn');
postIds.forEach(function (item, index) {
item.addEventListener('click', function () {
var postId = this.dataset.like;
var like = new XMLHttpRequest();
like.open("GET", "like.php?postid=" + postId);
like.onreadystatechange = function (e) {
if (like.readyState === 4) {
if (like.status === 200) {
var likebtn = document.getElementsByClassName('likebtn');
for (i = 0; i < likebtn.length; i++) {
item.classList.add('active');
}
// 押されたボタンの子要素(.like_count)を取得
var likeCount = item.getElementsByClassName('like_count');
// 子要素の値(テキストを取得)
// 取得した値に1をプラス
// プラスした値で子要素の値を上書きする
likeCount[0].innerHTML = Number(likeCount[0].innerHTML) + 1;
} else {
alert("通信中...");
}
}
};
like.send();
});
});
like.php
<?php
session_start();
if (isset($_SESSION['login_id']) && isset($_REQUEST['postid'])) {
$post_id = $_REQUEST['postid'];
try {
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false,
PDO::ATTR_EMULATE_PREPARES => false
);
$db = new PDO("mysql:host=localhost;dbname=データベース名;charset=utf8", "ユーザー名", "パスワード", $opt);
//post_idがcount_tableにないときは、count_tableのpost_idに挿入する
$sql = "INSERT INTO count_table(post_id) SELECT ? WHERE NOT EXISTS (SELECT * FROM count_table WHERE post_id = ?)";
$ps = $db->prepare($sql);
$ps->bindValue(1, $post_id, PDO::PARAM_STR);
$ps->bindValue(2, $post_id, PDO::PARAM_STR);
$ps->execute();
//ボタンが押されたpost_idのlike_count(count_table)に1を足して上書きする
$sql = "UPDATE count_table SET like_count = like_count + 1 WHERE post_id = $post_id";
$likedb = $db->prepare($sql);
$likedb->execute();
} catch (Exception $ex) {
die('データベースに接続できませんでした');
}
}
allpost.php
<?php
session_start();
if (isset($_SESSION['login_id'])) {
try {
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false,
PDO::ATTR_EMULATE_PREPARES => false
);
$db = new PDO("mysql:host=localhost;dbname=データベース名;charset=utf8", "ユーザー名", "パスワード", $opt);
//全ユーザーの投稿を取得
$sql = "SELECT P.post_id,like_count,post,user_id,created_at from post as P LEFT OUTER JOIN count_table as C ON C.post_id = P.post_id";
$ps = $db->prepare($sql);
$ps->execute();
} catch (Exception $ex) {
die('データベースに接続できませんでした');
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>みんなのポスト</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div>
<?php while ($row = $ps->fetch(PDO::FETCH_ASSOC)): ?>
<div><?php echo $row['post']; ?></div>
<div><?php echo $row['user_id']; ?></div>
<div><?php echo $row['created_at']; ?></div>
//like_countが0より大きかったらactiveクラスをつける
<button type="button" id="likebtn" class="likebtn <?php if ($row['like_count'] > 0) { echo "active";} ?>" data-like="<?php echo $row['post_id']; ?>">
<span class="like_count"><?php echo $row['like_count']; ?></span>
いいね</button>
<?php endwhile; ?>
</div>
<script src="like.js"></script>
</body>
</html>
style.css
.likebtn {
width: 80px;
height: auto;
border: solid 1px;
border-radius: 50px;
}
.active {
background-color: hotpink;
}
いいねボタンをクリックすると、”active”クラスがボタンに付与されて、ピンク色に変わります。
おわりに
以上、PHPとJavaScriptの非同期処理を使った「いいねボタン」の実装についてでした。
参考になれば嬉しいです。
コメント