最近因为虚拟主机太贵,所以就给降级了,把带宽从3M降到1M,价格是便宜了不少,但是整站的加载速度却变慢很多,F12看一下,时间大部分都在加载图片上。所以就有了把图片等附件放到百度云上的想法,这样就可以把带宽压力的大部分分出去。

网上搜一把就发现使用百度云存储wordpress附件这个事情已经有人做了插件,下下来看了一下,功能基本满足需求。美中不足的是这个插件设置完成后需要把数据库中文章的内容改掉,也就是把文章中的图片等附件链接改成百度云上附件的地址。这样做的坏处是,万一哪天不想使用百度云了,还需要手动到数据库中把url都改回来。

所以我就稍微给插件加了一个小功能,在系统显示文章内容之前,使用一个filter把内容中的图片地址替换成百度云中的地址,这样就不用动数据库中的内容,哪天不想使用百度云存附件了,只需要把插件停了就行。

插件原地址:http://mawenjian.net/p/976.html,向原作者表示感谢。

修改后的插件可以在这里下载:http://pan.baidu.com/share/link?shareid=412052&uk=2131098973

Posted in PHP.

之前一直使用一个叫做新浪连接的插件来同步我的博客内容到新浪微博上。最近今天发现,总是同步失败,发布内容时页面报500错误。仔细查了下,是新浪强制使用了Oauth2的认证方式,插件使用的老认证方式已经不被支持了。到插件官网去看,作者貌似没有更新插件的意思,只能自己再想他法鸟。

找了一下,发现微博通提供api可以调用,同时提供了一个现成的wordpress插件,只需要注册微博通,然后在里面绑定微博账号,当然,可以绑定新浪、人人、腾讯等各种微博,一发全发,这个是之前那个插件没有的优势。不过也有令人不爽的地方,首先是这个插件功能比较弱,只能发文章标题,不能发摘要,不能发图片。参考新浪连接,我就把代码改了下,现在可以发标题摘要也能发图片了。代码如下:

<?php
/*
Plugin Name: 微博通同步发布
Plugin URI: http://www.wbto.cn
Description: 自动把你的博客文章同步到微博通,微博通将同步至你所绑定的各个平台。
Version: 1.0
Author: yige <abcwuwuwu@qq.com>
Author URI: http://t.qq.com/abcwuwuwu

Date: 2011年3月17日 23:07:30
Modified by :zhujianfeng <http://weibo.com/fdjianfeng> 2012-07-27
*/

function wbto_install() {
	global $wpdb;
	$table_name = $wpdb->prefix."wbto";
	if($wpdb->get_var("show tables like '$table_name'") != $table_name) {
		$sql = "CREATE TABLE " . $table_name . " (id mediumint(9) NOT NULL AUTO_INCREMENT, wbto_username VARCHAR(100) NOT NULL, wbto_password VARCHAR(100) NOT NULL, );";
	}
	require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
	dbDelta($sql);
}

function send_to_wbto($post_ID) {
	$username = get_option('wbto_username');
	$password = get_option('wbto_password');
	$posted = get_post($post_ID);

	$post_title = $posted->post_title;
	$post_content = get_post_excerpt($posted);

	$title_len = mb_strlen($post_title,'UTF-8');
	$content_len = mb_strlen($post_content,'UTF-8');
	$rest_len = 110;

	if($title_len + $content_len> $rest_len) {
		$post_content = mb_substr($post_content,0,$rest_len-$title_len).'... ';
	}
	$status = '【'.$post_title.'】 '.$post_content;

	$pic = get_post_first_image($posted->post_content);

	$fields = array();
	$fields['source'] = 'wordpress';
	$fields['content'] = urlencode($status.' '.$posted->guid);
	$wbto_url = "http://wbto.cn/api/update.json";
	if ($pic){
		$wbto_url = "http://wbto.cn/api/upload.json";
		$fields["imgurl"] = $pic;
	}

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $wbto_url);
	curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
	curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE);
	curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	curl_setopt($ch, CURLOPT_POST, TRUE);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
	$result = curl_exec($ch);
	curl_close($ch);

}

function wbto_menu() {
add_options_page('微博通同步设置', '微博通同步', 8, __FILE__, 'wbto_options');
}
if(!function_exists('get_post_excerpt')){
	function get_post_excerpt($post){
		$post_excerpt = strip_tags($post->post_excerpt); 
		if(!$post_excerpt){
			###第一种情况,以<p>开始,</p>结束来取第一段 Windows live writer
			if(preg_match('/<p>(.*)<\/p>/iU',trim(strip_tags($post->post_content,"<p>")),$result)){ 
				$post_content = $result['1'];
			} else {
			###第二种情况,以换行符(\n)来取第一段   
				$post_content_r = explode("\n",trim(strip_tags($post->post_content))); 
				$post_content = $post_content_r['0'];
			}
			$post_excerpt = explode("\n",trim(strip_tags($post->post_content))); 
   			$post_excerpt = $post_excerpt['0'];	
		}
		$post_excerpt = trim(strip_tags($post_excerpt));
		$post_excerpt = str_replace('"', '', $post_excerpt);	
		// replace newlines on mac / windows?
		$post_excerpt = str_replace("\r\n", ' ', $post_excerpt);
		// maybe linux uses this alone
		$post_excerpt = str_replace("\n", ' ', $post_excerpt);
		$post_excerpt = mb_substr($post_excerpt,0,120);

		return $post_excerpt;
	}
}
if(!function_exists('get_post_first_image')){

	function get_post_first_image($post_content){
		preg_match_all('|<img.*?src=[\'"](.*?)[\'"].*?>|i', $post_content, $matches);
		if($matches){		
			return $matches[1][0];
		}else{
			return false;
		}
	}
}
function wbto_options() {
	echo '<div class="wrap">';
	echo '<h2>微博通同步</h2>';

	echo '<form method="post" action="options.php">';
	echo wp_nonce_field('update-options');

	echo '<table class="form-table">';

	echo '<tr valign="top">';
	echo '<th scope="row">用户名 <a href="http://www.wbto.cn/?app=wp">注册</a></th>';
	echo '<td><input type="text" name="wbto_username" value="'.get_option('wbto_username').'" /></td>';
	echo '</tr>';

	echo '<tr valign="top">';
	echo '<th scope="row">密码</th>';
	echo '<td><input type="password" name="wbto_password" value="'.get_option('wbto_password').'" /></td>';
	echo '</tr>';

	echo '</table>';

	echo '<input type="hidden" name="action" value="update" />';
	echo '<input type="hidden" name="page_options" value="wbto_username,wbto_password" />';

	echo '<p class="submit">';
	echo '<input type="submit" name="submit" id="submit" class="button-primary" value="保存更改" />';
	echo '</p>';

	echo '</form>';
	echo '</div>';

}

add_action('admin_menu', 'wbto_menu');
add_action('publish_post', 'send_to_wbto');
?>

还有另外一点比较不爽的就是,发送频率有限制,具体限制多久不知道,但是根据我的测试,5分钟内发两次是不行的。
参考的文章如下:
http://fairyfish.net/project/sina-connect/
http://www.jsxubar.info/wordpress-use-wp_wbto-plugin-sync-post-to-weibo.html

Posted in PHP.

场景如下:数据库里有大量记录,php程序需要取出来做一些运算,是一次取出所有还是一次取出部分?示例代码如下:

//一次读取
$start = '2012-06-11 00:00:00';
$end = '2012-06-18 00:00:00';
$rows = $db->query("select ... where
        time between '$start' and '$end'");
foreach ($rows as $row) {
    $name = $row["name"];
    $table[$name] = $row["value"];
}

//多次读取
$start = '2012-06-11 00:00:00';
$end = '2012-06-18 00:00:00';
$start_t = strtotime($start);
$end_t = strtotime($end);
$time_span = 43200;
for ($t = $start_t; $t < $end_t; $t += $time_span) {
    $this_s = date("Y-m-d H:i:s", $t);
    if ($t + 86400 > $end_t) {
        $this_e = date("Y-m-d H:i:s", $end_t);
    } else {
        $this_e = date("Y-m-d H:i:s", $t + $time_span);
    }
    $rows = $db->query("select ... where
            time between '$this_s' and '$this_e'");
    foreach ($rows as $row) {
        $name = $row["name"];
        $table[$name] = $row["value"];
    }
}

在上述代码中,做了几次实验,得出下列数据:

其中,总记录数是2296605,第一次测试是一下全部取出,需要占用2G左右内存,整个执行时间是4分多钟,逐步减少每次取出的记录数,当然同时要增加取出次数,当一次取出的次数在16W左右时,程序执行时间最短。
相同的代码在不同的数据规模上性能表现差别巨大,所以写代码还是要注意要处理的数据规模。

Posted in PHP.