初始cookie方法

/**
* 阅读统计
* 调用<?php get_post_view($this); ?>
*/
function Postviews($archive) {
    $db = Typecho_Db::get();
    $cid = $archive->cid;
    if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) {
        $db->query('ALTER TABLE `'.$db->getPrefix().'contents` ADD `views` INT(10) DEFAULT 0;');
    }
    $exist = $db->fetchRow($db->select('views')->from('table.contents')->where('cid = ?', $cid))['views'];
    if ($archive->is('single')) {
        $cookie = Typecho_Cookie::get('contents_views');
        $cookie = $cookie ? explode(',', $cookie) : array();
        if (!in_array($cid, $cookie)) {
            $db->query($db->update('table.contents')
                ->rows(array('views' => (int)$exist+1))
                ->where('cid = ?', $cid));
            $exist = (int)$exist+1;
            array_push($cookie, $cid);
            $cookie = implode(',', $cookie);
            Typecho_Cookie::set('contents_views', $cookie);
        }
    }
    echo $exist == 0 ? '0' : $exist.' ';
}

原函数  Postviews  的目的是统计文章的阅读量。它首先检查数据库表  table.contents  中是否存在 views 字段,如果不存在则添加。

在文章页面$archive->is('single') 时,通过检查用户的 contents_views Cookie 来判断用户是否已经阅读过该文章。如果没有阅读过,则增加文章的浏览量,并更新Cookie,很显然,这种方式的浏览量增加比较缓慢。


要实现每刷新一次浏览量加一,就不需要通过 Cookie 来判断用户是否已经阅读过该文章了,直接在每次页面加载时增加浏览量即可。

刷新逻辑方法

/**
 * 阅读统计
 * 调用<?php get_post_view($this);?>
 */
function Postviews($archive) {
    $db = Typecho_Db::get();
    $cid = $archive->cid;
    // 检查并添加views字段
    if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) {
        $db->query('ALTER TABLE `'.$db->getPrefix().'contents` ADD `views` INT(10) DEFAULT 0;');
    }
    // 获取当前浏览量
    $exist = $db->fetchRow($db->select('views')->from('table.contents')->where('cid =?', $cid))['views'];
    // 每次加载页面都增加浏览量
    $newViews = (int)$exist + 1;
    $db->query($db->update('table.contents')
        ->rows(array('views' => $newViews))
        ->where('cid =?', $cid));
    echo $newViews;
}

先检查数据库表中是否存在 views 字段,不存在则添加。接着获取当前文章的浏览量 $exist 。然后直接将浏览量加一得到 $newViews 
这样,每次页面刷新,文章的浏览量都会加一,你更喜欢哪个呢?

调用与输出

//上边函数放在功能函数文件,一般是function.php
//下面在要显示的地方输出即可
<?php Postviews($this); ?>

不过浏览量多了,就显得很臃肿,就需要转换单位了,1000以上的阅读量可以转化为1k,10000以上为1w。
例如 1800 转换为1.8k
或者 66600 转换为 6.66w

阅读量转化

function convert($num) 
{
    if ($num >= 100000)
    {
        $num = round($num / 10000) .'W+';
    } 
    else if ($num >= 10000) 
    {
        $num = round($num / 10000, 1) .'W+';
    } 
    else if($num >= 1000) 
    {
        $num = round($num / 1000, 1) . 'K+';
    }

    return $num;
}

又出了新问题,最近在主页文章列表也加了浏览量函数,导致每次打开首页,每篇文章浏览量都加一,我们可以加个判定,优化一下

/**
 * 阅读统计
 * 调用<?php get_post_view($this);?>
 */
function Postviews($archive) {
    if (!$archive->is('single')) {
        // 如果不是文章详情页,直接返回,不进行浏览量统计
        return;
    }
    $db = Typecho_Db::get();
    $cid = $archive->cid;
    // 检查并添加views字段
    if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) {
        $db->query('ALTER TABLE `'.$db->getPrefix().'contents` ADD `views` INT(10) DEFAULT 0;');
    }
    // 获取当前浏览量
    $exist = $db->fetchRow($db->select('views')->from('table.contents')->where('cid =?', $cid))['views'];
    // 每次加载页面都增加浏览量
    $newViews = (int)$exist + 1;
    $db->query($db->update('table.contents')
        ->rows(array('views' => $newViews))
        ->where('cid =?', $cid));
    echo $newViews;
}

通过  $archive->is('single')  判断当前页面是否为文章详情页。如果不是文章详情页,则直接返回,不执行浏览量增加。只有在文章详情页时,才会执行。

又又又来了,由于上述代码不在首页时,直接返回,不执行增加也不执行显示。所以首页想显示,同时刷新不增加,只在文章详情增加。可以将获取浏览量和增加浏览量的逻辑分开。只在文章详情页增加浏览量,在文章列表页和文章详情页都获取并显示浏览量。

最终代码

/**
 * 获取文章浏览量
 */
function getPostViews($cid) {
    $db = Typecho_Db::get();
    // 检查并添加views字段
    if (!array_key_exists('views', $db->fetchRow($db->select()->from('table.contents')))) {
        $db->query('ALTER TABLE `'.$db->getPrefix().'contents` ADD `views` INT(10) DEFAULT 0;');
    }
    $exist = $db->fetchRow($db->select('views')->from('table.contents')->where('cid =?', $cid))['views'];
    return $exist;
}

/**
 * 阅读统计
 * 调用<?php get_post_view($this);?>
 */
function Postviews($archive) {
    if ($archive->is('single')) {
        $db = Typecho_Db::get();
        $cid = $archive->cid;
        // 获取当前浏览量
        $exist = getPostViews($cid);
        // 每次加载页面都增加浏览量
        $newViews = (int)$exist + 1;
        $db->query($db->update('table.contents')
           ->rows(array('views' => $newViews))
           ->where('cid =?', $cid));
        echo $newViews;
    } else {
        $cid = $archive->cid;
        echo getPostViews($cid);
    }
}