多数大学生出来选择的工作和专业无关
首页 > 专业知识

提高PHP运行速度的小技巧分享

时间:2018-05-04 18:03:16 [来源]:郑州PHP培训学校

   提高PHP运行速度的小技巧分享

  使用PHP的最大1个优势就是速度快。一般情况下,PHP总是具有足够的速度支持Web内容动态生成,许多时候甚至无法找出比它更快的方法。然而,当面对庞大的访问量、高负荷的应用、有限的带宽,以及其他各种带来性能瓶颈的因素时,就需要考虑怎样提高PHP的性能了。
  1、代码优化
  代码优化不仅仅是写出干净和清晰的代码,而是对代码进行一定的简化。可以使用Zend Optimizer来自动帮助完成这些繁杂的工作。Zend Optimizer可以从Zend Technologies的网站http://www.zend.com/免费得到,但必须同意它的许可约定,因为它不是以GPL方式发行的。它的原理很简单,即通过检测Zend引擎产生的中间代码,并对它进行优化,从而获得更高的执行速度。
  在使用了Zend Optimizer后,复杂的PHP源程序的执行效率马上会得到显著提高,缺点是优化后的代码可读性下降,给代码修改带来困难。
  Zend Optimizer的安装方法非常简单,只要根据用户使用的平台,下载相关的预编译版本,把下面2行代码加入到php.ini文件中,重新启动Web服务器就行了:
  zend_optimizer.optimization_level=15
  zend_extension=″/path/to/ZendOptimizer.so″zend_loader.enable=Off
  额外增加的第三行代码是可选的,因为禁用zend_loader将会使优化速度更快。需要注意的是,只有在不使用Zend Encoder Runtime的时候,才可以禁用zend_loader。
  2、使用缓存
  如果PHP程序的规模很大,那么提高速度的办法就是使用缓存。现在已经有许多缓存方案可供选择,其中包括Zend Cache、APC和Afterburner Cache。
  上面这几种都是“缓存模块”(caching modules)。第一次调用PHP文件时,缓存模块从PHP源代码生成一些中间代码,并把这些中间代码存储在Web服务器的内存中。以后再调用这些文件时,就可以直接使用内存中“编译”过的代码。这种方法确实能够改善应用的性能,因为它使得磁盘访问量减低到了最少的程度(代码已经读取和解析),代码直接在内存中运行,使得服务器响应请求的速度大大提高。
  当然,缓存模块还会监视PHP源文件的变化,必要时会重新缓存页面,从而防止用户得到的页面仍旧由过时的PHP代码生成。由于缓存模块能够明显地降低服务器的负载,提高PHP应用的响应效率,因此它们非常适合于负载较大的网站使用。
  Zend Cache是Zend Technologies公司开发的商业软件。在第一次运行后,PHP页面的运行速度立刻会有很大的提高,服务器的空闲资源也更多了。缺点是它不是免费的,但性价比还是很高的。
  Afterburner Cache是Bware Technologies公司开发的免费缓存模块。功能与Zend Cache基本一样,但提高性能方面比不上Zend Cache。
  APC(Alternative PHP Cache)是由Community Connect公司开发的另一种免费缓存模块,目前版本是2.0.4,可以从http://pecl.php.net/package/APC获得。对于产品应用来说,它的性能很稳定,而且也能在很大程度上提高响应请求的速度。
  3、压缩网页内容
  影响站点的访问速度还有1个重要因素,那就是下载速度。解决的办法就是压缩网页内容。对于纯文本内容而言,HTTP压缩技术可压缩至原大小的40%以下,从而提供60%以上的数据传输节约。虽然Web服务器会因为压缩导致CPU占用的略微上升,但可以节约大量用于传输的网络IO。
  根据IETF规范,大部分浏览器都支持使用gzip压缩算法进行内容压缩。也就是说,可以先用gzip压缩网页内容,然后发送到客户端浏览器,浏览器在接收的时候会自动解压数据,再显示页面。这个过程对用户来说,是完全透明的。同样,压缩Web页面的内容也有不同的方法。
  Mod_gzip是1种开放源代码的、标准的Apache模块,也叫互联网内容加速模块。可以将它和Apache一起编译,也可以作为DSO使用。相对于普通的浏览过程,它可以节省40%左右的流量。Mod_gzip不仅可以压缩静态的内容,如HTML、XML,而且对动态生成的,包括SQL、Java、 WML、VRML等产生的内容,在服务器端进行实时压缩并传输,其压缩效率惊人,一般都为60%~85%。
  压缩动态网页的内容,还可以使用class.gzip来对.php文件编码,class.gzip通过在PHP脚本的开头和结尾调用它的一些函数来压缩网页内容。如果整个站点都需要这样的压缩,可以在php.ini文件中的auto_prepend和auto_append中调用这些函数,但是会占用一定的系统开销。
  PHP4.0.4推出了1种新的输出缓冲的处理手段—ob_gzhandler,它的作用和class.gzip完全一样,区别是可以直接把它加到php.ini文件中,语法如下:
  output_handler = ob_gzhandler;
  这样将激活PHP的输出缓冲功能,并在发送内容前进行压缩。如果不想在这里设置,只在需要的地方才改变这个默认设置(不压缩),只要在需要压缩的PHP源程序目录中,修改一下.htaccess文件就行了,语法如下:
  php_value output_handler ob_gzhandler
  或者直接在PHP代码中调用它:
  ob_start(“ob_gzhandler”);
  输出缓冲的效果确实很理想,并且不会为服务器带来额外的系统开销。要注意的一点是Netscape Communicator不支持图像的压缩。因此除非知道访问者都使用Internet Explorer,否则必须禁止压缩jpeg和gif图象。
  4、其它技巧
  在编程时,使用一些小技巧也可以加快PHP的运行速度:
  (1)用i+=1代替i=i+1,既符合c/c++的习惯,效率相对还更高。
  (2)尽可能使用PHP内部函数。
  (3)能使用单引号字符串时,尽量使用单引号字符串。单引号字符串的效率要高于双引号字符串。
  (4)用foreach代替while遍历数组,foreach的效率明显高于while循环,而且不需要调用reset函数。
  让PHP更快的为用户提供文件下载
  一般来说,我们可以通过直接让URL指向一个位于Document Root下面的文件,来引导用户下载文件。
  但是,这样做,就没办法做一些统计,权限检查,等等的工作。于是,很多时候,我们采用让PHP来做转发,为用户提供文件下载。
  $file = “/tmp/dummy.tar.gz”;
  header(“Content-type: application/octet-stream”);header('Content-Disposition: attachment; filename=“' . basename($file) . '”');header(“Content-Length: “. filesize($file));readfile($file);
  但是这个有一个问题,就是如果文件是中文名的话,有的用户可能下载后的文件名是乱码。
  于是,我们做一下修改(参考: :
  $file = “/tmp/中文名.tar.gz”;
  $filename = basename($file);
  header(“Content-type: application/octet-stream”);//处理中文文件名
  $ua = $_SERVER[“HTTP_USER_AGENT”];
  $encoded_filename = urlencode($filename);$encoded_filename = str_replace(“+”, “%20”, $encoded_filename);if (preg_match(“/MSIE/”, $ua)) {
  header('Content-Disposition: attachment; filename=“' . $encoded_filename . '”');} else if (preg_match(“/Firefox/”, $ua)) {header(“Content-Disposition: attachment; filename*=”utf8''“ . $filename . '”');} else {
  header('Content-Disposition: attachment; filename=“' . $filename . '”');}
  header('Content-Disposition: attachment; filename=“' . $filename . '”');header(“Content-Length: “. filesize($file));readfile($file);
  输出的时候,如果是Apache + PHP mod,那么还需要发送到Apache的输出缓冲区。最后才发送给用户。而对于Nginx + fpm如果他们分开部署的话,那还会带来额外的网络IO。
  恩,现在看起来好多了,不过还有一个问题,那就是readfile,虽然PHP的readfile尝试实现的尽量高效,不占用PHP本身的内存,但是实际上它还是需要采用MMAP(如果支持),或者是一个固定的buffer去循环读取文件,直接输出。
  那么,能不能不经过PHP这层,直接让Webserver直接把文件发送给用户呢?
  今天,我看到了一个有意思的文章:How I PHP:X-SendFile。
  我们可以使用Apache的module mod_xsendfile,让Apache直接发送这个文件给用户:
  $file = “/tmp/中文名.tar.gz”;
  $filename = basename($file);
  header(“Content-type: application/octet-stream”);//处理中文文件名
  $ua = $_SERVER[“HTTP_USER_AGENT”];
  $encoded_filename = urlencode($filename);$encoded_filename = str_replace(“+”, “%20”, $encoded_filename);if (preg_match(“/MSIE/”, $ua)) {
  header('Content-Disposition: attachment; filename=“' . $encoded_filename . '”');} else if (preg_match(“/Firefox/”, $ua)) {header(“Content-Disposition: attachment; filename*=”utf8''“ . $filename . '”');} else {
  header('Content-Disposition: attachment; filename=“' . $filename . '”');}
  header('Content-Disposition: attachment; filename=“' . basename($file) . '”');//让Xsendfile发送文件
  header(“X-Sendfile: $file”);
  Lighttpd和Nginx也有类似的模块,大家有兴趣的可以去找找看。X-Sendfile头将被Apache处理,并且把响应的文件直接发送给Client。
  PHP捕捉错误并显示友好信息的方法
  捕捉错误,不能使用try{...}catch(){}的方式,PHP里面的try{...}catch是需要自己抛出异常才能捕获的,区别于其他语言。
  其次,可以使用如下的方法实现同样的效果:
  error_reporting(0);//设置屏蔽系统错误提示,放页首//$string = file_get_contents("index.html");//正常代码echo 5/0;//改:5/8 //正常代码
  //如果正常代码出错,则处理之:
  $arr=error_get_last();//获取刚发生的错误信息,并返回数组,无错返回null.
  if(isset($arr) ) //不为null,则表示出错了
  {
  echo "出错了,错误信息:";
  print_r($arr); //具体错误信息,可根据需要修改。
  exit;
  }
  【echo 5/8;】输出:
  0.625
  【echo 5/0;】输出:
  出错了,错误信息:
  Array (
  [type] => 2
  [message] => Division by zero
  [file] => D:wampwwwsinaeditornewfile.php
  [line] => 13
  )
 

上一篇:PHP开发者常犯的10个MySQL错误

下一篇:11种php编程典型安全隐患及处理