PHPとJavaScriptの非同期処理で「いいねボタン」を作ろう!

PHPとJavaScriptの非同期処理で「いいね機能」を作ろう!のアイキャッチ

このページにはプロモーションが含まれています。

目次
プログラミング言語の人気オンラインコース

はじめに

こんにちは。はなまるです!

今回は、PHPとJavaScriptの非同期処理を使った「いいねボタン」を作るための参考プログラムをお伝えします。

非同期処理の流れを確認しよう

はじめに処理の流れを確認しましょう!

非同期処理のイメージの画像
STEP
イベントが発生

ブラウザでイベントが発生。クリックイベントなど

STEP
サーバー側へ指示

JavaScriptからリクエスト

STEP
サーバー処理

JavaScriptにデータが返ってくる

STEP
完了後の処理

JavaScriptでの処理をおこなう

動作の確認

クリックするといいねがプラスされて、増えていきます。

いいねが1以上ついているボタンには、ピンク色が付きます。

データベーステーブル構造

テーブル構成は以下のように作りました。

userテーブル

userテーブルの画像

postテーブル

postテーブルの画像

count_tableテーブル

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の非同期処理を使った「いいねボタン」の実装についてでした。

参考になれば嬉しいです。

よかったらシェアしてください!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

フリーランスとしてWeb制作をしています。
Webアプリ開発・セキュリティの勉強中です。
学んだことをアウトプットしてみたいと思い、ブログでの発信に挑戦中!
[保有資格:基本情報技術者]

コメント

コメントする

CAPTCHA


目次