PHP 性能优化

PHP 性能优化在中大型项目当中是非常重要的一件事情。

PHP 性能优化分为代码级和配置级两个部分。

一、PHP 代码级优化建议

1)用单引号代替双引号

因为 PHP 会在双引号包含的字符串中搜索变量,单引号不会。在单引号当中,PHP 不会自动搜索变量、转义字符等。因此效率上快很多。特别是在一些大内容的字符串的情景下,单引号性能更优异。

2)$row['id'] 的速度是 $row[id] 的 7 倍。

在一些旧版不严格的 PHP 当中,$row['id'] 写成 $row[id] 也是能正确解析的。新版这样会提示 notice 错误。

3)使用 for 对数组循环之前确定数组元素的长度

虽然像 count、strlen 这样的操作时间复杂度是O(1),不会有太大的性能消耗。当然避免每次都循环计算是一个良好的习惯。

4)unset 那些不用的变量及大数组。

大小项目当中性能可能并不明显。但是在大项目且并发量高的时候,变量占用的内存如果不及时注销回收,会导致内存负载很高。

5)尽量使用伪函数(语言结构 )

常用的语言结构有 echo、isset、unset 等。它们比函数性能要高很多。常见的 isset 替换掉 array_key_exists。如何判断一个方法是语言结构还是普通方法?

方式一:

<?php
var_dump(function_exists('echo'));

方式二:

// 在 PHP 命令行操作
$ php --rf echo

6)类静态方法比普通类成员方法性能好。

这个性能差异在旧版表现明显,在 PHP 5.6+ 之后,这个差异并不是很明显了。当然,静态方法在调用的时候更易操作。

7)尽量避免使用魔术方法。

通过对魔术方法测试魔术方法比普通的方法性能在压力很高的环境下相差成倍呈现。

8)加载文件时尽量使用绝对路径。

PHP 加载相对路径会从可能的库位置进行尝试加载。可能的库位置由 php.ini 配置文件当中的 include_path 配置决定。这里的路径配置越多,那么相对路径的加载就会越慢。

9)函数代替正则表达式完成相同的功能。

与之相关的功能有:strtok、strstr、strpos、str_replace、substr、explode、implode。

10)尽量避免使用 @ 屏蔽错误消息的做法。

我们应该使用使用 error_reporting(0) 关闭错误,使用使用 error_log 把错误写入日志文件。

11)尽量避免程序抛出 notice 错误消息。

错误消息对性能影响很大。即使通过 error_reporting(0) 关闭了也不行。所以,我们要尽量避免错误的产生。

12)能用 PHP 内置方法解决就不要自己用代码实现

内置方法比自定义方法速度快。在自己实现之前,请检查 PHP 内置方法已经提供。

13)用尽量少的代码实现功能。

很明显,代码越长不仅不易维护,而且 PHP 词法解析器与语法语法解析器会用更多的时间去翻译,挺累的。

14)自增/自减局部变量比全局变量快。

本身从变量所处内存位置亦可知局部变量比全局变量要快。

15)派生类中的方法运行起来要快于在基类中定义的同样方法。

从 PHP 原理来说,首先从当前类查找该方法,找不到再找父类。假如此时当前类是一个多级的子孙类。那么,就会导致向上查找。从而性能会下降。

16)并非要用类实现所有的数据结构,数组也很有用。

类比对象会消耗更多的内存。很多人在 PHP 开发过程中会过度的像 Java 这种语言一样面向对象。把一些复杂参数的传递封装成一个对象。其实大多数情况下没有必要。直接传数据就很好。性能表现也非常好。

17)尽量少的进行文件操作。

在任何语言下,对文件的操作都会对性能产生影响。操作的文件越多性能越差。毕竟,最终性能都会反应在系统 IO 上。

18)尽量使用 file_get_contents/file_put_contents 代替 fopen/fget 等相关的文件读写函数。除非需要对文件更精细的操作。

19)尽量少的对数据库进行 INSERT/UPDATE/DELETE 操作。

众所周知,INSERT/UPDATE/DELETE 对数据库造成 IO 压力。操作越频繁,压力越大。通常在一个项目中 20% 是写入操作,80% 是读操作。这就是所谓的二八原则。

20)对函数/方法内 global 的变量,应该用完就 unset 掉。

global 的变量,unset 的时候只会在当前函数或方法内部被清除掉。并不会把全局的变量给清除。

21)能用缓存的地方尽量使用缓存。

众所周知,缓存可以帮助我们挡掉一部分调用数据库以及逻辑运算部分的工作。所以,性能肯定是快快的。

22)"用 i+=1代替 i=i+1。符合 c/c++ 的习惯,效率还高 "。

23)多维数组尽量不要循环嵌套赋值。

翻译过来就是不要在循环过程中动态在数据内部创建一个元素。然后,再次循环在的时候在这个元素内部再动态创建一个元素。

24)如不是特殊需要,参数传递都建议使用传值而不是传引用。当然,如果参数是很大的数组且需要修改时可以考虑引用传递。

二、PHP 配置级优化建议

  1. 禁用高风险 PHP 函数

disable_functions = 该选项可以设置哪些 PHP 函数是禁止使用的。PHP 中有一些函数的风险性还是相当大的,可以直接执行一些系统级脚本命令。如果允许这些函数执行,当 PHP 程序出现漏洞时,损失是非常严重的!以下我们给出推荐的禁用函数设置:

disable_functions = phpinfo,passthru,exec,system,popen,chroot,escapeshellcmd,escapeshellarg,shell_exec,proc_open,proc_get_status

需注意:如果您的服务器中含有一些系统状态检测的 PHP 程序,则不要禁用shell_exec,proc_open,proc_get_status 等函数。

  1. 优化 PHP 脚本执行时间

max_execution_time = 30

该选项设定 PHP 程序的最大执行时间,如果一个 PHP 脚本被请求,且该 PHP 脚本在 max_execution_time 时间内没能执行完毕,则 PHP 不再继续执行,直接给客户端返回超时错误。没有特殊需要该选项可保持默认设置 30秒。如果您的 PHP 脚本确实需要长执行时间则可以适当增大该时间设置。

  1. 优化 PHP 脚本处理内存占用

memory_limit = 8M

该选项指定 PHP 脚本处理所能占用的最大内存,默认为 8MB,如果您的服务器内存为 1GB 以上,则该选项可以设置为 12MB 以获得更快的 PHP 脚本处理效率。

如果此值设置过小,那么一些大型的耗时的框架,比如像 Laravel/wordpress 就会导致报 "Fatal Error: Allowed memory size of xxxxxx bytes exhausted " 的错误。

  1. PHP上传文件大小限制:

upload_max_filesize = 2M

该选项设定PHP所能允许最大上传文件大小,默认为 2MB。根据实际应用需求,可以适当增大该设置。一定要谨防此值设置过大,导致遭遇大文件上传把服务器资源吃尽导致服务器瘫痪。

比如,我们设置此值允许最大上传 1GB。一个普通用户上传一个 1GB 的文件需要 30 分钟。那么假如一个恶意用户模拟 1000 个正常用户上传文件。那么此时服务器同一时刻会面临 1000 上传与服务器对接。造成服务器 30 分钟内不能响应其他正常请求。导致服务器陷入瘫痪之境。

  1. Session存储介质

session.save_path

在小应用当中,通常 session 都存储到服务器文件当中。就是由此选项决定。如果你用的是一些 PHP 框架。那么,可能此值会在框架当中被修改。

一般大型应用会将 session 写入到类似如 Redis 这样的缓存当中。以此降低 session 写入/删除时对服务器性能造成 IO 压力。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 1、用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注...
    红鱼绿鱼与驴阅读 1,063评论 0 3
  • 总体介绍: 一、规范说明 性能是网站运行是否良好的关键因素, 网站的性能与效率影响着公司的运营成本及长远发展,编写...
    henryspace阅读 861评论 0 0
  • 1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。 2、$row['id'...
    红鱼绿鱼与驴阅读 178评论 0 0
  • PHP虽然是世界上最好的语言,但是它本身作为一门脚本语言,其运行效率一直被人们所诟病。 作为以PHP为开发语言的应...
    guanguans阅读 605评论 1 9
  • 听课笔记(上): 马静,大数据时代的前瞻思维及管理变革,南航经管学院。 自己也是民主党派。重要话题,前瞻话题。因为...
    镂月芙阅读 356评论 0 0