在 laravel 中使用中间件来确定页面访问

Using middleware in laravel to determine page visits

Public function handle($request, Closure $next)
{
    $count = 0;
    $time = now();
    $visitor = "Someone";

    if (request("visitor") == "Someone" && $count == 0) {
        $count++;
        \Mail::raw('You have a new page visit at ' . $time ' ' . $count . '', function ($note) {
            $note->to('manager@mail.com');
        });

        return $next($request);
    } else {
        return abort (404);
    }

此代码只是一个简单的中间件,用于检查 laravel 中的页面访问。它工作正常,我正在通过日志接收电子邮件。但是,每次点击的页面计数仅为 1。不增加到2、3……

我真的需要帮助来计算页面点击率,无论谁或什么访问,甚至不管 IP。另外,我如何将计数提取到视图并将其保存在数据库中。我真的需要帮助,因为我还是个学习者。请帮忙!

首先,如果你每次都重新声明$count,它永远不会增加。

其次,您在发送邮件之前检查$count是否等于0,因此即使它确实增加了,您下次也不会发送邮件。

保留计数值的一种方法是使用缓存。

public function handle($request, Closure $next)
{
    // retrieve cached value for 'page_visits'. If it doesn't exist, return 0 instead
    $count = cache('page_visits', 1);
    $visitor = request()->ip();
    $time = now();

    \Mail::raw("You have a new page visit at {$time->isoFormat('LLLL')} from {$visitor}. Total: {$count}", function ($note) {
        $note->to('manager@mail.com');
    });

    cache()->put('page_visits', ++$count);

    return $next($request);
}

类似的我也做过一次,不过是针对用户遇到的系统问题。由于您想测量流量(使用数据库),因此场景有点相似。假设您有一个名为 traffic 的 table,因此关于流量的逻辑将像您一样放置在中间件的 handle 函数中,但会像这样测量流量:

public function handle($request, Closure $next)
{
    $time = now(); // @Todo: check timezone in the config/app.php

    $visitor = $request->ip();
    $traffic = Traffic::where('visitor', $visitor)->first();

    if ($traffic) {
        // Resident visitor
        $traffic->visits++;
        $traffic->update();

    } else {
        // New visitor
        $traffic = new Traffic(['visitor' => $visitor]);
        $traffic->save();

        $totalTraffic = Traffic::all()->sum('visits');
        $totalVisitors = Traffic::all()->count();

        // Email notification
        \Mail::raw("There is a new visitor at {$time} from ip {$visitor}.\nIn total there are {$totalVisitors} visitors, and over all you have {$totalTraffic} visits.", function ($note) {
            $note->to('manager@mail.com');
        });
    }

    return $next($request);
}

请记住,您可以通过在模型内部实现引导功能将流量逻辑移至流量模型来改进此解决方案,这样看起来会更简洁。更多信息 https://laravel.com/docs/7.x/eloquent#observers

抱歉我来晚了,希望对您有所帮助...

方案二: 您还可以在数据库中创建迁移或 运行 以下语句,将访问的默认列设置为 1,因为每次创建新列时它都不会更改。

ALTER TABLE traffic ALTER visits SET DEFAULT 1;

流量模型:

class Traffic extends Model
{
    protected $fillable = ['visitor' , 'visits'];

    protected static function boot()
    {
        parent::boot();

        static::saving(function ($traffic) {
            if ($traffic->visits) {
                $traffic->visits++;
            }
        });
    }
}

交通中间件:

public function handle($request, Closure $next)
{
    $time = now();

    $visitor = $request->ip();
    $traffic = Traffic::firstOrCreate(['visitor' => $visitor]);
    $traffic->save();

    //Email notification
    $totalTraffic = Traffic::all()->sum('visits');
    $totalVisitors = Traffic::all()->count();

    \Mail::raw("New visit at {$time} from {$visitor}. You have over all {$totalTraffic} visits from {$totalVisitors} visitors.", function ($note) {
        $note->to('manager@mail.com');
    });

    return $next($request);
}