PHP 性能優(yōu)化

PHP 性能優(yōu)化在中大型項(xiàng)目當(dāng)中是非常重要的一件事情。

PHP 性能優(yōu)化分為代碼級(jí)和配置級(jí)兩個(gè)部分异赫。

一、PHP 代碼級(jí)優(yōu)化建議

1)用單引號(hào)代替雙引號(hào)

因?yàn)?PHP 會(huì)在雙引號(hào)包含的字符串中搜索變量市袖,單引號(hào)不會(huì)洋腮。在單引號(hào)當(dāng)中,PHP 不會(huì)自動(dòng)搜索變量讼育、轉(zhuǎn)義字符等帐姻。因此效率上快很多。特別是在一些大內(nèi)容的字符串的情景下奶段,單引號(hào)性能更優(yōu)異饥瓷。

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

在一些舊版不嚴(yán)格的 PHP 當(dāng)中痹籍,$row['id'] 寫成 $row[id] 也是能正確解析的呢铆。新版這樣會(huì)提示 notice 錯(cuò)誤。

3)使用 for 對(duì)數(shù)組循環(huán)之前確定數(shù)組元素的長(zhǎng)度

雖然像 count蹲缠、strlen 這樣的操作時(shí)間復(fù)雜度是O(1)棺克,不會(huì)有太大的性能消耗。當(dāng)然避免每次都循環(huán)計(jì)算是一個(gè)良好的習(xí)慣线定。

4)unset 那些不用的變量及大數(shù)組娜谊。

大小項(xiàng)目當(dāng)中性能可能并不明顯。但是在大項(xiàng)目且并發(fā)量高的時(shí)候斤讥,變量占用的內(nèi)存如果不及時(shí)注銷回收纱皆,會(huì)導(dǎo)致內(nèi)存負(fù)載很高。

5)盡量使用偽函數(shù)(語言結(jié)構(gòu) )

常用的語言結(jié)構(gòu)有 echo周偎、isset抹剩、unset 等。它們比函數(shù)性能要高很多蓉坎。常見的 isset 替換掉 array_key_exists澳眷。如何判斷一個(gè)方法是語言結(jié)構(gòu)還是普通方法?

方式一:

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

方式二:

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

6)類靜態(tài)方法比普通類成員方法性能好蛉艾。

這個(gè)性能差異在舊版表現(xiàn)明顯钳踊,在 PHP 5.6+ 之后,這個(gè)差異并不是很明顯了勿侯。當(dāng)然拓瞪,靜態(tài)方法在調(diào)用的時(shí)候更易操作。

7)盡量避免使用魔術(shù)方法助琐。

通過對(duì)魔術(shù)方法測(cè)試魔術(shù)方法比普通的方法性能在壓力很高的環(huán)境下相差成倍呈現(xiàn)祭埂。

8)加載文件時(shí)盡量使用絕對(duì)路徑。

PHP 加載相對(duì)路徑會(huì)從可能的庫位置進(jìn)行嘗試加載∏穑可能的庫位置由 php.ini 配置文件當(dāng)中的 include_path 配置決定舌界。這里的路徑配置越多,那么相對(duì)路徑的加載就會(huì)越慢泰演。

9)函數(shù)代替正則表達(dá)式完成相同的功能呻拌。

與之相關(guān)的功能有:strtok、strstr睦焕、strpos藐握、str_replace、substr垃喊、explode猾普、implode。

10)盡量避免使用 @ 屏蔽錯(cuò)誤消息的做法缔御。

我們應(yīng)該使用使用 error_reporting(0) 關(guān)閉錯(cuò)誤抬闷,使用使用 error_log 把錯(cuò)誤寫入日志文件妇蛀。

11)盡量避免程序拋出 notice 錯(cuò)誤消息耕突。

錯(cuò)誤消息對(duì)性能影響很大。即使通過 error_reporting(0) 關(guān)閉了也不行评架。所以眷茁,我們要盡量避免錯(cuò)誤的產(chǎn)生。

12)能用 PHP 內(nèi)置方法解決就不要自己用代碼實(shí)現(xiàn)

內(nèi)置方法比自定義方法速度快纵诞。在自己實(shí)現(xiàn)之前上祈,請(qǐng)檢查 PHP 內(nèi)置方法已經(jīng)提供。

13)用盡量少的代碼實(shí)現(xiàn)功能浙芙。

很明顯登刺,代碼越長(zhǎng)不僅不易維護(hù),而且 PHP 詞法解析器與語法語法解析器會(huì)用更多的時(shí)間去翻譯嗡呼,挺累的纸俭。

14)自增/自減局部變量比全局變量快。

本身從變量所處內(nèi)存位置亦可知局部變量比全局變量要快南窗。

15)派生類中的方法運(yùn)行起來要快于在基類中定義的同樣方法揍很。

從 PHP 原理來說,首先從當(dāng)前類查找該方法万伤,找不到再找父類窒悔。假如此時(shí)當(dāng)前類是一個(gè)多級(jí)的子孫類。那么敌买,就會(huì)導(dǎo)致向上查找简珠。從而性能會(huì)下降。

16)并非要用類實(shí)現(xiàn)所有的數(shù)據(jù)結(jié)構(gòu)虹钮,數(shù)組也很有用聋庵。

類比對(duì)象會(huì)消耗更多的內(nèi)存荐操。很多人在 PHP 開發(fā)過程中會(huì)過度的像 Java 這種語言一樣面向?qū)ο蟆0岩恍?fù)雜參數(shù)的傳遞封裝成一個(gè)對(duì)象珍策。其實(shí)大多數(shù)情況下沒有必要托启。直接傳數(shù)據(jù)就很好。性能表現(xiàn)也非常好攘宙。

17)盡量少的進(jìn)行文件操作屯耸。

在任何語言下,對(duì)文件的操作都會(huì)對(duì)性能產(chǎn)生影響蹭劈。操作的文件越多性能越差疗绣。畢竟,最終性能都會(huì)反應(yīng)在系統(tǒng) IO 上铺韧。

18)盡量使用 file_get_contents/file_put_contents 代替 fopen/fget 等相關(guān)的文件讀寫函數(shù)多矮。除非需要對(duì)文件更精細(xì)的操作。

19)盡量少的對(duì)數(shù)據(jù)庫進(jìn)行 INSERT/UPDATE/DELETE 操作哈打。

眾所周知塔逃,INSERT/UPDATE/DELETE 對(duì)數(shù)據(jù)庫造成 IO 壓力。操作越頻繁料仗,壓力越大湾盗。通常在一個(gè)項(xiàng)目中 20% 是寫入操作,80% 是讀操作立轧。這就是所謂的二八原則格粪。

20)對(duì)函數(shù)/方法內(nèi) global 的變量,應(yīng)該用完就 unset 掉氛改。

global 的變量帐萎,unset 的時(shí)候只會(huì)在當(dāng)前函數(shù)或方法內(nèi)部被清除掉。并不會(huì)把全局的變量給清除胜卤。

21)能用緩存的地方盡量使用緩存疆导。

眾所周知,緩存可以幫助我們擋掉一部分調(diào)用數(shù)據(jù)庫以及邏輯運(yùn)算部分的工作瑰艘。所以是鬼,性能肯定是快快的。

22)"用 i+=1代替 i=i+1紫新。符合 c/c++ 的習(xí)慣均蜜,效率還高 "。

23)多維數(shù)組盡量不要循環(huán)嵌套賦值芒率。

翻譯過來就是不要在循環(huán)過程中動(dòng)態(tài)在數(shù)據(jù)內(nèi)部創(chuàng)建一個(gè)元素囤耳。然后,再次循環(huán)在的時(shí)候在這個(gè)元素內(nèi)部再動(dòng)態(tài)創(chuàng)建一個(gè)元素。

24)如不是特殊需要充择,參數(shù)傳遞都建議使用傳值而不是傳引用德玫。當(dāng)然,如果參數(shù)是很大的數(shù)組且需要修改時(shí)可以考慮引用傳遞椎麦。

二宰僧、PHP 配置級(jí)優(yōu)化建議

  1. 禁用高風(fēng)險(xiǎn) PHP 函數(shù)

disable_functions = 該選項(xiàng)可以設(shè)置哪些 PHP 函數(shù)是禁止使用的。PHP 中有一些函數(shù)的風(fēng)險(xiǎn)性還是相當(dāng)大的观挎,可以直接執(zhí)行一些系統(tǒng)級(jí)腳本命令琴儿。如果允許這些函數(shù)執(zhí)行,當(dāng) PHP 程序出現(xiàn)漏洞時(shí)嘁捷,損失是非常嚴(yán)重的造成!以下我們給出推薦的禁用函數(shù)設(shè)置:

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

需注意:如果您的服務(wù)器中含有一些系統(tǒng)狀態(tài)檢測(cè)的 PHP 程序,則不要禁用shell_exec,proc_open,proc_get_status 等函數(shù)雄嚣。

  1. 優(yōu)化 PHP 腳本執(zhí)行時(shí)間

max_execution_time = 30

該選項(xiàng)設(shè)定 PHP 程序的最大執(zhí)行時(shí)間晒屎,如果一個(gè) PHP 腳本被請(qǐng)求,且該 PHP 腳本在 max_execution_time 時(shí)間內(nèi)沒能執(zhí)行完畢缓升,則 PHP 不再繼續(xù)執(zhí)行鼓鲁,直接給客戶端返回超時(shí)錯(cuò)誤。沒有特殊需要該選項(xiàng)可保持默認(rèn)設(shè)置 30秒仔沿。如果您的 PHP 腳本確實(shí)需要長(zhǎng)執(zhí)行時(shí)間則可以適當(dāng)增大該時(shí)間設(shè)置坐桩。

  1. 優(yōu)化 PHP 腳本處理內(nèi)存占用

memory_limit = 8M

該選項(xiàng)指定 PHP 腳本處理所能占用的最大內(nèi)存,默認(rèn)為 8MB封锉,如果您的服務(wù)器內(nèi)存為 1GB 以上,則該選項(xiàng)可以設(shè)置為 12MB 以獲得更快的 PHP 腳本處理效率膘螟。

如果此值設(shè)置過小成福,那么一些大型的耗時(shí)的框架,比如像 Laravel/wordpress 就會(huì)導(dǎo)致報(bào) "Fatal Error: Allowed memory size of xxxxxx bytes exhausted " 的錯(cuò)誤荆残。

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

upload_max_filesize = 2M

該選項(xiàng)設(shè)定PHP所能允許最大上傳文件大小奴艾,默認(rèn)為 2MB。根據(jù)實(shí)際應(yīng)用需求内斯,可以適當(dāng)增大該設(shè)置蕴潦。一定要謹(jǐn)防此值設(shè)置過大,導(dǎo)致遭遇大文件上傳把服務(wù)器資源吃盡導(dǎo)致服務(wù)器癱瘓俘闯。

比如潭苞,我們?cè)O(shè)置此值允許最大上傳 1GB。一個(gè)普通用戶上傳一個(gè) 1GB 的文件需要 30 分鐘真朗。那么假如一個(gè)惡意用戶模擬 1000 個(gè)正常用戶上傳文件此疹。那么此時(shí)服務(wù)器同一時(shí)刻會(huì)面臨 1000 上傳與服務(wù)器對(duì)接。造成服務(wù)器 30 分鐘內(nèi)不能響應(yīng)其他正常請(qǐng)求。導(dǎo)致服務(wù)器陷入癱瘓之境蝗碎。

  1. Session存儲(chǔ)介質(zhì)

session.save_path

在小應(yīng)用當(dāng)中湖笨,通常 session 都存儲(chǔ)到服務(wù)器文件當(dāng)中。就是由此選項(xiàng)決定蹦骑。如果你用的是一些 PHP 框架慈省。那么,可能此值會(huì)在框架當(dāng)中被修改眠菇。

一般大型應(yīng)用會(huì)將 session 寫入到類似如 Redis 這樣的緩存當(dāng)中辫呻。以此降低 session 寫入/刪除時(shí)對(duì)服務(wù)器性能造成 IO 壓力。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末琼锋,一起剝皮案震驚了整個(gè)濱河市放闺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缕坎,老刑警劉巖怖侦,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谜叹,居然都是意外死亡匾寝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門荷腊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艳悔,“玉大人,你說我怎么就攤上這事女仰〔履辏” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵疾忍,是天一觀的道長(zhǎng)乔外。 經(jīng)常有香客問我,道長(zhǎng)一罩,這世上最難降的妖魔是什么杨幼? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮聂渊,結(jié)果婚禮上差购,老公的妹妹穿的比我還像新娘。我一直安慰自己汉嗽,他們只是感情好欲逃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诊胞,像睡著了一般暖夭。 火紅的嫁衣襯著肌膚如雪锹杈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天迈着,我揣著相機(jī)與錄音竭望,去河邊找鬼。 笑死裕菠,一個(gè)胖子當(dāng)著我的面吹牛咬清,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奴潘,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼旧烧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了画髓?” 一聲冷哼從身側(cè)響起掘剪,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奈虾,沒想到半個(gè)月后夺谁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肉微,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年匾鸥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉纳。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勿负,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出劳曹,到底是詐尸還是另有隱情奴愉,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布厚者,位于F島的核電站躁劣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏库菲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一志膀、第九天 我趴在偏房一處隱蔽的房頂上張望熙宇。 院中可真熱鬧,春花似錦溉浙、人聲如沸烫止。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馆蠕。三九已至期升,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間互躬,已是汗流浹背播赁。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吼渡,地道東北人容为。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像寺酪,于是被迫代替她去往敵國和親坎背。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 1寄雀、用單引號(hào)代替雙引號(hào)來包含字符串得滤,這樣做會(huì)更快一些。因?yàn)镻HP會(huì)在雙引號(hào)包圍的字符串中搜尋變量盒犹,單引號(hào)則不會(huì)懂更,注...
    紅魚綠魚與驢閱讀 1,066評(píng)論 0 3
  • 總體介紹: 一、規(guī)范說明 性能是網(wǎng)站運(yùn)行是否良好的關(guān)鍵因素阿趁, 網(wǎng)站的性能與效率影響著公司的運(yùn)營(yíng)成本及長(zhǎng)遠(yuǎn)發(fā)展膜蛔,編寫...
    henryspace閱讀 866評(píng)論 0 0
  • 1、如果能將類的方法定義成static脖阵,就盡量定義成static皂股,它的速度會(huì)提升將近4倍。 2命黔、$row['id'...
    紅魚綠魚與驢閱讀 178評(píng)論 0 0
  • PHP雖然是世界上最好的語言呜呐,但是它本身作為一門腳本語言,其運(yùn)行效率一直被人們所詬病悍募。 作為以PHP為開發(fā)語言的應(yīng)...
    guanguans閱讀 612評(píng)論 1 9
  • 聽課筆記(上): 馬靜蘑辑,大數(shù)據(jù)時(shí)代的前瞻思維及管理變革,南航經(jīng)管學(xué)院坠宴。 自己也是民主黨派洋魂。重要話題,前瞻話題喜鼓。因?yàn)?..
    鏤月芙閱讀 357評(píng)論 0 0