通常我们在PHP开发过程中遇到有交互环节,通常会使用cookies或者session来记录一些用户变量。
同时我们在做wordpress开发时,程序本身给我们提供了很多的hook(钩子),用来在特定的环节执行相关的代码。
wp_head钩子不支持写入session和cookies,init钩子支持写入,但不能获取到wp_query的内容,wp钩子可剪得两者!
这里通过一个示例来说一下在使用wp_head钩子想要写入cookies或者session的坑。
具体需求是这样的:
我们在做一个文章浏览次数统计的时候,默认情况是用户每刷新一次页面就增加一次访问量;代码如下:
//阅读数处理
function addrandviews() {
if (is_single()) {
global $post;
$post_ID = $post->ID;
if ($post_ID) {
$rdno = 1;
$posts_views = (int) get_post_meta($post_ID, 'views', true);
if (!update_post_meta($post_ID, 'views', ($posts_views + $rdno))) {
add_post_meta($post_ID, 'views', 1, true);
}
}
}
}
add_action('wp_head', 'addrandviews');
可以看到我们使用的钩子是wp_head,这个时候,用户每刷新一次都能增加一次访问量,即使是同一个用户!
下面的需求是同一个用户无论刷新多少次都只记录一次访问量:
我们思路是,在访问量增加后使用SESSION
或者COOKIES
来记录用户已经访问过该篇文章了;代码如下:
function addrandviews() {
if (is_single()) {
global $post;
$post_ID = $post->ID;
$wboxreadposts = array();
if(isset($_COOKIE['wboxreadposts'])){
$wboxreadposts = explode('|',$_COOKIE['wboxreadposts']);
}
if ($post_ID && !in_array($post_ID, $wboxreadposts)) {
$rdno = 1;
$posts_views = (int) get_post_meta($post_ID, 'views', true);
if (!update_post_meta($post_ID, 'views', ($posts_views + $rdno))) {
add_post_meta($post_ID, 'views', 1, true);
}
if(count($wboxreadposts) > 20) $wboxreadposts = array(); //限制cookies大小
$wboxreadposts[] = $post_ID;
setrawcookie("wboxreadposts", implode('|',$wboxreadposts) , time() + 2592000, COOKIEPATH, COOKIE_DOMAIN);
}
}
}
add_action('wp_head', 'addrandviews');
以上的代码看似没有问题,但在实际的测试中,cookies
并没有写入,我们再测试session
,同样没有写入,我们又测试了直接在functions.php
内放入写入cookies
和session
的代码,结果是写入成功了的,
这时我们得出的结论是wp_head
钩子是不能写cookies和session的。
我们查看了wordpress
官方给出的文档:
大致意思是,写入cookies
的代码是挂在init
的钩子中的,而读取是放到wp_head
钩子中的。
这时,我们立马把wp_head
换成了init
,新的问题出现了:
使用init钩子时,is_single()
函数无效,同时也没有$post
全局变量;
通过查阅wordpress的hook
文档,找到了可以解决问题的钩子: wp
这个钩子是在主查询生成后执行的,所以这里可以写入cookies
和session
,也可以判断是否为文章页。问题终于得到解决。
大牛请略过,不喜勿喷!
本文转载至: 西部盒子博客:关于在WordPress的hook钩子中写入cookies或session的坑