我试图在Laravel建立一个访客柜台......
我不知道将代码放入内部的最佳位置是什么,以便在每个页面上加载......但我把它放在routes.php ....
我想我最好将它放在basecontroller中?
但好吧,我的代码现在看起来像这样:
//stats
$date = new \DateTime;
$check_if_exists = DB::table('visitor')->where('ip', $_SERVER['REMOTE_ADDR'])->first();
$get_visit_day = DB::table('visitor')->select('visit_date')->where('ip', $_SERVER['REMOTE_ADDR'])->first();
$value = date_create($get_visit_day->visit_date);
if(!$check_if_exists)
{
DB::table('visitor')->insert(array('ip' => $_SERVER['REMOTE_ADDR'], 'hits' => '1', 'visit_date' => $date));
}else{
DB::table('visitor')->where('ip', $_SERVER['REMOTE_ADDR'])->increment('hits');
}
$value = date_create($get_visit_day->visit_date);
if ($check_if_exists && date_format($value, 'd') != date('d')) {
DB::table('visitor')->insert(array('ip' => $_SERVER['REMOTE_ADDR'], 'hits' => '1', 'visit_date' => $date));
}
工作正常,但问题是,我的数据库列总是添加一个新值。
所以这是我的数据库:
从表格'访客'。
它不断添加新的IP,hit和visit_date ...
如何才能从今天(当天)更新点击次数,如果过了一天,设置新的IP值并计入该列?
答案 0 :(得分:13)
我对此并不是100%肯定,但你应该可以做这样的事情。它没有经过测试,可能有更优雅的方式,但它是你的起点。
更改表格
将visit_date (datetime)
列更改为visit_date (date)
和visit_time (time)
列,然后创建id
列作为主键。最后,将ip + date
设置为唯一键,以确保您无法在一天内输入两次相同的IP。
创建一个雄辩的模型
这只是为了方便:为表格制作一个Eloquent模型,这样您就不必一直使用Fluent(查询构建器):
class Tracker extends Eloquent {
public $attributes = [ 'hits' => 0 ];
protected $fillable = [ 'ip', 'date' ];
protected $table = 'table_name';
public static function boot() {
// Any time the instance is updated (but not created)
static::saving( function ($tracker) {
$tracker->visit_time = date('H:i:s');
$tracker->hits++;
} );
}
public static function hit() {
static::firstOrCreate([
'ip' => $_SERVER['REMOTE_ADDR'],
'date' => date('Y-m-d'),
])->save();
}
}
现在你应该能够通过调用它来做你想做的事情:
Tracker::hit();
答案 1 :(得分:5)
查看您的代码并阅读您的描述,我假设您想要计算每天IP地址的点击次数。您可以使用Eloquent的updateOrNew()
方法执行此操作:
$ip = Request::getClientIp();
$visit_date = Carbon::now()->toDateString();
$visitor = Visitor::findOrNew(compact('ip', 'visit_date'));
$visitor->increment('hits');
但是,我会将其添加到队列中,这样您就不会在每个请求中访问数据库,并且可以通过后台进程增加命中数:
Queue::push('RecordVisit', compact('ip', 'visit_date'));
就在何处引导此问题而言,App::before()
过滤器听起来像是一个很好的候选者:
App::before(function($request)
{
$ip = $request->getClientIp();
$visit_date = Carbon::now()->toDateString();
Queue::push('RecordVisit', compact('ip', 'visit_date'));
);
您可以更进一步,通过在服务提供商中侦听此事件并在那里解雇您的队列作业,以便您的访问计数器是其自己的独立组件,并且可以轻松地从此项目和任何其他项目中添加或删除
答案 2 :(得分:3)
感谢@Joe帮我解决问题!
@Martin,你也感谢,但是@Joe的脚本为我的问题工作。
解决方案:
Tracker::hit();
在我的App :: before();
中新课程:
<?php
class Tracker Extends Eloquent {
public $attributes = ['hits' => 0];
protected $fillable = ['ip', 'date'];
public $timestamps = false;
protected $table = 'visitor';
public static function boot() {
// When a new instance of this model is created...
static::creating(function ($tracker) {
$tracker->hits = 0;
} );
// Any time the instance is saved (create OR update)
static::saving(function ($tracker) {
$tracker->visit_date = date('Y-m-d');
$tracker->visit_time = date('H:i:s');
$tracker->hits++;
} );
}
// Fill in the IP and today's date
public function scopeCurrent($query) {
return $query->where('ip', $_SERVER['REMOTE_ADDR'])
->where('date', date('Y-m-d'));
}
public static function hit() {
static::firstOrCreate([
'ip' => $_SERVER['REMOTE_ADDR'],
'date' => date('Y-m-d'),
])->save();
}
}
命名为'tracker':)
答案 3 :(得分:0)
public $attributes = ['hits' => 0];
protected $fillable = ['ip', 'date'];
public $timestamps = false;
protected $table = 'trackers';
public static function boot() {
// When a new instance of this model is created...
parent::boot();
static::creating(function ($tracker) {
$tracker->hits = 0;
} );
// Any time the instance is saved (create OR update)
static::saving(function ($tracker) {
$tracker->visit_date = date('Y-m-d');
$tracker->visit_time = date('H:i:s');
$tracker->hits++;
} );
}
// Fill in the IP and today's date
public function scopeCurrent($query) {
return $query->where('ip', $_SERVER['REMOTE_ADDR'])
->where('date', date('Y-m-d'));
}
public static function hit() {
/* $test= request()->server('REMOTE_ADDR');
echo $test;
exit();*/
static::firstOrCreate([
'ip' => $_SERVER['REMOTE_ADDR'],
'date' => date('Y-m-d'),
// exit()
])->save();
}
在laravel 5.7中,它需要parent :: boot(),否则它将显示未定义的索引:App \ Tracker https://github.com/laravel/framework/issues/25455
答案 4 :(得分:0)
这是我所做的非常基本的事情,但可以轻松构建它并为访问者添加过滤器,每天,每月,每年等等。
我将以下代码添加到 web.php 文件中的所有路由之上,以便在站点上的每个请求上运行,因此无论访问者登陆哪个页面,只有当 IP 地址唯一时,才会将 IP 地址保存到数据库中访客不会不断增加访客数量
// Web.php
use App\Models\Visitor
$unique_ip = true;
$visitors = Visitor::all();
foreach($visitors as $visitor){
if($visitor->ip_address == request()->ip()){
$unique_ip = false;
}
}
if($unique_ip == true){
$visitor = Visitor::create([
'ip_address' => request()->ip(),
]);
}
Routes...
模型很简单,只有一个 ip 地址字段