采用 PEAR 来缓冲 PHP 程序 BHqJ~2&FDW
,:j^EDCsaJ
PHP 世界中缓冲是一个热门的话题,因为 PHP 产生的动态页面,每次用户请求都需要重新计算,不论请求的结果是否一样,同时,PHP 每次都会编译一次脚本。这样的超负荷运转对一个流量很高的网站来说肯定难以忍受。幸运的是, Web 的结果可以缓冲,而不需要重新运行和编译脚本,商品化的产品像 ZendCache 或者开源的 Alternate PHP Cache都提供了把 PHP 脚本编译为字节代码并缓冲的办法。 )9==6p
G
?H`9*y
PEAR 的缓冲包提供了缓冲动态内容,数据库查询和 PHP 函数调用的框架。 uG~%/7Qt{
]Ocf %(
就像 Perl 有 CPAN, TeX 有 CTAN,PHP 也有自己的中心资源库,存放类,库和模块。这个库称为 PEAR(PHP Extension and Add-On Repository)。 5Tkh6 s
RR*<txdN
本文假设你已经安装了 PEAR 环境,如果没有的话,可以去 PHP 网站下载。 e$fxC-sZ
U5%EQc-"P
9["yL{IPe
PEAR 的缓冲包包含一个总体的缓冲类和几个特别的子类。缓冲类使用容器类来存贮和管理缓冲数据。 j'I$F1>Te
!Tr +: SM
下面是 PEAR 缓冲当前所包含的容器,以及各自的参数: mS6L6)] S
b>Iqk
file -- file 容器在文件系统存储了缓冲的数据,是最快的容器。 R@u6mMX{N,
esWgYAc3{
cache_dir -- 这是容器存储文件的目录。 [?yOJU%`
+3!um
filename_prefix -- 缓冲文件的前缀,例如:"cache_"。 A7 E*w
:TxfkicN\
shm -- shm 容器把缓冲数据放入共享内存,基准测试显示,目前的实现下,这个容器的速度要比文件容器慢。 2>_6b>9]
[wi "
shm_key -- 共享内存使用的键值。 z{7&= $
zsc8Lw
shm_perm -- 使用共享内存数据段的权限。 <{JHFU`^
VrrCW/o
shm_size -- 分配共享内存的大小。 .YKQ6
&Dgho
sem_key -- 信号灯的键值。 Z
~:S0HDP
TY],H=
sem_perm -- 信号灯的权限。 !Z`~=n3bk
[j`It4^nC
db -- PEAR 的数据库抽象层。 n'U*8ID
.yd{7Te
dsn -- 数据库连接的 DSN 。可以参考 PEAR 的 DB 文档。 =(3Qbb1i
Y, )'0O
cache_table -- 表的名字。 :w_Zr5H]
/#GX4&z
phplib -- phplib 容器使用数据库抽象层存储缓冲。 ~6Vs>E4G
Y7zg
db_class i-vhX4:bd
x;?4A J{
db_file &gw. &/t
kS%FV;9>(
db_path ;^^u _SuH
@(,k%84z
local_file dw5.vXL`
7%c9 nY
local_path h7)^$Hd
dP=1*
ext/dbx -- PHP 的数据库抽象层扩展,如果像把缓冲存入数据库,可以采用这个容器。 s7A{<>:
.9#4qoM'
module y{0`+/\`
mVcpYyD|k
host >JkQU e
YR@@:n'TP
db vQ#$.*Cvn
EW%%W6O6
username mnzamp
Py^F},?J
password y)X;g:w
gYn1-/Z>I
cache_table mL?9AxO
2asA]sY
persistent 2Vxr
EDcR:Dw3
使用 PEAR Cache 所得到的性能提升取决于你所选择的缓冲容器,例如,把数据库的结果再次存入数据库缓冲中就显得毫无意义。 4_TxFulX.
d kHcG&)
PEAR Cache 的函数缓冲模块能把任何函数或者方法的结果缓冲,不论是 PHP 的内置函数还是用户自定义函数,他缺省采用文件容器,把缓冲数据放入到一个叫做 #I|Vyufw
function_cache 的目录。 bHH{bv~Z
UO47XAO
!@{_Qt1
Cache_Function 类的构造器可以有三个可选的参数: OkGg4X|9
^3B{|cqf
$container :缓冲容器的名字。 M=HW2xn
.+t{o[
$container_options :缓冲容器的数组参数。 ?7 e|gpQ|
6a[D]46y,2
$expires:缓冲对象过期的时间(秒数)。 }@J&yrqg
d/!sHr69
普通的函数调用采用 Cache_Function 类的 call() 方法时,就能触发缓冲。调用 call() 很容易,的一个参数是函数的名字,然后是函数的参数,第二个参数是要调用函数中的第一个,依此类推,我们来看例子: FY)v rM*yh
sesr`,m.,
例 1: 缓冲函数和方法的调用 .;ml[DXH
Wp/!;
// 调用 PEAR Cache 的函数缓冲。 PwU}<Hrl]
\[Op:^S
<?php H=?v$!
i
require_once 'Cache/Function.php'; B(wk $2
~
nNsq(4
// 定义一些类和函数。 M8X*fYn
%Rj:r!XB:
class foo { $,otW2:)
function bar($test) { %_;q<@9)
echo "foo::bar($test)<br>"; O6LZ<}oUR
} Y$uXBTR`y/
} w~y+Pv@
GzWmXm
class bar { x tg3~/H
function foobar($object) { dRTtDH"%
echo '$'.$object.'->foobar('.$object.') I gcVl/d
'; `~vqu69MF9
} wUHuykF
} kD
dY
i7g>
Zy,U'Dv
$bar = new bar; Rcs7 'q5
m:5 *:Ii.
function foobar() { {LYA?w^GT
echo 'foobar()'; ]b4*`}\
} v^2K=f[nE
XmXp0b7
// 取得 Cache_Function 对象 |C?<!6.QmV
"P\k_-a'
$cache = new Cache_Function(); 8.HqQ:?&2t
7].tt
// 对 foo 类的静态函数 bar() 作缓冲(foo::bar())。 2c@4<kyfP
$cache->call('foo::bar', 'test');
YqX/7b+
'<5Gf1 @|
// $bar->foobar() KGdL1~
$cache->call('bar->foobar', 'bar'); :$."x
'
zRN_`U
$cache->call('foobar'); ,u7:l
?> W=41jw
jjL(=n<J<"
ba& \~_4
J5h;~l!y
下面我们采用 Cache_Output 来把输出作缓冲: b7Jk{x #u
SjV;&
1Z/
例子 2: 缓冲脚本的输出 fC+<n{"C
y3@R>@$
// 加载 PEAR Cache 的输出缓冲 $HT
{}^B
&dp<i[ec^
<?php ;W,XP#{W
require_once 'Cache/Output.php'; 5xX*68]%
0G ^73Z
$cache = new Cache_Output('file', array('cache_dir' => '.') ); NBZFIFO<
{;1Mud
// 计算要缓冲页面的标记,我们假定页面的缓冲取决于 GhpVi<FL
// URL, HTTP GET 和 POST 变量以及 cookies。 S"0<`{Gv
f#}P>,TP
$cache_id = $cache->generateID(array('url' => $REQUEST_URI, 'post' => $HTTP_POST_VARS, 'cookies' => $HTTP_COOKIE_VARS) ); pe$"
nUy|
N-EVHe'}6
// 查询缓冲 1^^<6e
p&~8N#I#
if ($content = $cache->start($cache_id)) { u^T)4~(
.<566g}VP
// 缓冲命中 hi4#8W
echo $content; H!mNHY_fA
die(); 2iC7c6hc
} ZZk6 @C
Lpd q^X
// 缓冲丢失 $\?BAkx
q66!xhp;?
// -- 在这里插入内容产生代码 -- NF+^
]pr( hk
// 把页面存入缓冲 ={ P
echo $cache->end(); ~x;1&\'k
?> "
UaUaSg#
l?GN& u
利用 Cache_Output 类,很容易把一个动态的数据库驱动的网站应用转化为静态,从而极大的提升站点的性能。 E-jL"H*
w6 0I;.hy
越来越多的站点在采用 GZIP 压缩 HTML 内容,这样减少了服务器的带宽消耗,对于使用 Modem 上网的用户来说也能受益不少。 QII-9RxX"
7(c7-
Cache_OutputCompression 扩展了 Cache_Output 类的功能,他把 GZIP 压缩的 HTML 内容进行缓冲,从而节省了 CPU 压缩的时间。