Laravel 5.2 实现浏览文章统计次数
一、安装 weboAp/Visitor
先按官方提供的文档安装好,并测试。 测试方法:
// app/Http/Controllers/ArticleController.php
use Weboap\Visitor\Facades\VisitorFacade; // 使用切面
class ArticleController extends Controller
{
/**
* 文章详情页
*
* @return \Illuminate\Http\Response
*/
public function show($id)
{
VisitorFacade::log();
}
}
浏览器访问:http://localhost/article/1
看数据库表 visitor_registry
是否插入了一条数据。有则表明安装 weboAp/Visitor
成功,如果没有,请按官方文档再跑一遍。
二、定制
改表名
官方预定的表名是 visitor_registry
,我要改为的是 article_clicks
.
-
改
migration
文件内容如下:// database/migrations/2014_02_09_225721_create_article_clicks.php <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; class CreateArticleClicks extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('article_clicks', function (Blueprint $table) { $table->increments('id'); $table->string('ip', 32); $table->string('country', 4)->nullable(); $table->string('city', 20)->nullable(); // 新增 $table->integer('article_id'); // 新增 $table->integer('clicks')->unsigned()->default(0); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('article_clicks'); } }
改完之后,手动去数据库删除
visitor_registry
表。重新执行php artisan migrate
。 -
config/visitor.php
<?php return [ 'table' => 'article_clicks', // 改这里 ];
覆盖 Visitor
类的 log
方法,使其支持传入文章 id。改动后的使用方法为:VisitorFacade::log($article->id)
;
-
新建自定义
Visitor
类且继承Visitor
<?php namespace App\Visitor; use Weboap\Visitor\Visitor as WeVisitor; use Carbon\Carbon as c; use App\ArticleClick; class Visitor extends WeVisitor { public function log($articleId = NULL) { $ip = $this->ip->get(); if (!$this->ip->isValid($ip)) { return; } if ($this->has($ip) && $this->hasArticle($articleId, $ip)) { $visitor = ArticleClick::where('ip', $ip) ->where('article_id', $articleId) ->whereDate('updated_at', '!=', c::today()) ->first(); if ($visitor) { $visitor->update(['clicks'=>$visitor->clicks + 1]); } return; } 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, 'article_id' => $articleId, 'updated_at' => c::now(), 'created_at' => c::now(), ]; $this->storage->create($data); } // Clear the database cache $this->cache->destroy('weboap.visitor'); } public function hasArticle($id, $ip) { return count(ArticleClick::where('article_id', $id)->where('ip', $ip)->get()) > 0; } }
-
新建
VisitorServiceProvider
并继承VisitorServiceProvider
// app/Providers/VisitorServiceProvider.php <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Weboap\Visitor\VisitorServiceProvider as VS; use App\Visitor\Visitor; class VisitorServiceProvider extends VS { public function register() { parent::register(); } public function RegisterVisitor() { $this->app->singleton('visitor', function ($app) { return new Visitor( // 这是替换后的类 $app['Weboap\Visitor\Storage\VisitorInterface'], $app['Weboap\Visitor\Services\Geo\GeoInterface'], $app['ip'], $app['Weboap\Visitor\Services\Cache\CacheInterface'] ); }); $this->app->bind('App\Visitor\Visitor', function ($app) { // 关键在这里,狸猫换太子。 return $app['visitor']; }); } }
-
注册两个自定义的类。
// composer.json "autoload": { "classmap": [ "database", "app/Visitor/Visitor.php" // 增加这行 ], "psr-4": { "App\\": "app/" } },
// config/app.php providers: [ ... App\Providers\VisitorServiceProvider::class // 增加这行 ]
最终结果