由于网上参考的两篇文章讲的不是特别适合自己,在下载和开发的过程中遇到不少的坑,所以就在前辈的基础上进行整理知识点。
参考1-在博客中实现浏览次数的统计-laravist
参考2-Laravel 文章浏览数统计 (VisitorRegistry)-PJBlog
浏览量统计的需求 :
用户访问文章页面–>取得ip地址和文章id,存入数据库 再次访问时根据ip和文章id判断是否新增记录
扩展工具:weboAp/Visitor 。
首先要用composer 加载weboAp/Visitor
在composer.json的require中添加,注意标点符号的遗漏和错误
{
"require ": {
"weboap/visitor ": "dev-master"
}
}
2.然后在命令行执行 composer update ,我使用的是 PhpStorm ,所以可以用 alt+F12 调出命令行,输入即可。
3.将Service添加到 config/app.php的 providers中,同样注意标点符号的遗漏和错误:
'Weboap\Visitor \VisitorServiceProvider '
4.之后在命令行(phpstorm->ALT+F12)里执行下面两个命令:
php artisan vendor :publish
php artisan migrate
5.到 http://dev.maxmind.com/geoip/geoip2/geolite2 “>http://dev.maxmind.com/geoip/geoip2/geolite2 下载geoip包(GeoLite2-City.mmdb),如果找不到,就到我放在CSDN的资源下载 geolite2CSDN下载地址 将它解压之后放到以下目录, geo 文件夹 需要自己创建的
storage/geo/
6.上面的步骤之后你将会得到一个表 visitor_registry,这里我们首先为 visitor_registry 添加一个字段 art_id 用于 One-To-Many 的关系
php artisan make :migration add_art_id_to_visitor_registry --table='visitor_registry'
7.在项目的 database 文件夹找到新生成的表格,名字是
日期+add_article_id_to_visitor_registry
在里面的up方法中写入
public function up()
{
Schema::table('visitor_registry', function (Blueprint $table) {
$table->integer('art_id')->unsigned()->index();
$table->foreign('art_id')->references('id')->on('article')->onDelete('cascade');
});
}
这边就是我遇到的坑之一,
首先
$table->integer('art_id')->unsigned()->index();
art_id是你文章表格的 id 列名
这边是在 visitor_registry 添加字段. 用于添加外键使用的
所以这边改成你需要的属性
$table->foreign('art_id')->references('id')->on('article')->onDelete('cascade');
这边是 visitor_registry 与你的表格添加外键.
这边也有一个坑,就是死活都无法添加进外键,
大概是这样↓↓↓好吧,我承认我暴走了= =翻来翻去找不到答案,
然后我就去睡了一觉,起来以后再翻翻stackoverflow,然后就解决了.
可能是你代码打错了,检查一下.
可能是主表的键没有设置无符号,这是国外友人提的,并被那个问主采纳了,那你就看看两个表的外键属性是否一致
最后这是我遇到的原因,大概是咸丰年前(其实就一个星期前),我开发博客系统的时候,把表格的引擎都改成了MyISAM ,而通过 migrate 生成的表格是默认InnoDB ,所以,它!就!添!加!不!成!功!
如果还不能解决,那我也没办法帮你了,科学上网,翻墙后出去大型基佬聚会会所stackoverflow看看
8.运行
php artisan migrate
9.接下来添加模型,
php artisan make :model VisitorRegistry
10.再接下来是在模型里面添加
protected $table = 'visitor_registry' ;
protected $fillable = ['clicks' ];
public function articles ()
{
return $this ->belongsTo('App\Article' );
}
11.再接下来就在你要计算浏览数的那个模型,也就是文章展示的模型中添加一对多的关系
public function visitors ()
{
return $this ->hasMany('App\VisitorRegistry' );
}
12.我们在第7步中给原先的表格添加了一个属性,所以我们需要修改原来扩展包里面的log()方法
在方法中添加参数
public function log ($art_id ) { }
在修改第二个If语句
if ( $this -> has( $ip ) && $this -> hasArticle($art_id ,$ip ) )
{
$visitor = VisitorRegistry::where ('ip' ,'=' ,$ip )-> where ('art_id' ,'=' ,$art_id )-> first();
$visitor -> update([ 'clicks' => $visitor -> clicks + 1 ] );
return true;
}
上面我们自己添加了一个 hasArticle($article_id,$ip),我们可以直接将这个方法写在 Visitor.php 中:
public function hasArticle($id ,$ip )
{
return count(VisitorRegistry::where ('art_id' ,'=' ,$id )-> where ('ip' ,'=' ,$ip )-> get()) > 0 ;
}
最后我们还要修改log()中的插入数据的数组数据$data
$data = array (
'ip' => $ip ,
'country' => $country ,
'clicks' => 1 ,
'art_id' => $art_id ,
'updated_at' => c::now(),
'created_at' => c::now()
);
完整的方法是:
public function log ($art_id )
{
$ip = $this ->ip->get();
if (!$this ->ip->isValid($ip )) {
return ;
}
if ($this ->has( $ip ) && $this ->hasArticle($art_id ,$ip ) ) {
$visitor = VisitorRegistry::where('ip' ,'=' ,$ip )->where('art_id' ,'=' ,$art_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 ;
$data = [
'ip' => $ip ,
'country' => $country ,
'clicks' => 1 ,
'art_id' => $art_id ,
'updated_at' => c::now(),
'created_at' => c::now()
];
$this ->storage->create($data );
}
$this ->cache->destroy('weboap.visitor' );
}
好了,super 完美.