ami-hp / laravel-eye
使用缓存和CronJob记录网站访问量
Requires
- php: >=7.2
- ext-json: *
- illuminate/cache: ^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
- illuminate/contracts: ^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
- illuminate/database: ^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
- illuminate/http: ^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
- illuminate/support: ^5.0|^6.0|^7.0|^8.0|^9.0|^10.0
- jaybizzle/crawler-detect: ^1.0
- jenssegers/agent: ^2.6
- nesbot/carbon: ^2.0
- ua-parser/uap-php: ^3.9
This package is auto-updated.
Last update: 2024-09-30 02:05:13 UTC
README
适用于 Laravel 的 Php >=7.2 包。
此包是两个访问计数器包的集合
- shetabit/visitor
- cyrildewit/eloquent-viewable
- 以及一些额外功能。
它根据用户的 Cookie 存储每次访问。目的是能够缓存访问以减少查询。对于比正常流量略高的网站,使用缓存更佳。
注意:如果您在缓存中保存大量数据,内存将被耗尽。限制取决于您的内存,但建议不要超过100万。
以下路径用于在用户访问您的可访问页面时存储访问记录
以下路径用于从存储中获取访问记录
安装
$ composer require ami-hp/laravel-eye
$ php artisan vendor:publish --provider="Ami\Eye\Providers\EyeServiceProvider"
$ php artisan migrate
注意:建议迁移默认的 jobs 和 failed_jobs 表,这些表是随着新的 Laravel 项目一起提供的。
配置
发布包文件后,您将在配置文件夹中有一个 eye.php
文件。
-
在此处,您可以定义您的访问表名称。
'table_name' => 'eye_visits',
-
为了防止内存错误,您可以指定缓存中保存的最大访问量。达到最大值后,所有访问都将插入数据库。您还可以更改您的缓存密钥。
'cache' => [ 'key' => 'eye__records', 'max_count' => 1000000, ],
-
当用户到达您的页面时,将设置一个 Cookie。您可以在任何时候更改 Cookie 的密钥。有效期设置为5年,您也可以更改它。
'cookie' =>[ 'key' => 'eye__visitor', 'expire_time' => 2628000, //in minutes aka 5 years ],
-
此包使用两个包来解析用户代理:jenssegers/agent 和 ua-parser/uap-php。默认情况下,它设置为 jenssegers。您可以将它更改为 UAParser。
'default_parser' => 'jenssegers',
-
您可以选择是否存储爬虫访问。此包将使用 jaybizzle/crawler-detect 来检测爬虫。
'ignore_bots' => true,
-
如果您想使用作业来提高插入速度,此包将为您完成。您可以随时将其更改为 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.key
和cookie.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