同步目录到七牛CDN

基于七牛SDK实现目录上传和同步

使用官方提供的PHP SDK实现,重新使用PHP实现目录同步,而不是使用官方提供的Windows 程序,主要是因为 qrsbox.exe 会同步目录下的所有文件,包括 .svn 文件和一些项目配置文件,如 .project

七牛的PHP SDK下载地址:http://developer.qiniu.com/code/v7/sdk/php.html

本次实现的源码有几个功能:

  1. 同步普通文件,不同步英文点号开始的文件,比如 .svn、.project
  2. 将同步日志直接存放在同步的目录下,跟随 svn 进行管理
  3. 多机使用 svn 管理目录,在多机上进行同步,不会将整个项目重新同步,qrsbox.exe 将同步日志存放在 C 盘的用户目录,每在一台机器 checkout 项目,进行同步时都会完整地同步一次
  4. 通过 bat 脚本调用 php 代码,认证信息和 bucket 信息配置在源码中,每个 bat 脚本对应各自的 bucket,不再像 qrsbox.exe 切换 bucket 需要重新配置
  5. 增量同步,基于同步日志实现

PHP脚本每次执行都会比较目录下的所有文件,以此判断是否需要同步。

同名不同内容文件上传时会提示文件已存在,先删除旧文件,再提交新文件。

没有实现的功能:

  1. 目录监控,实时上传(比较少遇到实时将开发环境代码更新到生产环境)
  2. 断点续传(CDN较多存放小文件)
  3. 没有实现同步文件删除(同 qrsbox.exe)

使用七牛CDN对博客静态资源进行加速

WordPress 博客程序默认静态资源全部存放在 wp-content、wp-includes 目录下,包括主题样式和各种插件样式。

使用七牛CDN对博客静态资源进行加速步骤:

第一步、同步所有静态资源到七牛空间

第二步、替换静态资源域名

if (!is_admin())
{
	function qiniu_ob_start()
	{
		ob_start('qiniu_cdn_replace');
	}

	function qiniu_cdn_replace($html)
	{
		if ($_SERVER['SERVER_PORT'] == '443' || $_SERVER['HTTPS'] == 'on')
		return  str_replace('blog.zhengxianjun.com/wp-content', 'dn-zhengxianjun.qbox.me/wp-content',
				str_replace('blog.zhengxianjun.com/wp-includes', 'dn-zhengxianjun.qbox.me/wp-includes', $html));

		return  str_replace('blog.zhengxianjun.com/wp-content', 'zhengxianjun.qiniudn.com/wp-content',
				str_replace('blog.zhengxianjun.com/wp-includes', 'zhengxianjun.qiniudn.com/wp-includes', $html));
	}

	add_action('wp_loaded', 'qiniu_ob_start');
}

上述代码需要添加到 wp-content/themes/twentyfifteen/functions.php。其中,twentyfifteen 是当前博客使用的主题。

实现效果

访问博客首页

博客首页

查看网络资源

网络资源

可以看到博客已经使用了CDN对静态资源加速。

以后每次更新静态资源时需要同时更新到七牛空间。

为了简化静态资源同步,使用脚本 wp-static-sync.php 同步静态资源到本地七牛空间目录,七牛的 QRSBox 会自动更新目录下的所有文件。

<?php
// 文件 wp-static-sync.php
if (!isset($_SERVER['argv']))
{
	return;
}

function copy_static($static_source, $static_target)
{
	if (!is_dir($static_source))
	{
		echo "static_source : <$static_source> is not a dir\n";
		return false;
	}

	if (!is_dir($static_target))
	{
		if (false === mkdir($static_target))
		{
			echo "mkdir ERROR target <$static_target>\n";
			return false;
		}
		else
		{
			echo "mkdir Ok target <$static_target>\n";
		}
	}

	$handler_source = opendir($static_source);
	$handler_target = opendir($static_target);

	$reg_static = '/\.css$|\.js$|\.gif$|\.jpg$|\.png$/i';

	while ($name = readdir($handler_source))
	{
		if ($name == '.' || $name == '..') continue;

		$file_source = $static_source . '/' . $name;

		if (is_file($file_source))
		{
			if (preg_match($reg_static, $name))
			{
				$file_target = $static_target . '/' . $name;
				if (false === copy($file_source, $file_target))
				{
					echo "copy ERROR <$file_source> to <$file_target>\n";
				}
				else
				{
					echo "copy Ok <$file_source> to <$file_target>\n";
				}
			}
		}
		else if (is_dir($file_source))
		{
			$file_target = $static_target . '/' . $name;
			if (false === copy_static($file_source, $file_target))
			{
				return false;
			}
			// 删除空目录
			if (count(scandir($file_target)) == 2)
			{
				if (false === rmdir($file_target))
				{
					echo "rmdir ERROR empty  <$file_target>\n";
				}
				else
				{
					echo "rmdir Ok empty  <$file_target>\n";
				}
			}
		}
	}
}

$static_source = 'D:\work\blog';
$static_target = 'D:\work\zhengxianjun_cdn\www\static';

copy_static($static_source . '/wp-content', $static_target . '/wp-content');
copy_static($static_source . '/wp-includes', $static_target . '/wp-includes');

至此,虽然流程上略长,但基本实现了想要的功能。

另一种方法,是使用 wpjam-qiniu 这款插件,该插件可以绑定到七牛空间。因为我在使用过程中出现了一些问题,之前发布的文章中图片地址出现了错误,所以使用上面所述的方法实现。