Laravel实现文章浏览数的统计

2017-08-23  本文已影响0人  ONEDAYLOG

本文主要基于Laravel5.3下,如何记录显示网页文章浏览数

插件 weboap/visitor
借阅 Laravel 文章浏览数统计 (VisitorRegistry)
借阅 在博客中实现浏览次数的统计

1.安装插件 weboap/visitor

将一下的require加入到composer.json中,然后运行composer update

{
    "require": {
        "weboap/visitor": "dev-master"
    }
}

将下面代码加入config/app.php中的service provider

 Weboap\Visitor\VisitorServiceProvider::class

执行 php artisan vendor:publish 注册到vendor 生成 vendor.php配置文件和 ×××_create_visitor_registry.php的数据表文件

php artisan migrate

生成数据表

2.下载和配置GeoLite2-City.mmdb用于IP地址获取所在地址

将下载的GeoLite2-City.mmdb解压并拷贝到项目中

//没有则新建
storage/geo/

这个时候我们就已经可以根据Ip地址记录网页浏览数

...
use Weboap\Visitor\Visitor;
...
    public $visitor;

    //依赖注入
    public function __construct(Visitor $visitor){
        $this->visitor = $visitor;
    }
...
//简单的调用
$this->visitor->log();

3.文章阅读量统计

修改XXX_visitor_registry.php

        public function up()
        {
            Schema::create('visitor_registry', function (Blueprint $table) {
                $table->increments('id');
                $table->string('ip', 32);
                $table->string('country', 4)->nullable();
                $table->string('city', 20)->nullable();//新增
                $table->integer('clicks')->unsigned()->default(0);

                $table->integer('users_id')->nullable();//新增
                $table->integer('hittable_id')->nullable();//新增
                $table->string('hittable_type')->nullable();//新增
                $table->timestamps();
            });
        }

生成VisitorRegistry模型后采用多态关联,文章阅读量,照片阅读量,各种阅读量都可以关联到这种表

class VisitorRegistry extends Model
{

    //
    protected $table = 'visitor_registry';

    protected $fillable = ['clicks'];

    public function hittable()
    {
        return $this->morphTo();
    }
}
class Articles extends Model
{
  ...
    protected $table = 'articles';

    public function hittable(){
        return $this->morphMany(VisitorRegistry::class, 'hittable');
    }
   ...
}

最后修改Weboap\Visitor\Visitor.php下的log()方法

/**
     * @param null $users_id
     * @param null $hit_id
     * @param null $hit_type
     * @return bool|void
     */
    public function log($users_id = null,$hit_id = null,$hit_type = null)
    {
        $ip = $this->ip->get();

        if (!$this->ip->isValid($ip)) {
            return;
        }

        //如果ip且$post_id对应ip存在,则该条数据的clicks+1
        if( $this->has( $ip ) && $this->hasHit($users_id,$hit_id,$hit_type, $ip))
        {
            //ip already exist in db.
            //$this->storage->increment( $ip );
            $visitor = VisitorRegistry::where('ip', $ip)
                ->where('users_id',$users_id)
                ->where('hittable_type',$hit_type)
                ->where('hittable_id', $hit_id)->first();

            $visitor->update(['clicks'=>$visitor->clicks+1]);

            return true;
        } else {
            $geo = $this->geo->locate($ip);

            $country = array_key_exists('country_code', $geo) ? $geo['country_code'] : null;
            $city = array_key_exists('city', $geo) ? $geo['city'] : null;

            //ip doesnt exist  in db
            $data = [
                'ip'         => $ip,
                'country'    => $country,
                'city'       => $city,
                'clicks'     => 1,
                'updated_at' => c::now(),
                'created_at' => c::now(),
                'users_id'=> $users_id,
                'hittable_id'=> $hit_id,
                'hittable_type'=> $hit_type
            ];
            $this->storage->create($data);
        }

        // Clear the database cache
        $this->cache->destroy('weboap.visitor');
    }

    public function hasHit($users_id,$hit_id,$hit_type, $ip)
    {
        return count(VisitorRegistry::where('ip', $ip)
            ->where('users_id',$users_id)
            ->where('hittable_type',$hit_type)
            ->where('hittable_id', $hit_id)->first())?true:false;
    }

经过修改,可以使用全新的log方法

 $this->visitor->log($user->id,$art->id,Articles::Class);
数据库图.png
上一篇下一篇

猜你喜欢

热点阅读