BAE 发邮件需要更改 WordPress 核心代码?你 Out 了!

网络上 80% 的教程告诉我们 BAE 发邮件需要更改核心代码,其实不然,你只要把代码丢在 Functions.php 就行了:

if ( !function_exists( 'wp_mail' ) ) :
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
	$queue = '云消息名称';
	require_once ('Bcms.class.php');
	$bcms = new Bcms () ;
	$form = '发件人地址';
	$ret = $bcms->mail ( $queue, '<!--HTML-->' . $message, array( $to ), array( Bcms::FROM=>$from_email, Bcms::MAIL_SUBJECT => $subject) ) ;
	if ( false === $ret ) {
		return false;
	} else {
		return true;
	}
}
endif;

因为 WordPress 是强大的。

用 BAE 是否有助于百度收录?

忽然查了一下自己的收录数据,原来近乎为 0 的站点,不知不觉有了收录。
闲来无事,再查查监控,百度蜘蛛勤快的爬。
但戏剧性的是,开始勤快爬的那一天真好是我搬回 BAE 的那一天。
就引发了一个设想:用 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 还没有建立,结果你自然知道了。

升级到 WordPress 3.7

手动升级到了 WordPress 3.7,感觉貌似不错。唯一不满意的就是 BAE 的多灾多难,安全与方便就如同鱼和熊掌,两者不可兼得。

升级也没有像 BAE 官方的 WordPress For BAE 3.0 教程那样容易,不知是不是我的问题。还要费心去跟,看看升级升级了什么。

Twenty Twelve 也升级了,跟进官方版本。

有时间会写写教程,目前暂定:

  • Twenty Twelve 免插件添加 PageNavi,包含 CSS
  • WordPress 如何完全手动升级(应对 BAE 特殊情况)

BAE 3.0 上的 WordPress(四):新的缓存设想

刚刚在 V2EX 看到有人问为什么 BAE 免费 Redis 没人用来做缓存,不免费 Cache,大家却都想用。

这不仅仅是因为 Cache 方便移植,而是 BAE 干了一件好事:

目前每条 redis 命令的有效长度最大为2048个字节。

2048 字节是什么情况?2K,这缓存,如果确实要用,必须分片写入、分片读写,那样的话,查询量也少不了多少,效率我个人感觉和直接不用缓存差不多。
知道这种情况,我也有心查了一下 Cache:

Key 最大长度:180Bytes
Value 最大长度:1MB

所以性能自然不如自己弄的 Memcached,但是架不住 BAE 的服务器好,所以还是比我们自己的快!

由此,我突然产生了一个新想法:利用 BCS 云存储也是 Key->Value 的特性,换存到云存储。目前我已经在尝试了。。

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 环境。

大功告成!

BAE 3.0 上的 WordPress(三):WordPress 缓存的使用

大家有无发现?旧版移植的 Cache 已无法使用?现在,我就把新版的发布出来。

嘘!你们有所不知,目前 BAE 3.0 所有服务都是免费的。所以 2.0 木有钱钱用 Cache 的童鞋有福了。

首先需要开通 Cache,放一张我开通后的图:

BAE Memcached 信息获取 截图

然后下载我修改好的文件(包含 WordPress Object Cache 模块和 BAE Cache SDK),放在 wp-content 目录下。

切记,不是 plugins 目录!

然后修改约 377 行,填入相关信息:

$this->mc[$bucket] = new BaeMemcache( ‘资源名称’, ‘连接地址:端口’, ‘API Key’, ‘Secret Key’ );

哈哈,大功告成!你就可以学别人用 Memcached 那样使用了。

文件下载:百度网盘

 

大家可能有疑问,为什么要加入 SDK?

因为 BAE 官方说

目前各语言服务的SDK需要开发者自己安装到环境中

BAE 的优势所在

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

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

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

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

我们做一个假设:

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

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

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

就说这么多。

BAE 3.0 上的 WordPress(二):WordPress 安装

话说,BAE 3.0 发布了,是不是应该写一下 3.0 的 WordPress 教程,来体验一下 BAE 3.0 呢?BAE 官方说的是

WordPress 3.6 完全兼容

那么?情况究竟如何?真的是这样么?

对,你没猜错!核心程序代码一行都不用改!

甚至你直接上传上去安装都可以,但是,我不推荐这种做法。

因为,BAE 官方说了:

BAE 3.0 更新代码时会将执行单元中存在而 SVN 中不存在的文件或目录删除。因此如果代码在运行过程中写了本地文件,那么再下次更新代码时本地文件就会本删掉。

 

那么应该怎么做呢?

  1. 建立一个应用,添加部署,添加扩展服务(方法省略,这个还不会,我不知道你是凭什么拿到公测资格的)
  2. 下载最新版 WordPress。(方法同样省略)
  3. 复制一份 wp-config-sample.php 为 wp-config.php
  4. 按照提示填写各项信息(具体请在 BAE 扩展服务找)(实在不会?两张图说明一切!)
    BAE MySql 信息获取 截图 BAE API Key 信息获取 截图
  5. 提交代码
  6. 按照普通的方法安装 WordPress

是不是一行代码都不用改?

终于搞定云存储的问题了

终于搞定 BCS 云存储的问题了,查来查去,查了半天,居然是因为我用了自动远程下载图片,然后把 BCS 的当远程图片了。。。