月度归档: 2015 年 5 月

  • 使用七牛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', 's.fiaox.com/wp-content',
    				str_replace('blog.zhengxianjun.com/wp-includes', 's.fiaox.com/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 这款插件,该插件可以绑定到七牛空间。因为我在使用过程中出现了一些问题,之前发布的文章中图片地址出现了错误,所以使用上面所述的方法实现。

  • 我心匪石,不可转也

    《诗经·邶风·柏舟》

    天涯海角

    泛彼柏舟,亦泛其流。耿耿不寐,如有隐忧。微我无酒,以敖以游。
    我心匪鉴,不可以茹。亦有兄弟,不可以据。薄言往愬,逢彼之怒。
    我心匪石,不可转也。我心匪席,不可卷也。威仪棣棣,不可选也。
    忧心悄悄,愠于群小。觏闵既多,受侮不少。静言思之,寤辟有摽。
    日居月诸,胡迭而微?心之忧矣,如匪浣衣。静言思之,不能奋飞。

  • JavaScript Symbol

    Symbol 是 ES6 中提出的一种原始值类型。

    var Seven = Symbol('Seven');
    typeof Seven; // => 字符串 symbol
    

    typeof 家族又多一个成员。

  • JavaScript Function bind

    JavaScript bind 函数允许返回一个跟源函数一样的绑定函数。绑定函数与源函数区别在与绑定函数的 this 已经被 bind 修改。

    函数定义

    new Function().bind(this, arg0, arg1…)

    代码示例

    function sayHello(guest) {
    	console.log('Hello ' + guest + ', I am ' + this.age + ' years old');
    }
    sayHello('Yue');
    
    var me = {
    	name: 'Seven',
    	age: '24'
    };
    
    var sayHi = sayHello.bind(me);
    sayHi('Yue');
    

    执行结果

    JavaScript bind

    尽管没有通过调用成员方法而是直接执行函数 sayHi(‘Yue’),sayHi 内部的 this 仍然指向了对象 me,而不是默认的 window。

    从控制台可以看到 sayHi 已经被“编译”为本地方法。

    bind 函数的可选参数 arg0、arg1 等是绑定到源函数对应的第0个参数、第一个参数。执行绑定函数时自动传递已绑定的参数。

    与 bind 相比,apply 和 call 方法是在函数执行时改变 this,bind 可以理解为在函数定义时改变 this。

    apply、bind、call 对比

    函数名 参数列表 说明
    apply (this_arg, arguments_array) 调用函数,通过 this_arg 替代源函数默认的 this,arguments_array 是传递给函数的参数列表

    var A = {
    	name: 'A',
    	sayHi: function(guest) {
    		console.log('Hi ' + guest + ', I am ' + this.name);
    	}
    }
    var me = {name: 'Seven'};
    A.sayHi('Yue');
    A.sayHi.apply(me, ['Yue']);
    
    bind (this_arg, arg0, arg1…) 创建与源函数函数体一样的绑定函数,并根据 this_arg 和 arg0、arg1 等分别修改绑定函数的 this 和 默认参数
    call (this_arg, arg0, arg1…) 调用函数,通过 this_arg 替代源函数默认的 this,arg0、arg1 等是传递给函数的参数列表

    var A = {
    	name: 'A',
    	sayHi: function(guest) {
    		console.log('Hi ' + guest + ', I am ' + this.name);
    	}
    }
    var me = {name: 'Seven'};
    A.sayHi('Yue');
    A.sayHi.call(me, 'Yue');