如何在 Laravel 中统计用户的最后在线时间
Laravel — 了解用户上次在线的时间
本文是我在重构 Pulse 的代码库时记录下的见解,变更和反思系列文章的一部分。Pulse 是一个为开发人员设计的无痛且经济实惠的站点和服务器监控工具。
今天,我将讨论我是如何添加中间件功能来记录用户上次在线/使用该应用程序的时间。我想将其添加到 Pulse 中,以解决一些我需要回答的分析性问题。
准备数据库
如果我们要记录用户上次的在线时间,则需要为此在 users 表中添加时间戳。这是一个简单的步骤,因此我们将从此开始。将以下内容插入到用户表迁移中:
$table->timestamp("last_online_at")->useCurrent();
接下来,我们希望 Laravel 将此属性识别为 Carbon 实例,以便我们可以利用其大量的日期和时间功能集。因此,在 User 模型类中,我们将其添加到 $casts 数组中:
class User
{
protected $casts = ["last_online_at" => "datetime"];
}
为应用添加逻辑
由于我们希望能够从应用程序的任何潜在入口点设置/更新此值,所以存储逻辑的理想位置是在中间件类中。因此,让我们继续创建一个:
namespace App\Http\Middleware;
use DB;
use Closure;
class LastOnlineAt
{
public function handle($request, Closure $next)
{
if (auth()->guest()) {
return $next($request);
}
if (auth()->user()->last_online_at->diffInHours(now()) !== 0)
{
DB::table("users")
->where("id", auth()->user()->id)
->update(["last_online_at" => now()]);
}
return $next($request);
}
}
这里发生了相当多的事情,所以让我们将其分解为…
1.首先检查用户是否为访客。如果是,我们将继续,因为我们无法为访客用户设置时间戳。
2.如果用户经过身份验证,我们将检索他们上次在线的时间戳。
3.接下来,我们确定此时间戳是否超过一小时(这是我添加的检查,以避免在每次请求时更新数据库,但你可以将此检查设置为你想要的任何内容,或完全删除它)。
4.假设时差超过一小时,我们将使用当前时间更新数据库中的时间戳。
5.无论是否执行了第4步,我们都将继续处理用户的请求(无论请求如何)。
你可能想知道为什么我不是直接更新经过身份验证的用户,而是使用 DB facade?
好吧,如果我们更新模型本身,这将导致它触发事件,并且还将 update_at 时间戳也设置为当前时间。从技术上讲,用户记录实际上并没有得到更新,我们只是设置了他们的最后上线时间。因此,我认为使用 DB facade 是更好的选择。
最后一步
所剩下的就是我们指示 Laravel 使用这个中间件。我们在应用程序的 HTTP kernel 中实现它。只需将类添加到 $MiddlewareGroups
属性内的 web 和 api 数组,例如:
protected $middlewareGroups = [
"web" => [LastOnlineAt::class],
"api" => [LastOnlineAt::class],
];
现在,只要通过身份验证的用户访问 web 或 api 路由,Laravel 都会设置其 last_online_at 时间戳。干净利落!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
:flushed:
:see_no_evil:放redis中是不是更好些?
按照步骤来的,为啥没生效,是哪里出问题了