2017-07-31 10 views
2

私のアプリケーションでページビューカウンタを実装したいと思います。私はこれまでやったことは、このメソッドを使用している:Laravelでページビューをカウントする

public function showpost($titleslug) { 
     $post = Post::where('titleslug','=',$titleslug)->firstOrFail(); 
     $viewed = Session::get('viewed_post', []); 
     if (!in_array($post->id, $viewed)) { 
      $post->increment('views'); 
      Session::push('viewed_post', $post->id); 
     } 
     return view('posts/show', compact('post', $post)); 
    } 

私はこのような人気のある記事一覧取得:

$popular_posts = Post::orderBy('views', 'desc')->take(10)->get(); 

しかし、私はに任意のより良い方法があるかどうかを知りたいのですがこれを行う ?現在の方法では、過去24時間以内に最も多く閲覧された投稿のリストを取得できますか?それはすべてありがとう!

+0

ページが表示されたときに保存すると、その情報を取得できますが、投稿が表示された回数だけカウンターを使用すると、最後のx分で表示されたものを並べ替えることはできません。 – milo526

+0

「アプリ」(私はウェブページを代わりに言う)の大きさ、言い換えればピークは何人ですか?または、統計情報を持っている場合、ピーク時にreq/mの数は何ですか?どのセッションドライバを使用していますか?ページビューは関連性の高いページだけを表示するか、後でデータを使用します(おそらく、「30日前にトップ10の記事/ページ」など)。 – Kyslik

+0

これは、ビューデータを格納するために別のテーブルを作成する必要があることを意味します。 @ milo526 –

答えて

4

@ milo526のコメントに引用されているように、インクリメントではなくユニークな方法で、すべてのヒットをページに記録できます。これにより、最も多く閲覧された投稿のリストを含む、アクセス情報を検索する多くの可能性があります。

ビューのレコードを保存するテーブルを作成します。

Schema::create("posts_views", function(Blueprint $table) 
     { 
      $table->engine = "InnoDB"; 

      $table->increments("id"); 
      $table->increments("id_post"); 
      $table->string("titleslug"); 
      $table->string("url"); 
      $table->string("session_id"); 
      $table->string("user_id"); 
      $table->string("ip"); 
      $table->string("agent"); 
      $table->timestamps(); 
     }); 

その後、対応するモデルを作成:

最後に
<?php namespace App\Models; 

class PostsViews extends \Eloquent { 

    protected $table = 'posts_views'; 

    public static function createViewLog($post) { 
      $postsViews= new PostsViews(); 
      $postsViews->id_post = $post->id; 
      $postsViews->titleslug = $post->titleslug; 
      $postsViews->url = \Request::url(); 
      $postsViews->session_id = \Request::getSession()->getId(); 
      $postsViews->user_id = \Auth::user()->id; 
      $postsViews->ip = \Request::getClientIp(); 
      $postsViews->agent = \Request::header('User-Agent'); 
    } 

} 

を、あなたの方法:

public function showpost($titleslug) 
{ 
    $post = PostsViews::where('titleslug', '=' ,$titleslug)->firstOrFail(); 

    PostsViews::createViewLog($post); 

    //Rest of method... 
} 

ほとんどを検索するには過去24時間の投稿を表示:

$posts = Posts::join("posts_views", "posts_views.id_post", "=", "posts.id") 
      ->where("created_at", ">=", date("Y-m-d H:i:s", strtotime('-24 hours', time()))) 
      ->groupBy("posts.id") 
      ->orderBy(DB::raw('COUNT(posts.id)', 'desc')) 
      ->get(array(DB::raw('COUNT(posts.id) as total_views'), 'posts.*')); 

PostsViewsでは、同じセッションからのヒットを考慮したくない場合に備えて、セッションIDなどのリスティングをさらに絞り込むのに役立つデータがあります。

このソリューションのいくつかの側面を最終的なコードに合わせる必要があるかもしれません。

+0

私はこれを試してみませんか? 'post_views'テーブルと' posts'テーブル? –

+0

私はいくつかのことを変えなければならなかったが、あなたは私にそのアイデアを与えた。ありがとう! –

+0

これは素晴らしいコンセプトです!私はまた、私が取り組んでいるプロジェクトのために少しそれを適応させました。 createViewLog()を更新して$ postsViews-> save()を呼び出すことを検討することもできます。そうしないと、ログエントリはテーブルに挿入されません。 – Benco

関連する問題