詳解Laravel開發用戶動態模組

*文
發布: 2023-03-19 08:46:01
原創
1462 人瀏覽過

本文主要為大家介紹了關於基於Laravel實現的用戶動態模組開發的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。希望對大家有幫助。

前言

相信大家都知道,幾乎所有的社群應用程式都有使用者動態這個部分,使用者可以透過好友動態來獲得更多感興趣的內容,從而提高社區活躍度和用戶黏性。它的實作相對來講比普通的內容發佈更複雜一些,主要體現在內容多樣性上。

為了解決這個問題,我們得把這些不同類型的內容抽象,提取共通性,使用相同的結構來處理,開發起來就會簡單很多。

概念抽象

使用者動態,顧名思義,動態的產生,就是一系列事件的歷史記錄,所以首先關注「事件」這個名詞,它有哪些屬性:

  • 觸發者,基於社群所有的事件幾乎都是由使用者觸發的

  • 事件主體,事件的主體訊息,例如「xxx發佈了文章」 中的「文章」。

  • 事件屬性,事件主體不同,所需的附加資訊也不同,例如事件類型。

  • 發生時間,記錄事件產生的時間,當然了在我們的資料庫通常記錄了所有資料產生的時間。

我們將使用者動態抽象化成只有4 個基礎屬性的結構,就比較容易實現了:

- description    事件描述
- causer_id 或者 user_id 事件触发者
- subject_id    主体 ID
- subject_type   主体类型
- properties    事件附加属性
- created_at    事件产生时间
登入後複製

而主體部分就是Laravel 裡的morph relation, 多態關聯。

怎麼展示

我們的動態展示需求通常有以下幾種:

  • 我的好友的動態

  • 某個人的動態,通常是個人中心

  • 全部動態,例如Laravel China 首頁的全部動態

  • 動態搜索,比較少見

我最近正在開發EasyWeChat 新版網站,其中也有用戶動態,舉例:

xxx 发布了讨论 《请问大家怎么使用 xxx》
xxx 评论了 xxx 的话题 《请问大家怎么使用 xxx》
xxx 回复了 xxx 的评论 “我是按照文档上 ...”
xxx 购买了 《微信开发:自定义菜单的使用》
xxx 关注了 xxx
...
登入後複製

你會發現,基本上每種動態的寫法都不一樣,所以我們還需要記錄一個「事件類型」 ,例如「追蹤」、 「發布」、「回覆」、「購買」。

然後我們在blade 或其它模板引擎的使用中,就可以switch ... case 寫法,來應用不同的模板渲染這些樣式,比如blade 中,我的用法:

@switch($activity->properties['event'] ?? '')
 @case('discussion.created')
  ...
  @break
 @case('comment.created')
  ...
  @break
@endswitch
登入後複製

程式碼實現

前面我們已經討論完了資料儲存以及展示方面的設計,接著就是怎麼實現,如果你比較勤勞,可以原生實現,畢竟上面的實作方法已經描述清晰,寫點程式碼實作就搞定了,今天我要推薦的是使用spatie/laravel-activitylog 來實現:

安裝一直很簡單對吧:

$ composer install spatie/laravel-activitylog -vvv
登入後複製

記錄動態

activity()->log('Look, I logged something');
登入後複製

當然了這種記錄沒意義,幾乎沒有任何有用的信息,所以我們通常的用法應該是這樣:

activity()
 ->performedOn($anEloquentModel)
 ->causedBy($user)
 ->withProperties(['customProperty' => 'customValue'])
 ->log('Look, I logged something');
 
$lastLoggedActivity = Activity::all()->last();

$lastLoggedActivity->subject; //returns an instance of an eloquent model
$lastLoggedActivity->causer; //returns an instance of your user model
$lastLoggedActivity->getExtraProperty('customProperty'); //returns 'customValue'
$lastLoggedActivity->description; //returns 'Look, I logged something'
登入後複製

方法介紹:

  • performedOn($model) 設定事件主體,也就是Eloquent Model 實例

  • causedBy($user) 設定事件觸發者, User 實例

  • withProperties($properties) 上面我們概念裡的事件屬性

  • withProperty($key, $value) 事件屬性的單一用法

  • ##log($description) 事件描述

例如,我們要記錄一條,用戶發布了討論:

$discussion = App\Discussion::create([...]);
activity()->on($discussion)
->withProperty('event', 'discussion.created')
->log('发表了话题');
登入後複製

或用戶註冊時,我要記錄一條動態:

activity()->on($user)
->withProperty('event', 'user.created')
->log('加入 EasyWeChat');
登入後複製

你會發現我都沒有設定觸發器,因為這個模組如果你沒設定觸發器預設就是目前登入使用者。

展示動態

展示動態就是根據條件從資料庫拿出來,這裡使用套件提供的模型類別:Spatie\Activitylog\Models\ Activity

use Spatie\Activitylog\Models\Activity;

// 全部动态
$activities = Activity::all();
// 用户 ID 为 2 的动态 
$activities = Activity::causedBy(User::find(2))->paginate(15);
// 以文章 ID 为 13 为主体的动态
$activities = Activity::forSubject(Post::find(13))->paginate(15);
登入後複製

接著就是遍歷展示就好了。

一些經驗與技巧

設定一個專門的動態觀察者類別來記錄動態

$ ./artisan make:listener UserActivitySubscriber
登入後複製

程式碼如下:

<?php 
namespace App\Listeners;
class UserActivitySubscriber
{
 protected $lisen = [
  &#39;eloquent.created: App\User&#39; => &#39;onUserCreated&#39;,
  &#39;eloquent.created: App\Discussion&#39; => &#39;onDiscussionCreated&#39;,
 ];

 public function subscribe($events)
 {
  foreach ($this->lisen as $event => $listener) {
   $events->lisen($event, __CLASS__.&#39;@&#39;.$listener);
  }
 }

 public function onUserCreated($user)
 {
  activity()->on($user)
   ->withProperty(&#39;event&#39;, &#39;user.created&#39;)
   ->log(&#39;加入 EasyWeChat&#39;);
 }

 public function onDiscussionCreated($discussion)
 {
  activity()->on($discussion)
    ->withProperty(&#39;event&#39;, &#39;discussion.created&#39;)->log(&#39;发表了话题&#39;);
 }
}
登入後複製

然後我們去註冊這個訂閱類別:

在App\Providers\EventServiceProvider 中$subscribe 中註冊這個訂閱類別:

/**
 * @var array
 */
protected $subscribe = [
 \App\Listeners\UserActivitySubscriber::class,
];
登入後複製
上面我們利用了Eloquent 模型事件來監聽模型的變化,當各種模型事件創建的時候我們調用對應的方法來記錄動態,所以實現起來非常的方便。

在事件屬性裡記錄關鍵資訊

看到上面記錄動態的時候你可能會問,只儲存了ID,這種多態關聯,查詢的時候會壓力很大,比如,我們要將動態顯示為:

安小超發布了文章《自訂選單的使用》

我們如果只是儲存了文章的id 與類型,我們還需要查詢一次文章表,才能得到標題用於顯示,這樣一個動態清單的話,可能會幾十條SQL 了,的確是這樣的,我的解決方案是這樣的:

#其實我們的用戶動態是不要求100% 精準的,所以,我如果在記錄時把文章的標題一起存下來是不是就不用再查表了?其實就是,我們在動態列表需要展示的關鍵訊息,例如標題這些一起用 withProperties 存起來,這樣就一條 SQL 解決了動態列表問題。

這樣的做法也有弊端,例如文章改了標題的時候,這裡就不同步了,當然你也可以在文章修改時來改這個屬性,不過我個人認為沒有多大必要。畢竟動態就是記錄了當時的情況,後來改標題了並沒有什麼問題。

OK,使用者動態模組的開發就分享到這裡,如果你有更進階的實作歡迎隨時交流。

關於好友動態部分的實現,根據你的應用量級,以及好友關係的存儲各有不同,大家自己集思廣益即可,大部分都是先查好友關係再查動態,關聯查詢也可以,自己實現吧。

相關推薦:

詳解Laravel如何透過預先載入最佳化Model查詢

############## ####詳解修改Laravel中url()的根位址###################詳解Laravel如何實現定時任務###############################################################################################

以上是詳解Laravel開發用戶動態模組的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!