分类目录归档:PHP语言

php调用shell程序出现僵尸程序defunct

php调用bash shell
[php]
system("/home/app/clean_queue.sh", $retval);
[/php]

clean_queue.sh如下:
[bash]
#!/bin/bash
sid="/data/httpsqs/queue"
pid=`ps -ef|grep -v grep|grep $sid|sed -n ’1P’|awk ‘{print $2}’`
while [ -n "$pid" ]
do
echo "queue id=$pid"
kill $pid
pid=`ps -ef|grep -v grep|grep $sid|sed -n ’1P’|awk ‘{print $2}’`
done

echo "has shutdown queue."
rm -rf /data/httpsqs/queue/httpsqs.db
echo "has delete queue db."

/usr/bin/httpsqs -d -p 1234 -x /data/httpsqs/queue
echo "has restarted page queue"

pid2=`ps -ef|grep -v grep|grep $sid|sed -n ’1P’|awk ‘{print $2}’`
while [ -z "$pid2" ]
do
echo "queue has not been started, ready to retry."
/usr/bin/httpsqs -d -p 1234 -x /data/httpsqs/queue
pid2=`ps -ef|grep -v grep|grep $sid|sed -n ’1P’|awk ‘{print $2}’`
done
echo "end check if started"
[/bash]

但执行的时候此段php代码始终不结束
[bash]
[root@script ~]# ps -ef|grep defunct
root 11273 21369 0 16:58 pts/0 00:00:00 php test_defunct.php
root 11275 11273 0 16:58 pts/0 00:00:00 [sh] <defunct>
root 11384 13877 0 16:59 pts/2 00:00:00 grep defunct
[/bash]

刚开始看到/usr/bin/httpsqs的背景颜色是红色的,以为是权限的问题,后来chmod u-s /usr/bin/httpsqs去掉suid属性还是问题依旧。
后来感觉是不是httpsqs启动后是deamon程序,调用的php一直判断这个shell没结果,就一直等,尝试加上nohup后台执行,如下面的写法:
[bash]
system("nohup /home/app/clean_queue.sh > /home/app/log/clean_queue 2>&1", $retval);
[/bash]
果然就不出僵尸进程了。

CI学习 – header和footer

见网上提到有很多种方法,没有具体测试哪个效率高。
方法一、在每个view文件的开头和结尾分别加上下面两句:
[php]
<?php $this->load->view(‘header’)?>

<?php $this->load->view(‘footer’)?>
[/php]
这也是最简单和容易理解的方法。

方法二、写一个模板类template.php,在里面实现这种逻辑,再提供一个showView()方法。头尾有各自的模型。
以下供参加:
[php]
<?php if (!defined(‘BASEPATH’))
exit(‘No direct script access allowed’);

class Template
{
private $mCI;

private $mHeaderView=’header.php’;//头部文件
private $mFooterView=’footer.php’;//尾部文件
private $mTemplateView=’template.php’;//模板框架

public function __construct()
{
$this->mCI = &get_instance();
}

public function showView($rContent_data)
{
//$rContent_data 在控制器中实现内容逻辑与视图
$data=array(
$header_data=$this->getHeader(),
$footer_data=$this->getFooter(),
$content_data=$rContent_data
);
$this->mCI->load->view($this->mTemplateView,$data);

}
private function getHeader()
{
$h=new HeaderModel();//实现头部逻辑,
$data=$h->getData();
return $this->mCI->load->view($this->mHeaderView,$data,true);
}
private function getFooter()
{
$f=new FooterModel();//实现尾部逻辑,
$data=$f->getData();
return $this->mCI->load->view($this->mFooterView,$data,true);
}
}

?>
[/php]
这种方式比较适用于头尾变化比较多的情况.

方式三:考虑到ajax请求的情况,使用hook,步骤如下:
1.在config.php开启hook
[php]
$config['enable_hooks'] = TRUE;
[/php]
2.hooks.php添加代码
[php]
$hook['display_override'] = array(
‘class’ => ‘MyDecorate’,
‘function’ => ‘init’,
‘filename’ => ‘MyDecorate.php’,
‘filepath’ => ‘hooks’
//’params’ => array(‘beer’)
);

[/php]
3、hooks目录新增文件MyDecorate.php
[php]
<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);

/**
* @author Zelipe
*
* 2012-05-26
*/
class MyDecorate {
private $CI;

public function __construct() {
$this->CI =& get_instance();
}

public function init() {
$html = ”;

// header html, ‘isAjax’ from helper
if(!isAjax())
$html .= $this->CI->load->view(‘header’, null, true);

// body html
$html .= $this->CI->output->get_output();

// footer html
if(!isAjax())
$html .= $this->CI->load->view(‘footer’, null, true);

$html = str_replace(‘ ‘, ”, $html); // 过滤代码缩进
$this->CI->output->_display($html);
}
}
[/php]
其中 isAjax() 为 helpers,可直接将此方法定义在MyDecorate.php内(可不作判断,如希望控制ajax不引入公用文件则保留)
[php]
// 是否为 ajax 请求
function isAjax() {
return (isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === ‘xmlhttprequest’);
}
[/php]
4、views 目录新增header.php, footer.php。

四、采用layout的方式,即在一个主view里嵌入头尾;
在core目录下创建一个自定义的controller,代码如下:
[php]
class Frontend_Controller extends CI_Controller{
public function __construct(){
parent::__construct();

}

/**
* 加载视图
*
* @access protected
* @param string
* @param array
* @return void
*/
protected function _template($template, $data = array())
{
$data['tpl'] = $template;
$this->load->view(‘layout’, $data);
}
}
[/php]
创建一个主View, 命名为layout.php,
[php]
<!–header…–>
<div class="content">
<?php $this->load->view(isset($tpl) && $tpl ? $tpl : ‘default’); ?>
</div><!– end content –>
<!–footer…–>
[/php]

CI学习 – 分页

举个按关键词搜索结果分页的例子,
1.视图HTML
[php]
<div id="body">
<form action="/index.php/search/index/" method="get">
<p>请输入书名、作者、出版社中的一个或多个来查询。</p>
<p><input type="text" name="s" value="" size="64" /> <input type="submit" value="搜索" /></p>
</form>
</div>
[/php]
即表单提交到名叫search的controller和名叫index的方法, 其中包含了一些动态参数,不是纯列表,故相对比较复杂,后面会提到。

2.控制器
[php]
public function index() {
$keyword = $this->input->get ( ‘s’ );
$offset = $this->input->get ( ‘offset’ );

if (empty ( $offset )) {
$offset = 0;
}

if (! empty ( $keyword )) {
$this->load->model ( ‘book_model’ );
$this->load->library ( ‘pagination’ );

$per_page = 10;
$config ['num_links'] = 5;
$config ['base_url'] = ‘/index.php/’ . $this->router->class . ‘/’ . $this->router->method . ‘/?s=’ . $keyword;
$config ['per_page'] = $per_page;
$config ['total_rows'] = $this->Book_Model->find_by_name ( $keyword, NULL, NULL, true );
$config ['page_query_string'] = false;
$config ['query_string_segment'] = ‘offset’; //重新定义记录起始位置的参数名,默认为per_page

$this->pagination->initialize ( $config );
$data ['books'] = $this->Book_Model->find_by_name ( $keyword, $per_page, $offset );
$this->load->view ( ‘search’, $data );
} else {
$this->load->view ( ‘search’ );
}
}
[/php]
因为config.php中默认的enable_query_strings是false, 起始位置始终在最后,这样出来的结果类似/index.php/search/index/?s=中国/10,页码取不到,需要将此配置改为false;

3.模型
[php]
public function find_by_name($name, $per_page=0, $offset = 0, $is_total = false) {
if ($is_total) {//总数
$query = $this->db->query ( "select count(id) as cnt from {$this->_book} where book_name like ‘%{$name}%’" );
if ($query->num_rows () > 0) {
$row = $query->row ();
$ret = $row->cnt;
}
}else{//列表
$query = $this->db->query ("select * from {$this->_book} where book_name like ‘%{$name}%’ limit {$offset}, {$per_page}");
$ret = $query->result ();
}
return $ret;
}
[/php]
Controller里这样调用
[php]
$this->_template ( ‘index’, $data );
[/php]
另外在config.php里加上这样一句
[php]
$config['subclass_prefix'] = ‘Frontend_’;
[/php]

解决mysql数据连接超时断开的问题

如果mysql的连接的空闲时间超过wait_timeout设置的时间,就会出现mysql server has gone away的错误,解决方法如下
建立一检测函数,如果mysql_ping不成功则关闭旧连接,然后重新建立一个新的连接。
function check_db_link($conn, $type = ‘center_server’) {
if (! mysql_ping ( $conn )) {
global $config;

mysql_close($conn);
//var_dump($config);

$conn = mysql_connect ( $config [$type] ['db_host'], $config [$type] ['db_user'], $config [$type] ['db_password'] );
mysql_select_db ( $config [$type] ['db_name'], $conn );
mysql_query ( “set names utf8″, $conn );
}
return $conn;
}
注:在新建连接之前必须先使用mysql_close($conn);关闭旧的连接,否则返回的连接依然不能用。

php正则表达式获取所有页面链接

[php]
<?php
$s = ‘<div class=\’tdgshid\’><a href=/geshou/2711.htm>凤凰传奇</a></div></td><td><div class=\’tdgshid\’><a href="/geshou/6931.htm">冷漠</a></div></td><td><div class=\’tdgshid\’><a href="http://www.nengzuo.com/test/7192.htm">高安</a></div><a href=\’http://www.nengzuo.com/test/7111.htm\’>php</a>’;
if (preg_match_all ( "/<a .*?href=[\"']{0,1}(.[^>]+)[\"']{0,1}.*?>(.*?)<\/a>/i", $s, $matches )) {
var_dump($matches);
}
[/php]

PHP用CURL伪造IP和来源[转]

文件1.php 请求 文件2.php

1.php代码:
[php]
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘X-FORWARDED-FOR:8.8.8.8′, ‘CLIENT-IP:8.8.8.8′));//IP
curl_setopt($ch, CURLOPT_REFERER, "http://www.yzswyl.cn/ "); //来路
curl_setopt($ch, CURLOPT_HEADER, 1);
$out = curl_exec($ch);
curl_close($ch);
[/php]

2.php代码:
[php]
function getClientIp() {
if (!empty($_SERVER["HTTP_CLIENT_IP"]))
$ip = $_SERVER["HTTP_CLIENT_IP"];
else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if (!empty($_SERVER["REMOTE_ADDR"]))
$ip = $_SERVER["REMOTE_ADDR"];
else
$ip = "err";
return $ip;
}
echo "IP: " . getClientIp() . "";
echo "referer: " . $_SERVER["HTTP_REFERER"];
[/php]
伪造成功,这是不是给“刷票”的朋友提供了很好的换IP的方案!!

摘自:http://yzswyl.cn/blread-1540.html

优化网站性能 提高网站速度访问速度的14条实践

相信互联网已经越来越成为人们生活中不可或缺的一部分。ajax,flex等等富客户端的应用使得人们越加“幸福”地体验着许多原先只能在C/S实 现的功 能。比如Google机会已经把最基本的office应用都搬到了互联网上。当然便利的同时毫无疑问的也使页面的速度越来越慢。自己是做前端开发的,在性 能方面,根据yahoo的调查,后台只占5%,而前端高达95%之多,其中有88%的东西是可以优化的。

以上是一张web2.0页面的生命周期图。工程师很形象地讲它分成了“怀孕,出生,毕业,结婚”四个阶段。如果在我们点击网页链接的时候能够意识到 这个过程而不是简单的请求-响应的话,我们便可以挖掘出很多细节上可以提升性能的东西。今天听了淘宝小马哥的一个对yahoo开发团队对web性能研究的 一个讲座,感觉收获很大,想在blog上做个分享。

相信很多人都听过优化网站性能的14条规则。更多的信息可见developer.yahoo.com

1. 尽可能的减少 HTTP 的请求数 [content]
2. 使用 CDN(Content Delivery Network) [server]
3. 添加 Expires 头(或者 Cache-control ) [server]
4. Gzip 组件 [server]
5. 将 CSS 样式放在页面的上方 [css]
6. 将脚本移动到底部(包括内联的) [javascript]
7. 避免使用 CSS 中的 Expressions [css]
8. 将 JavaScript 和 CSS 独立成外部文件 [javascript] [css]
9. 减少 DNS 查询 [content]
10. 压缩 JavaScript 和 CSS (包括内联的) [javascript] [css]
11. 避免重定向 [server]
12. 移除重复的脚本 [javascript]
13. 配置实体标签(ETags) [css]
14. 使 AJAX 缓存

在firefox下有一个插件yslow,集成在firebug中,你可以用它很方便地来看看自己的网站在这几个方面的表现。

这是对用yslow对我的网站西风坊测评的结果,很遗憾,只有51分。呵呵。中国各大网站的分值都不高,刚测了一下,新浪和网易都是31分。然后yahoo(美国)的分值确实97分!可见yahoo在这方面作出的努力。从他们总结的这14条规则,已经现在又新增加的20个点来看,有很多细节我们真得是怎么都不会去想,有些做法甚至是有些“变态”了。

第一条、尽可能的减少 HTTP 的请求数Make Fewer HTTP Requests

http请求是要开销的,想办法减少请求数自然可以提高网页速度。常用的方法,合并css,js(将一个页面中的css和js文件分别合并)以及 Image maps和css sprites等。当然或许将css,js文件拆分多个是因为css结构,共用等方面的考虑。阿里巴巴中文站当时的做法是开发时依然分开开发,然后在后台 对js,css进行合并,这样对于浏览器来说依然是一个请求,但是开发时仍然能还原成多个,方便管理和重复引用。yahoo甚至建议将首页的css和js 直接写在页面文件里面,而不是外部引用。因为首页的访问量太大了,这么做也可以减少两个请求数。而事实上国内的很多门户都是这么做的。

而css sprites是指只用将页面上的背景图合并成一张,然后通过css的background-position属性定义不过的值来取他的背景。淘宝和阿里巴巴中文站目前都是这样做的。有兴趣的可以看下淘宝和阿里巴巴的背景图

http://www.csssprites.com/ 这是个工具网站,它可以自动将你上传的图片合并并给出对应的background-position坐标。并将结果以png和gif的格式输出。

第二条、使用CDN(内容分发网络): Use a Content Delivery Network

简单地讲,通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的 cache服务器内,通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,杭州的用户访问近杭州服务器上的内容,北京的访问 近北京服务器上的内容。这样可以有效减少数据在网络上传输的时间,提高速度。更详细地内容大家可以参考百度百科上对于CDN的解释。Yahoo!把静态内容分布到CDN减少了用户影响时间20%或更多。

CDN技术示意图:

CDN组网示意图:

第三条、 添加Expire/Cache-Control 头:Add an Expires Header

现在越来越多的图片,脚本,css,flash被嵌入到页面中,当我们访问他们的时候势必会做许多次的http请求。其实我们可以通过设置Expires header 来缓存这些文件。Expire其实就是通过header报文来指定特定类型的文件在览器中的缓存时间。大多数的图片,flash在发布后都是不需要经常修 改的,做了缓存以后这样浏览器以后就不需要再从服务器下载这些文件而是而直接从缓存中读取,这样再次访问页面的速度会大大加快。一个典型的HTTP 1.1协议返回的头信息:
HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: “3e86-410-3596fbbc”
Content-Length: 1040
Content-Type: text/html

其中通过服务器端脚本设置Cache-Control和Expires可以完成。

如,在php中设置30天后过期:

<!--pHeader("Cache-Control: must-revalidate");
$offset = 60 * 60 * 24 * 30;
$ExpStr = "Expires: " . gmdate("D, d M Y H:i:s"time() + $offset) . " GMT";
Header($ExpStr);-->

也可以通过配置服务器本身完成,这些偶就不是很清楚了,呵呵。想了解跟多的朋友可以参考http://www.web-caching.com/

据我了解,目前阿里巴巴中文站的Expires过期时间是30天。不过期间也有过问题,特别是对于脚本过期时间的设置还是应该仔细考虑下,不然相应的脚本功能更新后客户端可能要过很长一段时间才能“感知”到这样的变化。以前做[suggest项目] 的时候就遇到过这个问题。所以,哪些应该缓存,哪些不该缓存还是应该仔细斟酌一番。

第四条、启用Gzip压缩:Gzip Components

Gzip的思想就是把文件先在服务器端进行压缩,然后再传输。这样可以显著减少文件传输的大小。传输完毕后浏览器会 重新对压缩过的内容进行解压缩,并执行。目前的浏览器都能“良好”地支持 gzip。不仅浏览器可以识别,而且各大“爬虫”也同样可以识别,各位seoer可以放下心了。而且gzip的压缩比例非常大,一般压缩率为85%,就是 说服务器端100K的页面可以压缩到25K左右再发送到客户端。具体的Gzip压缩原理大家可以参考csdn上的《gzip压缩算法 这篇文章。雅虎特别强调, 所有的文本内容都应该被gzip压缩: html (php), js, css, xml, txt… 这一点我们网站做得不错,是一个A。以前我们的首页也并不是A,因为首页上还有很多广告代码投放的js,这些广告代码拥有者的网站的js没有经过gzip压缩,也会拖累我们网站。

以上三点大多属于服务器端的内容,本人也是粗浅地了解而已。说得不对的地方有待各位指正。

第五条、将css放在页面最上面 ( Put Stylesheets at the Top)

将css放在页面最上面,这是为什么?因为 ie,firefox等浏览器在css全部传输完全之前不会去渲染任何的东西。理由诚如小马哥说得那样很简单。css,全称Cascading Style Sheets (层叠样式表单)。层叠即意味这后面的css可以覆盖前面的css,级别高的css可以覆盖级别低的css。在[css之!important] 这篇文章的最下面曾简单地提到过这层级关系,这里我们只需要知道css可以被覆盖的。既然前面的可以被覆盖,浏览器在他完全加载完毕之后再去渲染无疑也是合情合理的很多浏览器下,如IE,把样式表放在页面的底部的问题在于它禁止了网页内容的顺序显示。浏览器阻止显示以免重画页面元素,那用户只能看到空白页了。Firefox不会阻止显示,但这意味着当样式表下载后,有些页面元素可能需要重画,这导致闪烁问题。所以我们应该尽快让css加载完毕

顺着这层意思,如果我们再细究的话,其实还有可以优化的地方。比如本站上面包含的两个css文件,<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/themes/google/style/google.css” type=“text/css” media=“screen” /> 和<link rel=“stylesheet” rev=“stylesheet” href=“http://www.space007.com/css/print.css” type=“text/css” media=“print” />。 从media就可以看出第一个css是针对浏览器的,第二个css文件是针对打印样式的。从用户的行为习惯上来将,要打印页面的动作一定是发生在页面页面 显示出来之后的。所以比较好的方法应该是在页面加载完毕之后再动态地为这张页面加上针对打印设备的css,这样又可以提高一点速度。(哈哈)

第六条、将script放在页面最下面 (Put Scripts at the Bottom )

将脚本放在页面最下面的目的有那么两点: 1、 因为防止script脚本的执行阻塞页面的下载。在页面loading的过程中,当浏览器读到js执行语句的时候一定会把它全部解释完毕后在会接下来读下 面的内容。不信你可以写一个js死循环看看页面下面的东西还会不会出来。(setTimeout 和 setInterval的执行有点类似于多线程,在相应的响应时间之前也会继续下面的内容渲染。)浏览器这么做的逻辑是因为js随时可能执 行 location.href或是其他可能完全中断此页面过程的函数,即如此,当然得等他执行完毕之后再加载咯。所以放在页面最后,可以有效减少页面可 视元素的加载时间。        2、脚本引起的第二个问题是它阻塞并行下载数量。HTTP/1.1规范建议浏览器每个主机的并行下载数不超过2个(IE只能为2个,其他浏览器如ff等都是默认设置为2个,不过新出的ie8可以达6个)。因此如果您把图像文件分布到多台机器的话,您可以达到超过2个的并行下载。但是当脚本文件下载时,浏览器不会启动其他的并行下载。

当然对各个网站来说,把脚本都放到页面底部加载的可行性还是值得商榷的。就比如阿里巴巴中文站的页面。很多地方有内联的js,页面的显示严重依赖于此,我承认这和无侵入脚本的理念相差甚远,但是很多“历史遗留问题”却不是那么容易解决的。

第七条、避免在CSS中使用Expressions (Avoid CSS Expressions )

不过这样就多了两层无意义的嵌套,肯定不好。还需要一个更好的办法。

第八条、把javascript和css都放到外部文件中 (Make JavaScript and CSS External )

这点我想还是很容易理解的。不仅从性能优化上会这么做,用代码易于维护的角度看也应该这么做。把css和js写在页面内容可以减少2次请求,但也增 大了页面的大小。如果已经对css和js做了缓存,那也就没有2次多余的http请求了。当然,我在前面中也说过,有些特殊的页面开发人员还是会选择内联 的css和js文件。

第九条、减少DNS查询 (Reduce DNS Lookups)

在 Internet上域名与IP地址之间是一一对应的,域名(kuqin.com)很好记,但计算机不认识,计算机之间的“相认”还要转成ip地址。在网络 上每台计算机都对应有一个独立的ip地址。在域名和ip地址之间的转换工作称为域名解析,也称DNS查询。一次DNS的解析过程会消耗20-120毫秒的 时间,在dns查询结束之前,浏览器不会下载该域名下的任何东西。所以减少dns查询的时间可以加快页面的加载速度。yahoo的建议一个页面所包含的域 名数尽量控制在2-4个。这就需要对页面整体有一个很好的规划。目前我们这点做的不好,很多打点的广告投放系统拖累了我们。

第十条、压缩 JavaScript 和 CSS (Minify JavaScript )

压缩js和css的左右很显然,减少页面字节数。容量小页面加载速度自然也就快。而且压缩除了减少体积以外还可以起到一定的保护左右。这点我们做得不错。常用的压缩工具有JsMin、YUI compressor等。另外像http://dean.edwards.name/packer/还给我们提供了一个非常方便的在线压缩工具。你可以在jQuery的网页看到压缩过的js文件和没有压缩过的js文件的容量差别:

当然,压缩带来的一个弊端就是代码的可读性没了。相信很多做前端的朋友都遇到过这个问题:看Google的效果很酷,可是去看他的源代码却是一大堆 挤在一起的字符,连函数名都是替换过的,汗死!自己的代码也这样岂不是对维护非常不方便。所有阿里巴巴中文站目前采用的做法是在js和css发布的时候在 服务器端进行压缩。这样在我们很方便地维护自己的代码。

第十一条、避免重定向 (Avoid Redirects )

不久前在ieblog上看到过《Internet Explorer and Connection Limits》这篇文章,比如 当你输入http://www.kuqin.com/ 的时候服务器会自动产生一个301服务器转向 http://www.kuqin.com/ ,你看浏览器的地址栏就能看出来。这种重定向自然也是需要消耗时间的。当然这只是一个例子,发生重定向的原因还有很多,但是不变的是每增加一次重定向就会增加一次web请求,所以因该尽量减少。

第十二条、移除重复的脚本 (Remove Duplicate Scripts )

这点我想不说也知道,不仅是从性能上考虑,代码规范上看也是这样。但是不得不承认,很多时候我们会因为图一时之快而加上一些或许是重复的代码。或许一个统一的css框架和js框架可以比较好的解决我们的问题。小猪的观点很对,不仅是要做到不重复,更是要做到可重用。

第十三条、配置实体标签(ETags) (Configure ETags )

这点我也不懂,呵呵。在inforQ上找到一篇解释得比较详细的说明《使用ETags减少Web应用带宽和负载》,有兴趣的同学可以去看看。

第十四条、使 AJAX 缓存 (Make Ajax Cacheable )

ajax还要去缓存?做ajax请求的时候往往还要增加一个时间戳去避免他缓存。It’s important to remember that “asynchronous” does not imply “instantaneous”.(记住“异步”不是“瞬间”这一点很重要)。记住,即使AJAX是动态产生的而且只对一个用户起作用,他们依然可以被缓 存。

WordPress静态化方案[原]

今天觉得直接访问php比较慢,然后就想设置一下可以生成静态页面,减少服务器读取数据库的负担.搜了一下,发现有cos-html-cache(http://wordpress.org/extend/plugins/cos-html-cache/)[国产的], wp-super-cache(http://wordpress.org/extend/plugins/wp-super-cache/)等,然后就下载了一个cos-html-cache并上传到wp-content/plugins/下,登录到后台,执行下面的步骤:

  1. 进入设置/永久链接(settings/permalinks),在通用设置(Common settings)里选择”自定义结构”,填入”/archives/%year%/%monthnum%/%post_id%.htm”,保存更改,此时如果根目录下面的.htaccess文件可写,wp会自动更改其内容,如果不可写,可以自己编写.htaccess文件,输入类似下面的内容:
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
  2. 切换到插件(plugins)界面:激活cos-html-cache插件.
  3. 下面再刷新一下页面就可以看到效果了.

注:在写自定义URL规则的时候最后一定要写文件后辍名,比如.htm

WordPress静态化插件cos-html-cache

功能描述:生成文章和首页HTML缓存文件,当有评论、修改、添加和删除文章的时候更新首页和当前页面缓存。注意,不缓存其他页面。

环境需求:服务器必须支持URLrewrite

插件独立性:不依赖其他插件

你是否需要该插件?满足下列要求表示你需要该插件:

  1. 访问量过大;
  2. 服务器和数据库负荷过高;
  3. 不需要花哨的插件,仅仅是发表文章……
  4. 插件过多,页面载入速度太慢;
  5. 我想上面的原因已经够了

满足下面的条件则表示你不需要此插件:

  1. 安装了url 定向插件的,比如permalink redirect;
  2. 喜欢测试花哨的插件,缓存会让你不能即时看到测试结果;
  3. 页面需要实时更新数据,如非JS的访客统计程序;
  4. 总之,得到了一些,必须失去一些……

安装方法:

  1. 首先,永久连接不能使用默认格式;
  2. 修改你的永久链接格式,保证你的url路径看起来像真正的HTML文件的路径,中文推荐采用 /html/y%year%/%post_id%.html如果你和我一样不怕麻烦愿意为每篇文章写一个英语的post slug,建议采用这样的格式:/html/y%year%/%post_id%_%postname%.html;
  3. 下载插件,在后面的下载页面;
  4. 后台激活插件;
  5. 选项-〉coshtmlcache 将以前的文章批量生成cache;
  6. 如果你会css,可以自行修改插件目录下的css文件来显示留言;
  7. done

change log:

  1. 2007.05.28 version1.0 released;
  2. cookie read bug fixed;
  3. 考虑到有网友需要没有ajax集成的插件,所以特此增加了没有ajax的插件,并且重新确认了cookie的有效性;
  4. 增加了JS,判断当前用户是否登陆,如果登陆,发表留言则不需要留下姓名和email,同时该插件不在集成Ajax comment
  5. 解决了留言者姓名中文乱码问题;
  6. 增加了页面缓存功能

下载地址:

  1. version1.0 cos-html-cache.zip (替代后并重新批量更新缓存)
  2. version1.01 cos-html-cache101.zip(替代后并重新批量更新缓存)
  3. version1.1 cos-html-cache-v11.zip(替代后并重新批量更新缓存)
  4. version1.11 cos-html-cachev111.zip(替代后并重新批量更新缓存)

测试地址:demo.storyday.com

FAQ:

  1. 我后缀名是.htm不是.html的可以用么?

    可以,你设置永久连接是什么后缀就可以用什么后缀,jsp都可以,不需要修改插件。

  2. 如果我的永久连接是目录形式的可以用么?

    可以,插件将会在目录下生成index.html文件。

  3. 缓存的静态HTML文件在哪里?

    放在你URL链接对应的地方,比如你页面的地址是http://www.xxx.com/dir1/dir2/2.html 那么静态文件就在 dir1/dir2 目录下

  4. 后台批量生成的时候出现超时错误如何处理?

    如果你的文章太多,应该选择分步生成缓存,不要一次重建所有的缓存文件!

  5. 如果我的永久连接不合理怎么办?

    放心修改就是,不用担心链接失效问题,我自己都修改过几次,看看这里:http://www.storyday.com/html/y2007/706_permalinks-migration-plugin.html

  6. 静态化后不支持pingback,如何处理?

    在你的模板文件夹下的header.php文件中,加上这样的pingback meta:<link rel=”pingback” href=”<?php bloginfo(’pingback_url’); ?>” />,加在css调用之前,当调用静态文件的时候,htaccess和这个meta会帮你处理ping back的!

  7. 如果确定静态化成功?

    FTP查看有没有html文件生成,或者看看当前页面的源代码的最后面是否有这样的代码:<!– this is a real html file created at 2007-06-02 20:28:21 –>

  8. 生成了index.html为什么访问的还是index.php

    服务器配置文件访问优先级的问题,本插件无能为力,请修改服务器配置。

  9. 必须要ajax comment才能使用此插件么?

    不需要,任何模板均可,目前不集成任何其他ajax comment插件

  10. 如何停用插件?

    先在后台或者FTP中删除缓存文件,然后停止该插件即可,注意,一定要删除首页的index.html文件,要不就会出现评论中第51楼的“问题”

  11. 如何不生成首页?

    打开 php文件 ,看看最后几行

    add_action(’edit_post’, ‘createIndexHTML’);将 带有 createIndexHTML的add_action的行 删除即可,用了这个,没有必要用wp-cache,如果你要用也没有问题

再次提醒朋友们:有问题,先看你安装步骤是否正确,再看FAQ,然后再决定是否需要在下面的评论框中发表你的问题!