### PHP 应用提速面面观

PHP 最大的优点之一显然在于它的快速度。一般情况下 PHP 总是具有足够的速度支持 Web 内容动态生成，许多时候你甚至无法找出比它更快的方法。然而，当你不得不面对庞大的访问量、高负荷的应用、有限的带宽以及其他各种带来性能瓶颈的因素时，你可能会问问自己是否可以做点什么让网站运行得更好。或许只要加上一个很不起眼的免费模块，你的 PHP 应用性能以及 Web 服务器响应速度就会有显著的改善。本文讨论的就是如何进一步提高 php 应用的性能，给用户以更美妙的浏览感受。本文分三个方面（代码优化、缓存、内容压缩）阐述提高 PHP 应用性能的各种技术，并介绍各个领域的知名产品。
代码优化
首先我们来看看代码优化。注意，这里的代码优化可不是指把代码写得更加美观漂亮，因为这恐怕已经是众所周知没有必要继续讨论了；另外，如果你已经考虑到了速度问题，很可能你早就对 PHP 的源代码作了一些优化。不过，有些工具却能够自动地帮助我们完成这些繁杂的工作，如 Zend Optimizer 就是这样一个工具。Zend Optimizer 可以从 Zend Technologies 免费得到，但你必须同意它的许可约定，注意它不是以 GPL 方式发行。Zend Optimizer 获取由 Zend Engine 运行时编译生成的中间代码，并对它进行优化，从而使得中间代码具有更快的执行效率。
Zend Optimizer 的安装方法非常简单，你只需下载为自己所用平台提供的预编译版本，把下面两行代码加入到 php.ini，然后重新启动 Web 服务器即可：
zend_optimizer.optimization_level=15
zend_extension="/path/to/ZendOptimizer.so"
zend_loader.enable=Off
这里额外增加的第三行代码是可选的。禁止 zend_loader 似乎能够让 Zend Optimizer 的速度更快一点，所以在 php.ini 中加上这行代码是值得的。注意：只有当你不使用 Zend Encoder Runtime 时，你才可以禁用 zend_loader。
缓存
如果你想要让自己庞大的 PHP 应用有更好的性能表现，采用缓存也是一种很好的方法。现在已经有许多缓存方案可供选择，其中包括：Zend Cache，APC，和 Afterburner Cache。
所有这些产品都属于“缓存模块”。当第一次出现对.php 文件的请求时，它们会在 Web 服务器内存中保存 PHP 的中间代码，此后就用“经过编译”的版本响应后继的请求。这种方法确实能够改善应用的性能，因为它使得磁盘访问量减低到了最少的程度（代码已经读取和解析），代码直接在内存中运行使得服务器响应请求的速度大大提高。当然，缓存模块还会监视 PHP 源文件的变化，必要时重新缓存页面，从而防止了用户得到的页面仍旧由过时的 PHP 代码生成。由于缓存模块能够明显地降低服务器的负载、提高 PHP 应用的响应效率，因此它们非常适合于负载较大的网站使用。
如何选择这些缓存产品
Zend Cache 是 Zend Technologies 公司的商业软件，而 Zend Technologies 就是前面提到的那个为我们提供 PHP 引擎和免费 Zend Optimizer 的公司。Zend Cache 确实是名不虚传！对于大型的 PHP 页面，你可以感觉到第一次运行之后速度就会有所提高，而且服务器也会有更多的可用资源。遗憾的是这个产品并不免费，不过在有些情形下它仍旧是物超所值。
Afterburner Cache 是来自 Bware Technologies 的免费缓存模块，当前这个产品还是 Beta 版。Afterburner Cache 的做法看起来与 Zend Cache 差不多，但它对性能的改善程度（还）不能与 Zend Cache 相比，而且它还不能与 Zend Optimizer 一起工作。
APC 是 Alternative PHP Cache 的缩写，它是来自 Community Connect 的又一个免费缓存模块。这个产品已经具有足够的稳定性供正式场合使用，而且它看起来也能在很大程度上提高响应请求的速度。
内容压缩
前面我们讨论了几种提高 PHP 应用性能的方法，下面来看看使得浏览者感到网站速度太慢的另外一个重要因素：下载速度。如果 PHP 应用在内部 Intranet 上运行，而且每一台客户机都以 100 MB/s 的速度连接到服务器，那么下载速度应该不是什么问题。然而，如果服务器还要为慢腾腾的 Modem 用户提供服务，那么值得考虑内容压缩。大多数浏览器都根据 IETF 标准支持用 gzip 进行内容压缩。这意味着你可以用 gzip 压缩内容然而发送给浏览器，由浏览器解压缩数据之后再显示页面，这整个过程对用户来说完全透明。至于服务器端的内容压缩，现在已经有许多不同的方法可供使用。
例如，来自 Remote Communications 的免费 Apache 模块 mod_gzip 就具有为支持这类内容编码的浏览器压缩静态 Web 内容的能力。对于绝大多数静态 Web 内容，mod_gzip 都非常有效。mod_gzip 可以方便地编译到 Apache 里面，也可以作为 DSO 使用。据 Remote communications 公司说，mod_gzip 也能够压缩来自 mod_php、mod_perl 等的动态内容。我试了一次又一次，但看来还是不行。我看了许多关于 mod_gzip 的论坛和文章，看来到了 mod_gzip 的下一个版本（可能是 1.3.14.6f）这个问题有望得到解决。在此之前，我们可以在网站的静态部分使用 mod_gzip。
然而有时我们确实需要压缩动态内容，所以必须找找其他办法。有一种办法是使用 class.gzip_encode.php，这是一个可以用来压缩页面内容的 PHP 类，具体方法是在 PHP 脚本的开头和末尾调用该类的某些函数。如果要在网站级实现这个方案，可以从 php.ini 文件的 auto_prepend 以及 auto_append 指令调用这些函数。这种方法虽然有效，但它无疑为高负载的网站带来了更多的开销。关于如何使用这个类的详细说明，请参见它的源代码。它的源代码说明相当完善，作者告诉了你所有你必须知道的事情。
PHP 4.0.4 有一个新的输出缓存句柄 ob_gzhandler，它与前面的类相似，但用法不同。使用 ob_gzhandler 时要在 php.ini 中加入的内容如下：
output_handler = ob_gzhandler ;
这行代码使得 PHP 激活输出缓存，并压缩它发送出去的所有内容。如果由于某种原因你不想在 php.ini 中加上这行代码，你还可以通过 PHP 源文件所在目录的.htaccess 文件改变默认的服务器行为（不压缩），语法如下：
php_value output_handler ob_gzhandler
或者是从 PHP 代码调用，如下所示：
ob_start("ob_gzhandler");
采用输出缓存句柄的方法确实非常有效，而且不会给服务器带来什么特殊的负荷。但必须注意的是，Netscape Communicator 对压缩图形的支持不佳，因此除非你能够保证所有用户都使用 IE 浏览器，否则你应该禁止压缩 JPEG 和 GIF 图形。一般地，对于所有其他文件，这种压缩都有效，但建议你针对各种浏览器都分别进行测试，特别是当你使用了特殊的插件或者数据查看器时这一点尤其重要。