Help us understand the problem. What is going on with this article?

【PHP】フォロー機能実装

PHPについて学習内容を備忘録としてまとめます。
ユーザー間のフォロー機能を実装しましたので、作成方法を記載します。

anime1.gif
完成したものは上記のようにフォローボタンを押すと、
フォローした人フォロワーの情報がテーブルに渡されます。

テーブル構成

まずはフォローした人フォロワーの情報を扱うため、そのテーブルを作成します。
テーブルの構成は下記のようになっています。
image.png
relationがテーブル名、follow_idfollower_idがカラム名になっております。
名前はご自身でお好みでつけても問題ございません。

※動作画面にidカラムとdelete_flgカラムがありますが、こちらはなくても実装できます。

フォローボタン実装

フォローボタンを表示させます。
表示先のページはフォローするユーザーのページを指定しています。

$current_user = get_user($_GET['user_id']);
$profile_user = get_user($_GET['page_id']);

<form action="#" method="post">
          <input type="hidden" class="current_user_id" value="<?= $current_user['id'] ?>">
          <input type="hidden" name="follow_user_id" value="<?= $user_id ?>">
          <?php if (check_follow($current_user['id'],$user_id)): ?>
          <button class="follow_btn border_white btn following" type="button" name="follow">フォロー中</button>
          <?php else: ?>
          <button class="follow_btn border_white btn" type="button" name="follow">フォロー</button>
          <?php endif; ?>
</form>

まず、get_user()を使用してログイン中のユーザー情報ページ内のユーザー情報を取得しています。
get_user()は下記のような構成の関数になっており、引数にあるユーザーIDからユーザー情報を返します。

function get_user($user_id){
    try {
      $dsn='mysql:dbname=shop;host=localhost;charset=utf8';
      $user='root';
      $password='';
      $dbh=new PDO($dsn,$user,$password);
      $sql = "SELECT id,name,password,profile,image
              FROM user
              WHERE id = :id AND delete_flg = 0 ";
      $stmt = $dbh->prepare($sql);
      $stmt->execute(array(':id' => $user_id));
      return $stmt->fetch();
    } catch (\Exception $e) {
      error_log('エラー発生:' . $e->getMessage());
      set_flash('error',ERR_MSG1);
    }
  }

戻りまして、

$current_user = get_user($_GET['user_id']);
$profile_user = get_user($_GET['page_id']);

$_GET['user_id']$_GET['page_id']に関してはパスからユーザーIDを取得しています。

http://localhost/user/user_disp.php?user_id=20&page_id=23

このようなパスになっていた場合は$_GET['user_id']20$_GET['page_id']23が渡されます。

function check_follow($follow_user,$follower_user){
  $dsn='mysql:dbname=shop;host=localhost;charset=utf8';
  $user='root';
  $password='';
  $dbh=new PDO($dsn,$user,$password);
  $sql = "SELECT follow_id,follower_id
          FROM relation
          WHERE :follower_id = follower_id AND :follow_id = follow_id";
  $stmt = $dbh->prepare($sql);
  $stmt->execute(array(':follow_id' => $follow_user,
                       ':follower_id' => $follower_user));
  return  $stmt->fetch();
}

次にcheck_follow関数でユーザーがフォロー関係にあるか確認をしています。
引数に渡されたユーザーIDがrelartionテーブルでフォロー関係にあった場合はtrueを返し、フォロー関係にない場合はfalseを返します。

          <?php if (check_follow($current_user['id'],$user_id)): ?>
          <button class="follow_btn border_white btn following" type="button" name="follow">フォロー中</button>
          <?php else: ?>
          <button class="follow_btn border_white btn" type="button" name="follow">フォロー</button>
          <?php endif; ?>

フォローボタンを表示していたブラウザ画面に戻りまして、先ほどのcheck_follow関数でtrueが返ってきた場合はフォロー中falseが返ってきた場合はフォローがボタンに表示されます。

これでフォローボタンの実装が完了したので、今度はクリックした際のajax処理についてみていきます。

ajax処理_js

フォローボタンをクリックした時にデータベースを操作するajax処理について実装していきます。
jsファイルに下記ソースコードを入力していきます。

  $(document).on('click','.follow_btn',function(e){
    e.stopPropagation();
    var $this = $(this),
    current_user_id = $('.current_user_id').val();
    user_id = $this.prev().val();
    $.ajax({
        type: 'POST',
        url: '../ajax_follow_process.php',
        dataType: 'json',
        data: { current_user_id: current_user_id,
                user_id: user_id }
    }).done(function(data){
      location.reload();
    }).fail(function(){
      location.reload();
    });
  });

処理としては要素名が.follow_btnのフォローボタンがクリックされたときに、current_user_iduser_idを取得しajax_follow_process.phpに遷移しています。
細かく処理をみていきます。

  $(document).on('click','.follow_btn',function(e){
    e.stopPropagation();
    var $this = $(this),
    current_user_id = $('.current_user_id').val();
    user_id = $this.prev().val();

$(document).on('click','.follow_btn',function(e){でフォローボタンがクリックされた際に処理が走るように定義されております。
そしてcurrent_user_id = $('.current_user_id').val();user_id = $this.prev().val();でブラウザからユーザー情報を取得しています。

<input type="hidden" class="current_user_id" value="<?= $current_user['id'] ?>">
<input type="hidden" name="follow_user_id" value="<?= $user_id ?>">

こちらは先ほどフォローボタンを表示していたブラウザ画面なのですが、$('.current_user_id').val();<?= $current_user['id'] ?>user_id = $this.prev().val();<?= $user_id ?>をそれぞれ取得しています。

    $.ajax({
        type: 'POST',
        url: '../ajax_follow_process.php',
        dataType: 'json',
        data: { current_user_id: current_user_id,
                user_id: user_id }

フォローボタンがクリックされたときにこちらの処理が走り取得したユーザー情報をajax_follow_process.phpに渡し遷移します。

    }).done(function(data){
      location.reload();
    }).fail(function(){
      location.reload();
    });

こちらではajax処理が成功した場合と、失敗した場合で処理が分岐しています。
今回の場合だとどちらもlocation.reload();なのでページをリロードして終わりです。
それでは遷移したajax_follow_process.phpでの処理をみていきます。

ajax処理_PHP

ajax_follow_process.php
  $user_id = $_POST['user_id'];
  $current_user_id = $_POST['current_user_id'];

    if(check_follow($current_user_id,$user_id)){
      $action = '解除';
      $flash_type = 'error';
      $sql ="DELETE
              FROM relation
              WHERE :follow_id = follow_id AND :follower_id = follower_id";
    }else{
      $action = '登録';
      $flash_type = 'sucsess';
      $sql ="INSERT INTO relation(follow_id,follower_id)
              VALUES(:follow_id,:follower_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(':follow_id' => $current_user_id , ':follower_id' => $user_id));
      $return = array('action' => $action,
      'follow_count' => current(get_user_count('follow',$current_user_id)),
      'follower_count' => current(get_user_count('follower',$current_user_id)));
      echo json_encode($return);       
    }    
    catch (\Exception $e) {
      error_log('エラー発生:' . $e->getMessage());
      set_flash('error',ERR_MSG1);
      echo json_encode("error");
    }

jsファイルから取得したユーザー情報からフォロー関係にあるか確認し、返ってきた真偽値によってrelationテーブルを操作して処理を行っています。

これでフォロー機能が実装できたと思います。
先ほどの動作画面のようにフォローボタンをクリックしたときにrelationテーブルが操作される処理がされるはずです。

参考URL

https://github.com/nyann123/snspoi

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away