Laravel访客柜台

时间:2015-04-17 08:43:13

标签: php mysql laravel-4

我试图在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));
}

工作正常,但问题是,我的数据库列总是添加一个新值。

所以这是我的数据库: With the table 'visitor'

从表格'访客'。

它不断添加新的IP,hit和visit_date ...

如何才能从今天(当天)更新点击次数,如果过了一天,设置新的IP值并计入该列?

5 个答案:

答案 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 地址字段