1
3

More than 3 years have passed since last update.

【PHP】メッセージ通知数表示

Last updated at Posted at 2021-01-24

学習内容を備忘録としてまとめます。
メッセージ通知数表示機能を実装しましたので、作成方法を記載します。
message_tsuuchisuu6.gif

※通知数の表示は赤枠で囲っています

メッセージ機能については、下の記事で説明しているので割愛します。

【PHP】メッセージ機能実装

実装方法

実装方法について記載していきます。

テーブル構成

image.png
messatge_relationテーブルmessage_countを追加します。
このカラムは、ユーザー間にメッセージのやり取りがあった際にインクリメントされ、
通知数を表示するときはmessage_countカラムから、値を取り出して表示させます。

全体の流れ

本機能を、関数とカラム値の遷移を踏まえて全体的な流れをみていきます。
image.png

通知数をカウント

では、メッセージのやり取りがある際にmessage_countカラムの値をインクリメントするよう実装します。

message_add.php
:
    $stmt->execute($data);
    $dbh = null;

    if (!check_relation_message($user_id, $destination_user_id)) {
        insert_message($user_id, $destination_user_id);
    }
    insert_message_count($user_id,$destination_user_id); //ココ
    set_flash('sucsess', 'メッセージを送信しました');
    header('Location:../message/message.php?user_id=' . $destination_user_id . '');
:

メッセージを送信するときに、insert_message_countで値をインクリメントしています。

insert_message_count($user_id,$destination_user_id);

引数には自分のユーザーID送信先のユーザーIDを渡しています。

function insert_message_count($user_id,$destination_user_id){
  try {
    $dsn='mysql:dbname=db;host=localhost;charset=utf8';
    $user='root';
    $password='';
    $dbh=new PDO($dsn,$user,$password);
    $sql = "UPDATE message_relation
            SET message_count = message_count + 1
            WHERE ((user_id = :user_id and destination_user_id = :destination_user_id) or (user_id = :destination_user_id and destination_user_id = :user_id)) and user_id = :user_id";
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array(':user_id' => $user_id,
                         ':destination_user_id' => $destination_user_id));
    return $stmt->fetch();
  } catch (\Exception $e) {
    error_log('エラー発生:' . $e->getMessage());
    set_flash('error',ERR_MSG1);
  }
}

UPDATE文でmessage_countをインクリメントしています。
条件文(where)ではメッセージのやり取りをしているユーザー同士のIDから該当のmessage_relationの列を取得して、message_relation.user_idがログイン中のユーザーIDと一致するようにしています。

message_relation.user_idをログイン中のユーザーidとする理由としては、表示する通知数を取得する際にこちらのカラムを利用するからです。
後ほど、詳しく説明します。

通知数を表示

相手からメッセージが届いていた時に、通知数を表示する処理を実装します。

message_top.php
:
foreach ($message_relations as $message_relation):
if($message_relation['destination_user_id']==$current_user['id']){
$destination_user=get_user($message_relation['user_id']);
}else{
$destination_user=get_user($message_relation['destination_user_id']);
}
$bottom_message=get_bottom_message($current_user['id'],$destination_user['id']);
$new_message_count=current(new_message_count($current_user['id'],$destination_user['id'])); //ココ
?>
:
    <div class="message_notification">
        <span id="message_count">
            <?php if($new_message_count!=0){  //
            print''.$new_message_count.'';   //ココ
            }?>                               //
        </span>
    </div>
:

変数$new_message_countに通知数を渡します。

function new_message_count($user_id,$destination_user_id){
  try {
    $dsn='mysql:dbname=db;host=localhost;charset=utf8';
    $user='root';
    $password='';
    $dbh=new PDO($dsn,$user,$password);
    $sql = "SELECT message_count
            FROM message_relation
            WHERE ((user_id = :user_id and destination_user_id = :destination_user_id) or (user_id = :destination_user_id and destination_user_id = :user_id)) and user_id = :destination_user_id";
    $stmt = $dbh->prepare($sql);
    $stmt->execute(array(':user_id' => $user_id,
                         ':destination_user_id' => $destination_user_id));
    return $stmt->fetch();
  } catch (\Exception $e) {
    error_log('エラー発生:' . $e->getMessage());
    set_flash('error',ERR_MSG1);
  }
}

引数のユーザーIDから通知数を取得しており、
条件文(where)では自分と相手のIDからmessage_relationの列を探して、user_idが相手のIDのものを取得しています。
そうすることで、先ほどインクリメントしていたmessage_countカラムの値が取得できます。

message_top.php
:
    <div class="message_notification">
        <span id="message_count">
            <?php if($new_message_count!=0){  //
            print''.$new_message_count.'';   //ココ
            }?>                               //
        </span>
    </div>
:

あとは表示したい場所に$new_message_countを表示させます。
0のときは表示をしないようにします。

通知数をリセット

メッセージ画面を開いたときに通知数を0にします。
これをしないとメッセージトップ画面に戻っても、まだ通知数が表示されてしまうからです。

message.php
:
$messages = get_messages($current_user['id'], $destination_user['id']);
$bottom_message=get_bottom_message($current_user['id'],$destination_user['id']);
reset_message_count($current_user['id'],$destination_user['id']);  //ココ
?>

<body>
:

reset_message_count関数では該当のカラムに0を渡します。

function reset_message_count($user_id,$destination_user_id){
  try {
  $dsn='mysql:dbname=db;host=localhost;charset=utf8';
  $user='root';
  $password='';
  $dbh=new PDO($dsn,$user,$password);
  $dbh->beginTransaction();
  $sql = 'UPDATE message_relation SET message_count = 0 WHERE ((user_id = :user_id and destination_user_id = :destination_user_id) or (user_id = :destination_user_id and destination_user_id = :user_id)) and user_id = :destination_user_id';
  $stmt = $dbh->prepare($sql);
  $stmt->execute(array(':user_id' => $user_id,
                       ':destination_user_id' => $destination_user_id));
  $dbh->commit();
} catch (\Exception $e) {
  error_log('エラー発生:' . $e->getMessage());
  set_flash('error',ERR_MSG1);
  $dbh->rollback();
  reload();
}
}

先ほどのnew_message_count関数と同様の条件文(where)で列を取得して、0を渡します。

上記が実装できれば、トップの動作画面のようになると思います。

【おまけ】新規メッセージ件数の通知

message_tsuuchisuu5.gif
※通知数の表示は赤枠で囲っています

新しいメッセージがあると、ログイン時に件数を通知する機能を実装します。

フラッシュメッセージ機能については、下の記事で説明しているので割愛します。

【PHP】フラッシュメッセージの実装

新規メッセージ数の取得

ログイン時に新しいメッセージあるか、DBを確認します。

user_login_check.php
:
    $_SESSION['user_id']=$rec['id'];
    $_SESSION['user_name']=$rec['name'];
    if(current(message_count($_SESSION['user_id']))!=0){ //ココ
    set_flash('sucsess','ログインしました       メッセージが'.current(message_count($_SESSION['user_id'])).'件届いています'); //ココ
    }else{
    set_flash('sucsess','ログインしました');
    }
    header('Location:user_top.php?page_id='.$rec['id'].'&type=main');
:

新規メッセージがあれば、message_count関数を使用して件数をフラッシュメッセージで表示します。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3