ami-hp/laravel-eye

此包最新版本(1.1.4)没有提供许可信息。

使用缓存和CronJob记录网站访问量

安装: 46

依赖: 0

建议者: 0

安全: 0

星标: 3

关注者: 1

分支: 0

开放问题: 0

类型:package

1.1.4 2023-10-30 20:29 UTC

This package is auto-updated.

Last update: 2024-09-30 02:05:13 UTC


README

laravel-eye Logo

Total Downloads Latest Stable Version License

适用于 Laravel 的 Php >=7.2 包。

此包是两个访问计数器包的集合

它根据用户的 Cookie 存储每次访问。目的是能够缓存访问以减少查询。对于比正常流量略高的网站,使用缓存更佳。

注意:如果您在缓存中保存大量数据,内存将被耗尽。限制取决于您的内存,但建议不要超过100万。

以下路径用于在用户访问您的可访问页面时存储访问记录

以下路径用于从存储中获取访问记录

安装

$ composer require ami-hp/laravel-eye
$ php artisan vendor:publish --provider="Ami\Eye\Providers\EyeServiceProvider"
$ php artisan migrate

注意:建议迁移默认的 jobsfailed_jobs 表,这些表是随着新的 Laravel 项目一起提供的。

配置

发布包文件后,您将在配置文件夹中有一个 eye.php 文件。

  1. 在此处,您可以定义您的访问表名称。

    'table_name' => 'eye_visits',
  2. 为了防止内存错误,您可以指定缓存中保存的最大访问量。达到最大值后,所有访问都将插入数据库。您还可以更改您的缓存密钥。

    'cache' => [  
        'key' => 'eye__records',  
        'max_count' => 1000000,  
    ],
  3. 当用户到达您的页面时,将设置一个 Cookie。您可以在任何时候更改 Cookie 的密钥。有效期设置为5年,您也可以更改它。

    'cookie' =>[  
        'key' => 'eye__visitor',  
        'expire_time' => 2628000, //in minutes aka 5 years  
    ],
  4. 此包使用两个包来解析用户代理:jenssegers/agentua-parser/uap-php。默认情况下,它设置为 jenssegers。您可以将它更改为 UAParser

    'default_parser' => 'jenssegers',
  5. 您可以选择是否存储爬虫访问。此包将使用 jaybizzle/crawler-detect 来检测爬虫。

    'ignore_bots' => true,
  6. 如果您想使用作业来提高插入速度,此包将为您完成。您可以随时将其更改为 false。

    'queue' => true,

迁移

   Schema::create(config('eye.table_name'), function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->mediumText('unique_id')->nullable();
            $table->string('method')->nullable();
            $table->mediumText('request')->nullable();
            $table->mediumText('url')->nullable();
            $table->mediumText('referer')->nullable();
            $table->text('languages')->nullable();
            $table->text('useragent')->nullable();
            $table->text('headers')->nullable();
            $table->text('device')->nullable();
            $table->text('platform')->nullable();
            $table->text('browser')->nullable();
            $table->ipAddress('ip')->nullable();
            $table->string('collection')->nullable();
            $table->nullableMorphs('visitable'); // object model
            $table->nullableMorphs('visitor'); // subject model
            $table->timestamp('viewed_at')->useCurrent();
        });

用法

如何记录访问

您可以用各种方式记录访问,但首先,您必须设置数据以形成一个要记录的访问模型。

步骤 1:从开始设置访问数据

访问模型连接到上面显示的访问表。可以从开始到链式方法的结束设置数据。

示例

$post = Post::first();
$user = User::first();
$name = 'name of collection';

//if you wanted to set data
$eye = eye($post)->setVisitor($user)->setCollection($name);

//also if you didn't want to set data you can
$eye = eye();

设置可访问模型

如果不使用此方法,默认的可访问模型设置为NULL

$post = Post::first();

eye($post)
//or
eye()->setVisitable($post);

设置访问者模型

如果不使用此方法,默认的可访问模型设置为auth()->user()

$user = User::first();

eye()->setVisitor($user);

设置集合

如果不使用此方法,默认设置为NULL

$name = 'name of collection';

eye()->setCollection($name);

步骤 2:选择存储方法

您可以选择存储位置,即您希望存储访问的地方。

示例

eye()->viaDatabase();
//or
eye()->viaCache()

将访问记录存储在数据库中

在数据库中存储访问是一种常见的数据存储方式。通过使用此方法,每次用户访问时,都会执行查询以将数据插入数据库。默认情况下,此方法使用队列来插入数据,但您可以通过在配置文件eye.php中将队列值更改为false来始终关闭它。

优点:通过将访问模型连接到数据库,可以更好地控制访问。

缺点:与数据库交互需要时间。如果您的网站同时有大量访客,这将减慢您的网站速度。

eye($post)->viaDatabase();

将访问记录存储在缓存中

使用缓存作为存储是绕过将数据插入数据库的插入。但是,您可以将数据保留在缓存中,直到您想要的时间。可以保存的访问次数有限,您可以通过在配置文件eye.php中更改cache.max_count来控制。达到最大值后,包将自动将访问推送到数据库。如果需要,还可以更改缓存键名。

eye($post)->viaCache();

将访问记录存储在 Redis 中

您唯一需要做的就是将CACHE_DRIVER更改为redis,以便包通过缓存使用Redis。存储方法仍然是viaCache()

步骤 3:通过存储方法设置数据

您也可以在此阶段设置数据,而不是在选择存储方法之前设置。没有区别。

注意:这些方法包含在一个接口中,因此它们在所有存储方法中都有效。

示例

$eye = eye()->viaDatabase(); //OR
$eye = eye()->viaCache();

$post = Post::first();
$user = User::first();
$name = 'name of collection';

$eye->collection($name)
    ->visitor($user)
    ->visitable($user);

设置可访问模型

如果不使用此方法,默认的可访问模型设置为NULL

$post = Post::first();

eye()->viaCache()->visitable($post);
//SAME AS
eye($post)->viaCache();

设置访问者模型

如果不使用此方法,默认的可访问模型设置为auth()->user()

$user = User::first();

eye()->viaCache()->visitor($user);
//SAME AS
eye()->setVisitor($user)->viaCache();

设置集合

如果不使用此方法,默认设置为NULL

$name = 'name of collection';

eye()->viaCache()->collection($user);
//SAME AS
eye()->setCollection($name)->viaCache();

步骤 4:定义条件

仅记录一次

通过使用此方法,包将检查用户是否已存储记录。如果用户已经访问了页面,则不会记录新的访问。

它使用包为用户设置的cookie工作,并将存储为unique_id

注意:您可以通过更改配置文件eye.php中的cookie.keycookie.expire_time来更改cookie键和过期时间。

$name = 'name of collection';

eye()->viaCache()->once();

步骤 5:记录访问

最后,您可以将访问模型插入到数据库或缓存中。结构基本上是这样的

Step1->Step2->Step3->Step4->record(bool $once = false, ?Model $visitable = null, ?Model $visitor = null);

这意味着您也可以通过此方法设置可访问的和访问者。

$post = Post::first();
$user = User::first();

eye()->viaCache()->record(true , $post , $user);
//SAME AS
eye($post)->viaCache()->visitor($user)->once()->record();

附加示例

$post = Post::first();
$user = User::first();
$name = 'name of collection';

eye()->viaDatabase()->collection($name)->visitable($post)->record();
eye($post)->viaCache()->once()->record(); // Recommended

如何检索访问

您可能希望列出带有详细信息的访问或只是计数。所有这些都是可能的。您可以分别或全部组合为每个存储执行此操作。

步骤与记录步骤非常相似。

如何从每个存储中检索

如果您需要从每个存储中单独检索数据,只需使用它们的存储方法即可。

eye()->viaCache() 
// OR
eye()->viaDatabase()

注意:以下步骤适用于所有存储方法。

步骤 1:选择所需的数据

它的工作方式与设置数据完全相同。

选择可访问或 URL

如果您将模型传递给可访问方法,它将选择具有可访问模型的历史记录。如果没有,它将选择路由所在的URL。这也适用于NULL

对于可访问项

$post = Post::first(); // or NULL

eye($post)->viaCache(); // Simplified
//or
eye()->setVisitable($post)->viaCache();
//or
eye()->viaCache()->visitable($post); // Humanized

结果

->where('visitable_id'   , $post->id)
->where('visitable_type' , get_class($post))

对于URL

eye()->viaCache();

结果

->where('url' , request()->fullUrl())

有时您不需要为查询启用WHERE子句。您可以使用visitable(false)禁用它。

eye()->viaCache()->visitable(false);

选择访问者

如果您想获取特定访问者创建的访问记录,可以这样做。您也可以传递NULL

此方法与记录步骤中的方法的不同之处在于,您需要将$whereMode参数更改为true。否则,它只是设置访问者。

$user = User::first(); // or NULL

eye()->viaCache()->visitor($user , true);

结果

->where('visitor_id'   , $user->id)
->where('visitor_type' , get_class($user))

选择集合

$name = 'name of collection';

eye()->viaCache()->collection($name);

结果

->where('collection' , $name)

步骤 2:添加更多条件

选择一段时间内的访问记录

period()方法传递一个Period类作为参数。

您可以在Cryildewit/Period中阅读有关此类别的所有信息。

$startDateTime = '1997-01';
$endDateTime   = '2023-08-17 10:11:00';
$period = Period::create($startDateTime , $endDateTime); //example

eye()->viaCache()->period($period);

结果

if ($startDateTime !== null && $endDateTime === null) 
    ->where('viewed_at', '>=', $startDateTime);
elseif ($startDateTime === null && $endDateTime !== null)
    ->where('viewed_at', '<=', $endDateTime);
elseif ($startDateTime !== null && $endDateTime !== null)
    ->whereBetween('viewed_at', [$startDateTime, $endDateTime]);

选择具有唯一值的访问记录

列中可能存在多个具有相同值的行。默认情况下,该方法使用unique_id列,这是用户的cookie。

通过缓存
$column = 'unique_id';
eye()->viaCache()->unique($column);

结果

->unique($column)
通过数据库

问题是,它对所有存储方法的工作方式并不相同。在viaCache中,它用于检索访问详情和计数,但在viaDatabase中,它仅用于计数。

$column = 'unique_id';
eye()->viaCache()->unique($column)->count();

结果

->distinct()->count($column);

步骤 3:从存储中检索数据

最后,您只能使用count()get()来检索数据

结构基本上是这样的

Step1->Step2->count(); // returns Int
Step1->Step2->get();   // returns collection of Visit models

发挥创意。

示例

eye($post)->viaCache()
          ->unique()
          ->count();
// OR
eye()->viaDatabase()
     ->collection('name')
     ->visitor($user)
     ->get();

如何从多个存储中检索

当使用缓存时,达到最大包量后,将访问记录推送到数据库。或者,您可能意外地使用了多个存储。该包提供了一次性使用多个存储方法的方法。

步骤 1:选择存储方法

选择全部

非常简单。

eye()
// or
eye()->via('database' , 'cache'); // means both of them

步骤 2:选择访问模型

就像您正在单独使用存储一样进行操作。效果相同。

选择可访问模型

$post = Post::first();

eye($post);
//or
eye()->visitable($post);

选择访问者模型

$user = User::first();

eye($post);
//or
eye()->visitor($post);

选择集合

$name = 'collection';

eye($post)->collection($name);

步骤 2:添加更多条件

选择时间段

$startDateTime = '1997-01';
$endDateTime   = '2023-08-17 10:11:00';
$period = Period::create($startDateTime , $endDateTime); //example

eye()->period($period);

选择唯一值

默认情况下,它设置为unique_id

$column = 'platform';

eye()->unique($column);

如前所述,它仅在数据库的计数上工作。

步骤 3:检索访问记录

结合先前的方法,并添加get()count()

示例

eye($post)->collection($name)->unique()->count();
eye()->via('cache' , 'database')->visitor($user)->get();

如何删除访问记录

有时您需要从存储中删除一些记录的访问记录。此包为您提供了一些单独执行或一次性删除所有记录的方法。

注意:唯一方法在此不适用

删除所有

  • 步骤 1:选择存储方法
  • 步骤 2:截断

示例

eye()->truncate(); // Removes All Visits in Every Storage
eye()->viaCache()->truncate(); // Removes All Visits in a storage
eye()->via('database' , 'cache')->truncate(); // Removes All Visits in selected storages

删除所选访问记录

选择访问记录的工作方式与检索它们的工作方式完全相同。

  • 步骤 1:选择存储方法
  • 步骤 2:选择访问记录
  • 步骤 3:删除

示例

eye($post)->collection($name)->delete();
eye()->viaCache()->visitor($user , true)->delete();

eye()->via('cache')
     ->visitable(false)
     ->visitor($user , true)
     ->collection($name)
     ->delete();

如何使用特性

您也可以通过您修改后的模型获取访问记录数据。

EyeVisitable 特性

EyeVisitable添加到您的可访问模型中。

观察者

可访问观察者将监视您模型的活动,因此,当您的模型被(强制)删除时,访问记录也会通过此代码被删除。

public function deleted(Model $visitable)
{
    if ($visitable->isForceDeleting())
        eye($visitable)->delete();
}

关系

为了使用预加载,您将需要数据库关系。

public function visits()
{
    return $this->morphMany(Visit::class, 'visitable');
}

用法示例

$posts = Post::with('visits')->get();

foreach ($posts as $post){
    $post->visits; // collection of visits
}

//OR

$posts = Post::withCount('visits')->get();

foreach ($posts as $post){
    $post->visits_count; // int
}

如您所知,多对多关系与数据库相关联,因此我们需要以某种方式访问缓存的访问记录。此方法也已添加到特性中,以更容易地访问缓存的访问记录。

public function cachedVisits(?string $unique = null , ?string $collection = null , ?Model $visitor = null): Collection  

用法示例

$visits = $post->cachedVisits(); //collection of visits
// OR
$visits = $post->cachedVisits('unique_id' , 'name of collection' , $user);


$visits->count(); //int

EyeVisitor 特性

EyeVisitor添加到您的访问者模型中,其余部分与可访问特性类似。

观察者

public function deleted(Model $visitor)
{
    if ($visitor->isForceDeleting())
        eye()->visitor($visitor)->visitable(false)->delete();
}

关系

public function visits()
{
    return $this->morphMany(Visit::class, 'visitor');
}
public function cachedVisits(?string $unique = null , ?string $collection = null , $visitable = false): Collection