【PHP】いいね機能実装

PHPについて学習内容を備忘録としてまとめます。
#いいね機能
PHPでajax処理を用いた`いいね機能`を実装しましたので、ここに実装方法をまとめます。
いいね機能とはFacebookやツイッターにあるお気に入り機能を指します。

##いいねボタンの実装
まずは`いいねボタン`を実装します。
ボタンを配置する場所は適切なところに設置してください。

```php
#user_disp.php

//ユーザーIDと投稿IDを元にいいね値の重複チェックを行っています
function check_favolite_duplicate($user_id,$post_id){
    $dsn='mysql:dbname=db;host=localhost;charset=utf8';
    $user='root';
    $password='';
    $dbh=new PDO($dsn,$user,$password);
    $sql = "SELECT *
            FROM favorite
            WHERE user_id = :user_id AND post_id = :post_id";
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array(':user_id' => $user_id ,
                         ':post_id' => $post_id));
    $favorite = $stmt->fetch();
    return $favorite;
}

<form class="favorite_count" action="#" method="post">
        <input type="hidden" name="post_id">
        <button type="button" name="favorite" class="favorite_btn">
        <?php if (!check_favolite_duplicate($_SESSION['user_id'],$post_id)): ?>
          いいね
        <?php else: ?>
          いいね解除
        <?php endif; ?>
        </button>
</form>
```
上記では`いいねボタン`をクリックした際に、`check_favolite_duplicate`関数ですでに投稿をお気に入りしているかを判断し、
ボタンを`いいね`か`いいね解除`に切り替えています。

当然このままではajax処理は行われないため、JavaScriptを利用していきます。
jsファイルを作成し、下記を追加します。

##jsファイルを作成
```js
//URLから引数に入っている値を渡す処理
function get_param(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return false;
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}


$(document).on('click','.favorite_btn',function(e){
    e.stopPropagation();
    var $this = $(this),
        page_id = get_param('page_id'),
        post_id = get_param('procode');
    $.ajax({
        type: 'POST',
        url: 'ajax_post_favorite_process.php',
        dataType: 'json',
        data: { page_id: page_id,
                post_id: post_id}
    }).done(function(data){
        location.reload();
    }).fail(function() {
      location.reload();
    });
  });
```
上記処理ではクラス名が`favorite_btn`であるボタンをクリックした際に、
`ajax_post_favorite_process.php`に`page_id`と`post_id`を渡して処理を進めています。

get_paramとはURLから引数に入っている値を取り出すことができます。
この関数からpage_id(ユーザーID)とpost_id(投稿ID)を受け取っています。

##ajax処理の追加
では`ajax_post_favorite_process.php`で進めている処理を見ていきます。

```php
<script src=" https://code.jquery.com/jquery-3.4.1.min.js "></script>
<script src="../js/user_page.js"></script>
<?php
session_start();
session_regenerate_id(true);
require_once('config.php');

function check_favolite_duplicate($user_id,$post_id){
    $dsn='mysql:dbname=db;host=localhost;charset=utf8';
    $user='root';
    $password='';
    $dbh=new PDO($dsn,$user,$password);
    $sql = "SELECT *
            FROM favorite
            WHERE user_id = :user_id AND post_id = :post_id";
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array(':user_id' => $user_id ,
                         ':post_id' => $post_id));
    $favorite = $stmt->fetch();
    return $favorite;
}

if(isset($_POST)){

  $current_user = get_user($_SESSION['user_id']);
  $page_id = $_POST['page_id'];
  $post_id = $_POST['post_id'];

  $profile_user_id = $_POST['page_id'] ?: $current_user['user_id'];

  //既に登録されているか確認
  if(check_favolite_duplicate($current_user['id'],$post_id)){
    $action = '解除';
    $sql = "DELETE
            FROM favorite
            WHERE :user_id = user_id AND :post_id = post_id";
  }else{
    $action = '登録';
    $sql = "INSERT INTO favorite(user_id,post_id)
            VALUES(:user_id,:post_id)";
  }

  try{
    $dsn='mysql:dbname=shop;host=localhost;charset=utf8';
    $user='root';
    $password='';
    $dbh=new PDO($dsn,$user,$password);
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array(':user_id' => $current_user['code'] , ':post_id' => $post_id));

  } catch (\Exception $e) {
    error_log('エラー発生:' . $e->getMessage());
    set_flash('error',ERR_MSG1);
    echo json_encode("error");
  }
}

```
`check_favolite_duplicate`関数で現在のユーザーIDと投稿IDを取得しデータベースに組み合わせが重複していないか確認を取り、
重複していた場合にいいねを解除しています。
重複していなかった場合はfavoriteテーブルにuser_idとpost_idを追加します。

これで下記の画面のようにいいねボタンが実装され、テーブルにもカラムが追加されていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/6d6d8373-06ae-9bc4-5e6f-cf45ab9b0550.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/6904f6fc-c58c-7d51-4b10-4c1960f35d25.png)

↓いいねボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/99e5e02a-4ffe-f3f9-6586-f7dfdb8ab6a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/2216321a-41a6-07f5-0ae0-fedb9a07eaf3.png)
上記のような画面になりデータベースが更新されれば成功です。
こちらはユーザーIDが７、投稿IDが13で実行しています。

#参考URL
https://qiita.com/nyann123/items/7320d98d17768986add0