在服务端合并js和css文件

YSlow会告诉我们,合并所有的js和css文件可以减少HTTP请求,这样能提升访问速度。

通常为了开发的方便,我们会把js按用途分类,这样就会有很多js文件,比如sablog的jscript文件夹里就有10几个文件,这样访问的时候就是10几个HTTP请求。

那么解决办法就是合并它们,对吧。可是这样有一个问题就是你需要保存所有文件的源文件,并且有修改的时候又要从新合并一次。

实际上我们可以更简单一点,让php去合并这些文件吧,同时我们也不用操心压缩这档子事了。这里就要提到一个开源的php项目,名字叫做Minify,它可以帮助你合并,精简,压缩和缓存Javascript以及CSS文件。

Minify的使用非常简单:

1. 把下载到的源码解压缩,把其中的min文件夹复制到Apache的DOCUMENT_ROOT目录下,即你的网站跟目录。

2. 然后打开min/config.php文件,注意下面一些选项

//去掉下面3项中的一项注释,设置缓存目录
//$min_cachePath = 'c:\\WINDOWS\\Temp';
//$min_cachePath = '/tmp';
//$min_cachePath = preg_replace('/^\\d+;/', '', session_save_path());
//设置缓存时间,以秒为单位,当然是越大越好
//但是更简单的方式是在URL最后加一串数字,比如/min/f=hello.css&123456
//这样Minify会自动把缓存时间设置成一年,当文件有更新时之需要修改URL后面的数字即可
$min_serveOptions['maxAge'] = 1800;
//f参数获取的文件个数限制,建议越大越好,但是会出现URL超长的问题
//如果文件很多的话建议使用g参数设置group
$min_serveOptions['minApp']['maxFiles'] = 10;

3. 下面你可以打开http://yourdomain/min/builder/,这里有一个工具可以帮助你生成引用URL。填好你要合并的js或css文件,点击Update,下面会给出引用代码,类似这个样子

<script type="text/javascript" src="/min/b=sa2/include&amp;f=jscript/show.js,jscript/jquery.js,jscript/common.js,
jscript/ajax.js,jscript/fiximage.js,syntaxhighlighter/scripts/shCore.js,
syntaxhighlighter/scripts/shBrush.js&20100724"></script>

把它放到你的<head></head>标签里,删掉原先的一堆脚本引用,好了,现在访问你的网站只有一个HTTP请求了。

4. 你可能会嫌上面的URL是不是太长了点,当然我们还有更好的方法,并且效率会更高。我们可以使用g参数

这个方法需要在min/groupsConfig.php里进行设置,比如刚才的那一堆js可以写成这样

return array(
    'js' => array('//sa2/include/syntaxhighlighter/scripts/shCore.js',
    			  '//sa2/include/syntaxhighlighter/scripts/shBrush.js',
    			  '//sa2/include/jscript/show.js',
    			  '//sa2/include/jscript/jquery.js',
    			  '//sa2/include/jscript/fiximage.js',
    			  '//sa2/include/jscript/common.js',
    			  '//sa2/include/jscript/ajax.js')
);

这段代码也是可以用上面提到的builder来生成的。

这样在你的网页中就只需要这样来引用了

<script type="text/javascript" src="/min/g=js&20100724"></script>

看起来简洁许多吧~

用php解析html

最近想用php写一个爬虫,就需要解析html,在sourceforge上找到一个项目叫做PHP Simple HTML DOM Parser,它可以以类似jQuery的方式通过css选择器来返回指定的DOM元素,功能十分强大。

首先要在程序的开始引入simple_html_dom.php这个文件

include_once('simple_html_dom.php');

PHP Simple HTML DOM Parser提供了3种方式来创建DOM对象

// Create a DOM object from a string
$html = str_get_html('<html><body>Hello!</body></html>');

// Create a DOM object from a URL
$html = file_get_html('http://www.google.com/');

// Create a DOM object from a HTML file
$html = file_get_html('test.htm');

得到DOM对象后就可以进行各种操作了

// Find all anchors, returns a array of element objects
$ret = $html->find('a');

// Find (N)th anchor, returns element object or null if not found (zero based)
$ret = $html->find('a', 0);

// Find lastest anchor, returns element object or null if not found (zero based)
$ret = $html->find('a', -1); 

// Find all <div> with the id attribute
$ret = $html->find('div[id]');

// Find all <div> which attribute id=foo
$ret = $html->find('div[id=foo]'); 

这里可以使用各种css选择器,就像在jQuery中进行DOM操作一样,非常方便。此外,还有两个特殊的属性可以得到文本和注释的内容

// Find all text blocks 
$es = $html->find('text');

// Find all comment (<!--...-->) blocks 
$es = $html->find('comment');

当然,还是类似于jQuery,PHP Simple HTML DOM Parser也支持链式操作,以及各种访问DOM元素的简单方法

// Example
echo $html->find("#div1", 0)->children(1)->children(1)->children(2)->id;
// or 
echo $html->getElementById("div1")->childNodes(1)->childNodes(1)->childNodes(2)->getAttribute('id');

给sablog添加评论回复邮件通知功能

人家来你博客留言,还得不定时地来你的页面看你有没有回复,也太不友好了,必须要加个评论回复的邮件通知功能,sablog没有,自己写!

首先需要一个email类,这里下载:mailclass.rar

解压到include\class\目录下。

然后打开include\func\global.func.php,在最后添加一个函数:

function comment_notice($subject, $body, $mailto) {
    $mailAddr = '发信人邮箱';
    $fromName = '邮件发送者的名字';
    $mailPwd = '发信人邮箱密码';
    $smtpServer = 'smtp服务器地址';//smtp.qq.com,smtp.163.com...

     if ( !class_exists('PHPMailer') ) {
    require_once(SABLOG_ROOT.'include/class/class-phpmailer.php');
    require_once(SABLOG_ROOT.'include/class/class-smtp.php');
     }
     $mail = new PHPMailer();

     $mail->IsSMTP();
     $mail->Mailer         = "smtp";
     $mail->CharSet     = 'utf-8';
     $mail->Encoding = 'base64';
     $mail->IsHTML(true);
     $mail->SMTPAuth = true;
     $mail->Host                 = $smtpServer;
     $mail->Username = $mailAddr;
     $mail->Password = $mailPwd;
     $mail->From                 = $mailAddr;
     $mail->FromName = $fromName; 

     $mail->AddAddress($mailto);
     $mail->Subject = $subject;
     $mail->Body             = $body;
     $mail->Send();
}

再打开post.php,找到dcookies('cmcontent');一行,在它的上面加上:

// 邮件提醒
preg_match("/\[quote=(.*?)\]\s*(.+?)\s*\[\/quote\]/is",$content,$matches);
$mailto = $matches[1];
if($mailto && $mailto != '管理员用户名') {
    $q = $DB->fetch_one_array("SELECT email FROM {$db_prefix}comments WHERE author='$mailto' LIMIT 1");
    if($q['email']) {
        $mailto = $q['email'];
        if($url) {
            $fromuser = '<a href="'.$url.'">'.$username.'</a>';
        } else {
            $fromuser = $username;
        }
        $subject = $username.'回复了您的评论';
        $content = htmlspecialchars($content);
        $content = str_replace("\n", "<br />", $content);
        $content = str_replace("     ", "        ", $content);
        $content = str_replace("\t", "                ", $content);
        $content = preg_replace("/\[quote=(.*?)\]\s*(.+?)\s*\[\/quote\]/is",'',$content);
        $body = '<p>您收到这封邮件是因为有人回复你的评论,如果不想再收到此类邮件,请回信说明。</p>'
                    .'<p><strong>'.$fromuser.'</strong>:<br />'
                    .$content.'</p>'
                    .'<p><a href="'.$article['url'].$cmnum.'">点击查看该评论</a></p>';
        comment_notice($subject, $body, $mailto);
    }
}

$body里的内容自己看情况改吧。每当你引用并回复了某人的评论时,都会发一封邮件去通知他。

继续修复sablog-x 2.0的缩略图尺寸bug

前些天发了篇南京之行的图片日志,发现把图片附件插入到文章中后,缩略图悬浮信息里的尺寸显示有问题:

thumb-size-bug.png

查看缩略图显示代码,发现问题出在 include\func\attachment.func.php 153~170行:

$a_thumb_path = $attachdb[$attachid]['thumb_filepath'];
$a_path = $attachdb[$attachid]['filepath'];

if ($attachdb[$attachid]['thumb_filepath'] && $options['attachments_thumbs'] && file_exists(SABLOG_ROOT.$a_thumb_path)) {
    $attachdb[$attachid]['filepath'] = $attachdb[$attachid]['thumb_filepath'];
    $a_path = $a_thumb_path;
} else {
    $size = explode('x', strtolower($options['attachments_thumbs_size']));
    $imagesize = @getimagesize(SABLOG_ROOT.$a_path);
    $im = scale_image( array(
        'max_width'     => $size[0],
        'max_height' => $size[1],
        'cur_width'     => $imagesize[0],
        'cur_height' => $imagesize[1]
    ));
    $attachdb[$attachid]['thumb_width'] = $im['img_width'];
    $attachdb[$attachid]['thumb_height'] = $im['img_height'];
}

把第161行挪到第155行去,改成:

$a_thumb_path = $attachdb[$attachid]['thumb_filepath'];
$a_path = $attachdb[$attachid]['filepath'];
$imagesize = @getimagesize(SABLOG_ROOT.$a_path);

if ($attachdb[$attachid]['thumb_filepath'] && $options['attachments_thumbs'] && file_exists(SABLOG_ROOT.$a_thumb_path)) {
    $attachdb[$attachid]['filepath'] = $attachdb[$attachid]['thumb_filepath'];
    $a_path = $a_thumb_path;
} else {
    $size = explode('x', strtolower($options['attachments_thumbs_size']));
    $im = scale_image( array(
        'max_width'     => $size[0],
        'max_height' => $size[1],
        'cur_width'     => $imagesize[0],
        'cur_height' => $imagesize[1]
    ));
    $attachdb[$attachid]['thumb_width'] = $im['img_width'];
    $attachdb[$attachid]['thumb_height'] = $im['img_height'];
}

这样,在缩略图的alt信息里就会显示原图的大小了。

修复sablog-x 2.0水印bug并给缩略图添加水印

本文针对sablog-x 2.0 20091109版,给图片附件开启水印效果无效,修复方法如下

打开 include\func\image.func.php,第36行

$waterimg = '../templates/'.$options['templatename'].'/images/watermark.png';

修改为:

$waterimg = './templates/'.$options['templatename'].'/images/watermark.png';

修改以后原图能加上水印了,但是不会处理缩略图,而正文中出现的照片大多都是缩略图,要给缩略图加水印,修改如下:

打开 admin\uploadfiles.php,第120行

create_watermark($path);
$attach['size'] = filesize($path);

修改为:

create_watermark($path);
if ($attach_data['thumbwidth'] > $watermark_size[0] && $attach_data['thumbheight'] > $watermark_size[1]) {
    create_watermark($attach_dir.$thumb_data['thumbfilepath']);
}
$attach['size'] = filesize($path);