いいね機能の作成
いいねモデルの作成
Modelsフォルダ内に「likes.php」ファイルを作成します。
![](https://tech-popeye.com/wp-content/uploads/2021/11/vscode_1-1024x489.png)
likes.phpに以下の内容を書きます。
htdocs/Twitter/Models/likes.php
<?php
// 設定ファイルの読み込み
include_once '../config.php';
function createLike($data)
{
// データベースに接続
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// 成功/失敗確認
if ($mysqli->connect_errno) {
echo 'MySQLの接続に失敗しました。<br>';
exit;
}
// いいね登録のSQLを作成
$query = 'INSERT INTO likes (user_id, tweet_id) VALUES (?, ?)';
// セキュリティ上、以下のように書く
$statement = $mysqli->prepare($query);
$statement->bind_param('ii', $data['user_id'], $data['tweet_id']);
// SQLを実行
$response = $statement->execute();
// 成功/失敗確認
if ($response == false) {
echo 'エラーが発生しました。<br>';
$response = null;
} else{
// 成功したら挿入したデータの主キー(likesテーブルのidカラムの値)を取得できる
$response = $mysqli->insert_id;
}
// データベースへの接続解除
$statement->close();
$mysqli->close();
// response変数には、id(成功)or null(失敗)が入っている
return $response;
}
function deleteLike($data)
{
// データベースに接続
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// 成功/失敗確認
if ($mysqli->connect_errno) {
echo 'MySQLの接続に失敗しました。<br>';
exit;
}
// いいねを削除するSQLを作成
$query = 'UPDATE likes SET status ="deleted" WHERE id = ? AND user_id = ?';
// セキュリティ上、以下のように書く
$statement = $mysqli->prepare($query);
$statement->bind_param('ii', $data['like_id'], $data['user_id']);
// SQLを実行
$response = $statement->execute();
// 成功/失敗確認
if ($response == false) {
echo 'エラーが発生しました。<br>';
}
// データベースへの接続解除
$statement->close();
$mysqli->close();
// response変数には、true(成功)or false(失敗)が入っている
return $response;
}
?>
いいねを登録するcreateLike関数を追加しています。
引数として、連想配列(登録するユーザー情報とツイート情報を含む)を受け取るものとします。
「$response = $mysqli->insert_id」に着目して下さい。insert_idはmysqliクラスがもつ変数です。主キーをもつテーブルにデータを挿入した場合、その主キーの値(ここでは、likesテーブルのidカラムの値)を取得することができ、その値がinsert_idに入っています。
その他はこれまでに解説した内容と同様です。
また、いいねを削除するdeleteLike関数を追加しています。
likesテーブルのstatusカラムの値を「deleted」に更新することで、削除状態になったことにしています。
いいねコントローラーの作成
Controllersフォルダ内に「like.php」ファイルを作成します。
![VSCode](https://tech-popeye.com/wp-content/uploads/2021/11/vscode_2_compressed-8-1024x555.png)
like.phpに以下の内容を書きます。
htdocs/Twitter/Controllers/like.php
<?php
include_once '../util.php';
// いいねモデルを読み込み
include_once '../Models/likes.php';
// ログインチェック
$view_user = getSession();
if ($view_user == false) {
// ログインしていない
header('Location: ../Controllers/sign-in.php');
exit;
}
$like_id = null;
// いいねの登録
if (isset($_POST['tweet_id'])) {
$data = [
'tweet_id' => $_POST['tweet_id'],
'user_id' => $view_user['id'],
];
$like_id = createLike($data);
}
// いいねの取り消し
if (isset($_POST['like_id'])) {
$data = [
'like_id' => $_POST['like_id'],
'user_id' => $view_user['id'],
];
deleteLike($data);
}
// JSON形式で結果をクライアントに応答
$response = [
'message' => 'success',
'like_id' => $like_id, // like_id変数には、id(成功)or null(失敗)が入っている
];
header('Content-Type: application/json; charset=uft-8');
echo json_encode($response);
?>
クライアントからのPOSTで、$_POST[‘tweet_id’]がセットされていれば、いいねを登録します。そうではなく、$_POST[‘like_id’]がセットされていれば、いいねの取り消しを行います。
最後に結果をクライアントに応答します。
JSON形式とは下図のようなデータの形式を指します。
![JSONの説明](https://tech-popeye.com/wp-content/uploads/2021/11/json_compressed.png)
次の「header(‘Content-Type: application/json; charset=uft-8’)」のように書くことで、クライアントに「このデータはJSON形式のデータです」と教えることができます。これは覚えるしかありません。
最後に、変数$responseは連想配列ですので、json_encode関数を使って、連想配列からJSON形式に変換しています。json_encodeはPHPの関数です。
その戻り値(JSON形式のデータ)をechoすることで、JSON形式のデータがクライアントに通知(出力)されるのです。
ツイート領域の変更
ツイート領域を以下のように修正します。
htdocs/Twitter/Views/common/tweet.php
<div class="tweet">
<div class="user">
<a href="profile.php?user_id=<?php echo $view_tweet['user_id']; ?>">
<img src="img_uploaded/user/<?php echo $view_tweet['user_image_name']; ?>" alt="">
</a>
</div>
<div class="content">
<div class="name">
<a href="profile.php?user_id=<?php echo $view_tweet['user_id']; ?>">
<span class="nickname"><?php echo $view_tweet['user_nickname']; ?></span>
<span class="user-name">@<?php echo $view_tweet['user_name']; ?> ・<?php echo $view_tweet['tweet_created_at']; ?></span>
</a>
</div>
<p><?php echo $view_tweet['tweet_body'] ?></p>
<?php if (isset($view_tweet['tweet_image_name'])) : ?>
<img src="<?php echo $view_tweet['tweet_image_name']; ?>" alt="" class="post-image">
<?php endif; ?>
<div class="icon-list">
<!-- ★変更箇所(ここから) -->
<div class="like js-like" data-tweet-id="<?php echo $view_tweet['tweet_id']; ?>" data-like-id="<?php echo $view_tweet['like_id']; ?>">
<!-- ★変更箇所(ここまで) -->
<?php
if (isset($view_tweet['like_id'])) {
// いいね!がある場合
echo '<img src="../Views/img/heart.svg" alt="">';
} else {
// いいね!がない場合
echo '<img src="../Views/img/heart2.svg" alt="">';
}
?>
</div>
<div class="like-count js-like-count"><?php echo $view_tweet['like_count']; ?></div>
</div>
</div>
</div>
「data-tweet-id=”<?php echo $view_tweet[‘tweet_id’]; ?>”」を追加しています。これはlikes.jsで使います。
いいね通知機能の作成
likes.jsを以下のように修正します。
htdocs/Twitter/Views/js/likes.js
$(function() {
// いいね!がクリックされたとき
$('.js-like').click(function() {
const this_obj = $(this);
// ★変更箇所1(ここから)
const tweet_id = $(this).data('tweet-id');
// ★変更箇所1(ここまで)
const like_id = $(this).data('like-id');
const like_count_obj = $(this).parent().find('.js-like-count');
let like_count = Number(like_count_obj.html());
if (like_id) {
// ★変更箇所2(ここから)
$.ajax({
url: 'like.php',
type: 'POST',
data: {
'like_id': like_id
}
})
.done(function() {
// いいね!取り消し(カウントを減らす)
like_count -= 1;
like_count_obj.html(like_count);
this_obj.data('like-id', null);
// いいね!ボタンの色を変更
this_obj.find('img').attr('src', '../Views/img/heart2.svg');
});
// ★変更箇所2(ここまで)
} else {
// ★変更箇所3(ここから)
$.ajax({
url: 'like.php',
type: 'POST',
data: {
'tweet_id': tweet_id
}
})
.done(function(data) {
// いいね!付与(カウントを増やす)
like_count += 1;
like_count_obj.html(like_count);
this_obj.data('like-id', data['like_id']);
// いいね!ボタンの色を変更
this_obj.find('img').attr('src', '../Views/img/heart.svg');
});
// ★変更箇所3(ここまで)
}
});
})
変更箇所1では、tweet.phpで追加した「data-tweet-id」属性の値を取り出しています。
変更箇所2について解説します。
「$.ajax()」はjQueryの関数で、サーバーに対してHTTPリクエストを送ることができます。引数としてJSON形式のデータを渡します。これは覚えるしかありません。
引数のJSON形式のデータについてみていきます。
1つ目は、キー「url」、値「like.php」です。これは、サーバーのURLとして(Controllersの)like.phpを指定してHTTPリクエストを送るという意味です。
2つ目は、キー「type」、値「POST」です。これは、POSTの形式でHTTPリクエストを送るという意味です。
3つ目は、キー「data」、値はJSON形式のデータです。このようにJSON形式のデータは、JSONの中にJSONを入れ子にすることができます。dataという文字通り、サーバーに送るデータを指定します。キー「like_id」、値「like_id(=変数like_idの値)」というデータをサーバーに送るという意味ですね。JSON形式にしているのは、複数のデータをサーバーに送る場合があるためです。複数のデータを指定する場合は、カンマ区切りでキーと値を並べます。
送られたデータは、サーバー側のPHPでは「$_POST[‘キー名’]」のように取得できます。ここでは「$_POST[‘like_id’]」ですね。
次の「.done(function() { … })」に着目して下さい。
これは「$.ajax()」の処理が終わったら(HTTPリクエストをサーバーに送って、サーバーから応答があったら)、実行される処理という意味です。これは覚えるしかありません。実行される処理は「function(){ … }」の中に書きます。
変更箇所3は、変更箇所2とほぼ同じです。
変更箇所3では、「.done(function(data) { … })」のように、functionの引数に「data」がありますね。これはサーバーからの応答データを指します。これは覚えるしかありません。
サーバー側(Controllers/like.php)の最後に、JSON形式の「$response」をクライアントに返す処理を書きましたね。このJSONデータが「function(data)」のdataに入ってきます。JavaScriptでは、JSON形式のデータは「data[‘キー名’]」のように、PHPの連想配列のように取り出すことができます。ここでは「data[‘like_id’]」として取り出していますね。
![ブラウザ](https://tech-popeye.com/wp-content/uploads/2021/11/browser_3_compressed-8-1024x501.png)
ここまで出来たら、変更内容をコミットし、GitHubにプッシュして下さい。
本節の説明は以上になります。