2018年4月

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文章浏览次数统计插件设置

文章阅读数是一个衡量传播价值的重要指标,有PV(Page View), UV(Unique View)等,本篇介绍下简单PV统计插件的使用方法。

Page View是指页面被访问的次数,单一用户多次访问页面或刷新页面均会被计算次数。

Unique View,独立访客数,指一天内访问该页面的人数,一般使用IP来区分,统一IP的多次访问不会被重复计数。

本篇介绍简单PV指标的插件使用方法,因本站访客寥寥无几,大部分都是自己的访问次数,所以PV并不能真实体现被浏览的情况,后续笔者会在此插件的基础上实现UV的统计方式。

- 阅读剩余部分 -