简单说说PHP优化那些事(经验分享)


Posted in PHP onNovember 27, 2014

我们在编写程序时,总是想要使自己的程序占用资源最小,运行速度更快,代码量更少。往往我们在追求这些的同时却失去了很多东西。下面我想讲讲我对PHP优化的理解。优化的目的是花最少的代价换来最快的运行速度与最容易维护的代码。

进行大范围的优化,而不是死啃某些程序代码

我这里所说的优化,基本上都是从服务器,Apache,数据库这些方面来进行的优化,而并不是对你的PHP代码加以改进从而提高程序的运行速度,因为比起你将程序中的正则优化为字符串处理函数从而提升程序速度来说,在大范围内进行的优化所需要的代价要比这个小的多,而获得报酬却要丰厚的多。

在非代码处进行优化有以下好处:

1、通常情况下能够大大提高效率

2、不会危及到代码的完整性

3、能够快速部署

缓存技术

下面来说说常用的缓存技术,通过这些缓存技术能够大大的提高效率

在说到缓存技术的时候不得不提到memcached ,memcached是高效、快速的分布式内存对象缓存系统,主要用于加速 WEB 动态应用程序。

Memcached的原理

memcached 是以守护程序方式运行于一个或多个服务器中,等待接收客户端的连接操作,客户端可以由各种语言编写(例如PHP)。PHP 等客户端在与 memcached 服务建立连接之后,接下来的事情就是存取对象了,每个被存取的对象都有一个唯一的标识符 key,存取操作均通过这个 key 进行,保存到 memcached 中的对象实际上是放置内存中的,并不是保存在 cache 文件中的,这也是为什么 memcached 能够如此高效快速的原因。

说完memcached,下面来说说常用的缓存方法

1、编译与OPCODE缓存

因为PHP是解释型的语言,所以每个PHP文件在运行的时候都需要编译后再执行,同一个文件,不同的用户访问,或者同一个用户不同时间访问同一个文件,每次都需要重新编译然后运行,这样就耗费了大量时间。

通过编译缓存每个文件在修改之后只编译一次这样就减少了文件IO操作,用户访问后机器指令直接从内存中取出并执行而不是硬盘中读出。

最常见的PHP编译缓存工具有:APC,Accelerator,xcache

2、全局页面缓存? Squid Cache

Squid Cache(简称为Squid)是一个流行的自由软件(GNU通用公共许可证)的代理服务器和Web缓存服务器,Squid作为网页服务器的前置cache服务器通过缓存相关请求来提高Web服务器的速度。

3、局部缓存之SQL缓存

在大多数应用程序中主要的瓶颈往往可以追溯到数据库的操作中,一般都是因为复杂的数据库查询而耗费了大量时间,而SQL缓存可以大大降低复杂查询造成的负荷。

SQL缓存的例子(使用了memcached扩展)

代码片段:

$key = md5(“some sort of sql query”);
if (!($result = memcache_get($key))) {
$result = $pdo->query($qry)->fetchAll();
// 缓存查询结果一小时
memcache_set($key, $result, NULL, 3600);
}

4、局部缓存之代码块缓存

为了优化PHP程序,有时候我们不得不优化一个个代码段来减少那么一点点的执行的时间,但是比起优化复杂的不同的PHP代码段还不如通过缓存来直接忽略这些代码段的优化,这样做的好处是:

1、能够很快的看到效果

2、不会破坏以前的代码

3、速度要比优化代码要快得多

代码块缓存的列子(同样使用了memcached扩展)

function complex_function_abc($a, $b, $c) {
$key = __FUNCTION__ . serialize
(func_get_args());
if (!($result = memcache_get($key))) {
$result = //函数代码
// 储存执行结果1小时
memcache_set($key, $result, NULL, 3600);
}
return $result;
}

当然除了上述方法外还可以用到文件缓存(将数据库中的数据取出储存在文件中),还可以生成静态HTML文件等,但是这些方法的缓存还是将文件储存在硬盘上而不是内存中。

输出控制

除了上述缓存技术外还可以通过输出控制来让程序执行的时间更少

下面通过PHP与APACHE来说说输出控制

1、PHP输出控制

这里最主要用到ob_start()以及PHP中的OB系列函数,这些函数可以做什么呢?

第一就是静态模版技术。所谓静态模版技术就是通过某种方式,使得用户在client端得到的是由PHP产生的html页面。如果这个html页面不会再被更新,那么当另外的用户再次浏览此页面时,程序将不会再调用PHP以及相关的数据库,对于某些信息量比较大的网站,例如sina,163,sohu。类似这种的技术带来的好处是非常巨大的。

代码示例:

代码示例:

<?php

ob_start(); //打开缓冲区

?>

php页面的全部输出

<?php

$content = ob_get_contents(); //取得php页面输出的全部内容

$fp = fopen(“output.html”, “w”); //创建一个文件,并打开,准备写入

fwrite($fp, $content); //把php页面的内容全部写入output.html,然后……

fclose($fp);

?>

当然这个ob系列函数还有其他很多用处我就不在这里一一说明了。

2、apache输出控制

将SendBufferSize设置为页面大小,这样就能将页面一次性放在发送缓冲区从而增加处理速度。

SendBufferSize 指令

说明:TCP发送缓冲区大小(字节)

语法:SendBufferSize bytes

默认值:SendBufferSize 0

作用域:server config

状态:MPM

模块:beos, mpm_netware, mpm_winnt, mpmt_os2, prefork, worker

这个指令设置服务器的TCP发送缓冲区的大小(字节)。提高这个值会导致两个后果:高速度和高潜伏时间(100ms左右)。如果设置为”0″,将使用操作系统默认值。

通过源代码方式编译你的Apache/PHP/Database 可让你的程序增加10?15%的速度

下面再说说在代码优化的时候应该注意的

1、短代码不等于快的代码

很多人在写程序时希望将代码写的越简洁越好,但是越短的代码有时候反而需要更长的执行时间,所以哪怕是用更多的代码也不使用速度慢的代码

2、在写程序的时候更应该注重程序的扩展性,而不是追求速度

3、在优化你的代码之前,先看看跟数据库有关的部分,因为大多数应用程序的瓶颈在数据库而不是代码

4、微优化得不偿失

什么叫做微优化?就像前面所说的将正则表达式部分的代码改用字符串函数代替。这样做有以下缺点:

(1)花费时间较长

(2)不会解决你的性能问题

(3)很有可能会破坏以前的代码从而产生未知的错误

(4)付出大于回报

这里还不得不提到一个误区,有些人为了让程序更加优化,在分析业务逻辑的时候便将优化考虑在内了,从而为了得到更优的代码而改动业务逻辑。这是十分愚蠢的想法,因为程序的目的便是为了处理现实中遇到的问题,是为这些问题服务的,怎么能本末倒置呢。

PHP 相关文章推荐
apache rewrite_module模块使用教程
Jan 10 PHP
也谈php网站在线人数统计
Apr 09 PHP
php增删改查示例自己写的demo
Sep 04 PHP
PHP弹出提示框并跳转到新页面即重定向到新页面
Jan 24 PHP
php中in_array函数用法探究
Nov 25 PHP
PHP SESSION的增加、删除、修改、查看操作
Mar 20 PHP
配置Nginx+PHP的正确思路与过程
May 10 PHP
基于php(Thinkphp)+jquery 实现ajax多选反选不选删除数据功能
Feb 24 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
Apr 19 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
Dec 21 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
Jul 26 PHP
php 使用 __call实现重载功能示例
Nov 18 PHP
几个实用的PHP内置函数使用指南
Nov 27 #PHP
简单谈谈php中ob_flush和flush的区别
Nov 27 #PHP
浅谈php优化需要注意的地方
Nov 27 #PHP
PHP实现文件下载详解
Nov 27 #PHP
thinkphp的URL路由规则与配置实例
Nov 26 #PHP
thinkphp文件引用与分支结构用法实例
Nov 26 #PHP
PHP获取当前所在目录位置的方法
Nov 26 #PHP
You might like
PHP 中文处理技巧
2010/04/25 PHP
PHP开发需要注意的安全问题
2010/09/01 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
PHP实现QQ空间自动回复说说的方法
2015/12/02 PHP
浅谈PHP链表数据结构(单链表)
2016/06/08 PHP
PHP验证码无法显示的原因及解决办法
2017/08/11 PHP
JavaScript 中的事件教程
2007/04/05 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
jcrop基本参数一览
2013/07/16 Javascript
jQuery中ajax的get()方法用法实例
2014/12/26 Javascript
jquery.mobile 共同布局遇到的问题小结
2015/02/10 Javascript
JQuery复制DOM节点的方法
2015/06/11 Javascript
JQuery.validate在ie8下不支持的快速解决方法
2016/05/18 Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
2017/02/13 Javascript
在 Angular 中使用Chart.js 和 ng2-charts的示例代码
2017/08/17 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
JavaScript解析及序列化JSON的方法实例分析
2019/01/04 Javascript
解决layui的form里的元素进行动态生成,验证失效的问题
2019/09/14 Javascript
Node.js中出现未捕获异常的处理方法
2020/06/29 Javascript
[55:26]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第一场 2月23日
2021/03/11 DOTA
Python去除字符串两端空格的方法
2015/05/21 Python
Python异常处理知识点总结
2019/02/18 Python
centos 安装Python3 及对应的pip教程详解
2019/06/28 Python
Python字符串、列表、元组、字典、集合的补充实例详解
2019/12/20 Python
Python获取对象属性的几种方式小结
2020/03/12 Python
python使用pymongo与MongoDB基本交互操作示例
2020/04/09 Python
完美解决python针对hdfs上传和下载的问题
2020/06/05 Python
Python偏函数实现原理及应用
2020/11/20 Python
英国领先的在线药房:Pharmacy First
2017/09/10 全球购物
adidas泰国官网:adidas TH
2020/07/11 全球购物
瑞士首家网上药店折扣店:McDrogerie
2020/12/22 全球购物
开平碉楼导游词
2015/02/06 职场文书
辞职申请书范本
2019/05/20 职场文书
少年的你:世界上没有如果,要在第一次就勇敢的反抗
2019/11/20 职场文书
新手入门Jvm-- JVM对象创建与内存分配机制
2021/06/18 Java/Android
mysql查询结果实现多列拼接查询
2022/04/03 MySQL