WordPress 在 BAE 上如何获得访客的真实IP

不知大家有无注意到,在 BAE 上运行的 WordPress,获取到的评论 IP 都是 BAE 的内网 IP,而不是真正的访客 IP。

那么真正的访客 IP 在哪里呢?根据 BAE 官方的解答,真正的访客 IP 在 HTTP_X_FORWARDED_FOR 中,但是由于 BAE 的特殊性,所以代码与安全宝获取真实 IP 的代码略有不同,但依旧是放在主题的 Functions.php 中。

代码如下:

<?php
add_action('init', 'GetIP');
function GetIP() {
	$IP = str_replace(", ", "", str_replace(getenv('REMOTE_ADDR'), "", getenv('HTTP_X_FORWARDED_FOR')));
	if (false === getenv('HTTP_X_FORWARDED_FOR')) {
		$_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
	} else {
		$_SERVER['REMOTE_ADDR'] = $IP;
	}
}
?>

BAE 版 WordPress Gravatar 头像缓存

因为近期 Gravatar 头像加载速度又慢如蜗牛,所以需要缓存一下。百度了一下,没有 BAE 版的,于是参照 SAE 版的,自己写了个。

什么是Gravatar?

Gravatar 是 Globally Recognized Avatar 的缩写,是 Gravatar 推出的一项服务,意为“全球通用头像”。如果在 Gravatar 的服务器上放置了你自己的头像,那么在任何支持 Gravatar 的站点上留言时,只要提供你与这个头像关联的 E-Mail 地址,就能够显示出你的Gravatar头像来。

为什么要缓存Gravatar头像?

因为 Gravatar 的服务器在国外,在国内访问使用该功能的网站或博客,可能因为载入速度过慢而导致页面一直在载入中甚至头像无法显示,这是一个非常糟糕的用户体验。将头像缓存下来,定时更新,而头像图片的文件一般不会很大,不需要暂用很大的服务器空间,因此缓存 Gravatar 头像是一个加快网站访问速度的高性价比选择。

如何在 BAE 中缓存Gravatar头像?

很简单,在你的主题的 Function.php 文件中加入以下代码:

<?php
function nikbobo_get_avatar_cache ( $avatar ) {
	if( $_SERVER['PHP_SELF'] == '/wp-admin/options-discussion.php' )
		return $avatar;
	$bucket = '这里更改为你的Bucket名称';
	$cache_dir = '/avatar/';
	$baidu_bcs = new BaiduBCS();
	$tmp = strpos( $avatar, 'avatar/' ) + 7;
	$avatar_id = substr( $avatar, $tmp, strpos( $avatar, '?' ) - $tmp );
	$tmp = strpos( $avatar, 'avatar/' ) + 7;
	$pattern = "/(<img.* src=\')([^\']*)(\'.*)/";
	$avatar_url = preg_replace( $pattern, "$2", $avatar );
	$avatar_url = str_replace( "&", "&", $avatar_url );
	$avatar_file = $cache_dir . $avatar_id . '.png';
	if( ! $baidu_bcs->is_object_exist( $bucket, $avatar_file ) ) {
		$content = @file_get_contents( $avatar_url );
		if( ! $content )
			return $avatar;

		$opt['acl'] = "public-read";
		$opt['headers']['Expires'] = 'access plus 15 days';
		$opt['headers']['Content-Type'] = 'image/png';

		$result = $baidu_bcs->create_object_by_content( $bucket, $avatar_file, $content, $opt );
	}
	$avatar_cache_url = 'http://bcs.duapp.com/' . $bucket . $avatar_file;
	$avatar = preg_replace( $pattern, "$1" . $avatar_cache_url . "$3", $avatar );
	return $avatar;
}

add_filter('get_avatar', 'nikbobo_get_avatar_cache');
?>

以上代码在 BAE 环境中测试通过,无法确定能否用于非 BAE 环境。

大功告成!

WordPress 子主题制作出现 Cannot redeclare 错误的原因及解决方法

前段时间,我尝试以子主题的模式制作了一个主题。原以为制作起来 So Easy,可是,却没有想象的那么容易。首当其冲的是函数替换问题。

WordPress 官方给出的替换方法

<?php
if (!function_exists('theme_special_nav')) {
    function theme_special_nav() {
        //  Do something.
    }
}
?>

事实上却没有那么简单。有些函数替换会报 Cannot redeclare 错误,怎么回事呢?

出错的原因

大家翻开支持子主题的主题的 Functions.php(这句话真绕口),会发现,那些可以替换的函数,在 Functions.php 中也是使用:

<?php
if (!function_exists('theme_special_nav')) {
    function theme_special_nav() {
        //  Do something.
    }
}
?>

写的,这样就是可以替换的原因,然而那些不能替换的函数呢?一般就是这样的写法:

<?php
function theme_special_nav() {
    //  Do something.
}
add_action('xxx', 'theme_special_nav');
?>

那么不能替换的函数怎么替换呢?其实也可以巧妙解决的。本文就以 theme_special_nav 这个函数为例,说一下怎么解决的。

解决方法

假设父主题的 Functions.php 是这样写的:

<?php
function theme_special_nav() {
    //  Do something.
}
add_action('xxx', 'theme_special_nav');
?>

其实已经隐含着替换方法了,我们可以在子主题加入以下代码:

<?php
function remove_parent_theme_hook() {
	remove_action('xxx', 'theme_special_nav');
}
add_action('after_setup_theme', 'remove_parent_theme_hook');
function nikbobo_theme_special_nav() {
	// Do Something.
}
add_action('xxx', 'theme_special_nav');
?>

原理就是利用 WordPress 的 Hook 机制,在 after_setup_theme 即主题设置完成这个时机删除掉原来的 Hook,然后添加自己的 Hook,为什么一定要在 after_setup_theme 这个时机呢?直接一句:

<?php
remove_action('xxx', 'theme_special_nav');
?>

不就行了么?

大家有无留意到,WordPress 的子主题介绍上有一句话:

其实它会在父主题文件加载之前先载入

也就意味着,你 remove_action 的时候,这个 Hook 还没有建立,结果你自然知道了。

Gravatar 头像问题今天有了真正解决的方法了

Gravatar 头像问题今天有了真正解决的方法了,因为京东云目前免费,所以我使用京东云+京东云存储搭建了一个 Gravatar 头像镜像服务器。

WordPress 立刻在 Functions.php 中添加以下代码,立刻切换到京东云的镜像服务器。

function china_get_avatar($avatar) {
	$avatar = str_replace(array('www.gravatar.com', '0.gravatar.com', '1.gravatar.com', '2.gravatar.com'), 'avatar.jd-app.com', $avatar);
	return $avatar;
}
add_filter('get_avatar', 'china_get_avatar', 10, 3);

更好的方法是安装 Gravatar Fixed 头像修正插件 然后修改 Gravatar 服务器为 http://avatar.jd-app.com/

Gravatar SSL 服务器暂时无法,因为貌似京东云不支持 SSL。

搬家成功,现用服务:创智主机+CDN.GD

因为无法忍受 BAE 的速度慢,和时不时挂掉,经过博友推荐,搬家到了创智主机。

目前我使用的是免费套餐:美国——洛杉矶,感觉速度哗哗,据说收费套餐更加优秀。

心动了么?那就立刻去看看吧!

说完这个,说说CDN.GD,这是一个 CDN,但是管理十分严格,就和创智主机一样,加速效果如何,我暂时不知,反正我这里觉得哗哗快。

为什么管理严格的东西好?因为管理严格的东西,可以有效避免某种情况的发生。

这个 CDN 还需要 5元钱,来防止恶意注册,但是现在,可以立刻输入:hostloc,免掉五元钱。

好吧,我承认,我写这篇文章是为了那个

写篇文章,均可免费获得基础套餐一年来的。。。

BAE 的优势所在

今天,无意间看到了一堆喷 BAE、SAE 的言论,看不过眼,所以写一下。

大家的焦点主要在“不支持写本地目录”这个问题上。那么我就说以下为什么要这么做。

其实这么做,目的只有一个——安全。

为什么动静分离会安全呢?

我们做一个假设:

WordPress 爆出了一个任意上传的漏洞。

如果动态和静态放在一起,上传成功,立刻挂马。

如果动静分离,上传成功,上传到专门的静态服务器,没有动态语言解析器,结果——无法执行!上传成功,也是废品!

就说这么多。

更换独立域名nikbobo.net

今天,将博客域名由www.nikbobo.net更换为nikbobo.net(www.nikbobo.net),非常高兴,终于有独立域名了。

这个域名是崔朝阳送我的,我的主机也是他提供的,非常感谢他。

他今年要考高考,现已进入高考百日,在这里,衷心的祝愿他,考个好大学。

说说最近,庆庆中秋

不知不觉,中秋节到了,再加上国庆双节,有了那么一点时间,沉寂了那么久,是该冒个泡了。
吐槽一下最近的倒霉事吧:
1、万恶的金九月饼
大概是9月中旬吧,等宅急送的过程中,闲来无事,把家里的那个金九双黄莲蓉开来吃。果然是双黄莲蓉,这么大一个饼,竟然只有两个咸蛋黄。更不幸的是,吃完就不舒服,立刻给肚子擦了点油,吃了腹可安,最后连宅急送都没吃完,肚子超不舒服,早早睡觉了,竟然浪费了一顿大餐。
长教训了:1)月饼一定要先蒸过再吃;2)金九月饼吃不得;3)大饼吃不得;4)等宅急送的过程中,一定不能乱吃东西!
2、洗澡洗到一半,没气
洗头洗到一半,突然水变凉,一看,居然没了煤气,不想洗冷水澡,只好出来烧水,好不容易靠着热水洗干净头。身也没敢摸肥皂,没热水,拿剩下那点热水冲冲身,就赶紧擦干身出来了,好郁闷!
好了,发泄完毕,祝大家中秋快乐!