Typecho下Unique Page浏览计数插件

Typecho下Unique Page浏览计数插件

前面文章分享了网友的Page View插件,Views, 但是因为本人网站其实大部分时间都是自己在访问,因此基于PV的访问可能更多的是自己的访问量,对于后续网站检索的数据无法真实体现。故而在此基础上修改了一种基于Unique Page的浏览计数方法。

实现原理

相对于PV每一次文章内容也被浏览会增加一次计数,这里的UV则是根据客户端访问IP计数,每篇文章每一个IP在同一天的多次访问只记为1,最后相加显示之和便是文章的UV数。

代码

<?php
/**
 * Typecho 版 Unique Views
 * 
 * @package UViews 
 * @author Ray Lei
 * @version 0.0.1
 * @update: 2018.04.09
 * @link http://raylei.cn/
 */
class UViews_Plugin implements Typecho_Plugin_Interface
{
    /**
     * 激活插件方法,如果激活失败,直接抛出异常
     * 
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function activate()
    {
        Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('UViews_Plugin', 'viewsCounter');

        $db = Typecho_Db::get();
        $prefix = $db->getPrefix();

        //如果已启用过该插件则不在修改数据库
        //SELECT * FROM `typecho_options` where name = 'plugins' and value like '%UViews_Plugin%'
        $result = $db->fetchRow($db->select()->from('table.options')->where('name=?', 'plugins')->where('value like ?', '%UViews_Plugin%'));

        if (empty($result)) {
          $db->query('create table typecho_content_views(
            id int primary key auto_increment,
            cid int, ip varchar(32), 
            views int,
            lastViewDate datetime
            );');
      }
  }

    /**
     * 禁用插件方法,如果禁用失败,直接抛出异常
     * 
     * @static
     * @access public
     * @return void
     * @throws Typecho_Plugin_Exception
     */
    public static function deactivate(){}
    
    /**
     * 获取插件配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form 配置面板
     * @return void
     */
    public static function config(Typecho_Widget_Helper_Form $form){}

    /**
     * 个人用户的配置面板
     * 
     * @access public
     * @param Typecho_Widget_Helper_Form $form
     * @return void
     */
    public static function personalConfig(Typecho_Widget_Helper_Form $form){}

    // Function to get the client ip address
    public static function get_client_ip_env() {
        $ipaddress = '';
        if (getenv('HTTP_CLIENT_IP'))
            $ipaddress = getenv('HTTP_CLIENT_IP');
        else if(getenv('HTTP_X_FORWARDED_FOR'))
            $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
        else if(getenv('HTTP_X_FORWARDED'))
            $ipaddress = getenv('HTTP_X_FORWARDED');
        else if(getenv('HTTP_FORWARDED_FOR'))
            $ipaddress = getenv('HTTP_FORWARDED_FOR');
        else if(getenv('HTTP_FORWARDED'))
            $ipaddress = getenv('HTTP_FORWARDED');
        else if(getenv('REMOTE_ADDR'))
            $ipaddress = getenv('REMOTE_ADDR');
        else
            $ipaddress = 'UNKNOWN';

        return $ipaddress;
    }

    /**
     * 加入 beforeRender
     * 
     * @access public
     * @return void
     */
    public static function viewsCounter()
    {
        // 访问计数
        if (Typecho_Widget::widget('Widget_Archive')->is('single')) {
            $db = Typecho_Db::get();
            $cid = Typecho_Widget::widget('Widget_Archive')->cid;
            $row = $db->fetchRow($db->select('ip, views, lastViewDate')->from('table.content_views')->where('cid = ?', $cid)->where('ip= ?', UViews_Plugin::get_client_ip_env()));

            //如果不存在,则新增,否则根据访问时间来更新计数和上次访问时间
            if (empty($row)) {
                $insert  = $db->insert('table.content_views')->rows(array('ip' =>UViews_Plugin::get_client_ip_env() , 'cid'=>$cid,'views'=>1, 'lastViewDate'=> date("Y-m-d H:i:s")));
                $insertret = $db->query($insert);
            }else{
                $date = new DateTime($row["lastViewDate"]);
                if(date("Y-m-d") != $date->format('Y-m-d'))
                 $db->query($db->update('table.content_views')->rows(array('views'=>(int)$row['views']+1, 'lastViewDate'=>date('Y-m-d H:i:s')))->where('cid=?', $cid));
             else
                 $db->query($db->update('table.content_views')->rows(array('lastViewDate'=>date('Y-m-d H:i:s')))->where('cid=?', $cid));
         }

     }
 }

    /**
     * 输出访问次数
     *
     * 语法: UViews_Plugin::theViews();
     * 输出: '访问: xx,xxx 次'
     *
     * 语法: UViews_Plugin::theViews('有 ', ' 次点击');
     * 输出: '有 xx,xxx 次点击'
     *
     * @access public
     * @param string  $before 前字串
     * @param string  $after  后字串
     * @param bool    $echo   是否显示 (0 用于运算,不显示)
     * @return string
     */
    public static function theViews($before = '(UV)访问: ', $after = ' 次', $echo = 1)
    {
        $db = Typecho_Db::get();
        $cid = Typecho_Widget::widget('Widget_Archive')->cid;
        $row = $db->fetchRow($db->select(array('sum(views)' => 'ViewCount'))->from('table.content_views')->where('cid = ?', $cid));
        if ($echo)
            echo $before, number_format($row['ViewCount']), $after;
        else
            return $row['ViewCount'];
    }    
}

插件的使用方法:将上述代码命名为Plugin.php, 在usr/Plugins/下新建UViews文件夹,然后上传该文件;

后续操作见之前Views插件介绍文章: Typecho文章浏览次数统计插件设置.

最后,在需要使用访问计数的地方添加如下代码即可:

<?php UViews_Plugin::theViews(); ?>

标签: typecho, VIews, 浏览计数

已有 5 条评论

  1. yugiwu yugiwu

    感谢,这个还有PV统计都非常好用~~~

    1. 如果能对别人有点帮助,还是能让我感到很欣慰的

  2. 云武 云武

    能获取 All Views 吗?

    1. All view指的时page view,就是不去重,只要访问就算吗?
      如果是这样的话,是可以的。

  3. cfepm cfepm

    我用手机换移动网络访问后,统计没增加,很奇怪

添加新评论