技術文章
50個小技巧來提高PHP執行效率
發布日期:2019-07-29 閱讀次數:1 字體大小:

在项目开发过程中,经常遇到了一些PHP处理程序性能底下的情况,虽然有很多原因如:服務器本身配置,运行环境nginx服務,php-fpm配置等等,更多有一点仍然是PHPer没有对程序进行更好的优化。

第一類、變量類型:

1)主要是使用未定義變量,而直接使用變量,做程序開發結束的時候,程序員都喜歡關閉debug,讓一切Notice和Warning都影藏起來,但實質上php即使關閉debug也會記錄日志,將所有的Notice和Warning信息全部寫入日志文件中,無非是一件浪費性能的事,很多phper都有這個小習慣,包括我也一樣。

2)另外在程序中應盡量注意變量的使用,如字符串最好使用單引號,而不是雙引號,畢竟雙引號還得PHP解析爲單引號在執行。

3)說到這裏數組中的鍵值索引一樣也需要用單引號,不要不寫引號這樣的程序執行效率極低。

第二類、函數類型:

1)SESSION變量,大家都知道調用SESSION這個全局變量,往往大家在將值放入SESSION之後,直接就往下接著寫自己的代碼了,卻忘記了SESSION變量會在頁面執行完畢之後才會將值放入SESSION中供其他頁面使用,這樣如果這個頁面執行時間過長,其他頁面也調用這個SESSION就會等待這個寫入SESSION的頁面執行完畢之後,再往後執行其他程序,但是我們的程序要的不是這樣的效果,因爲我們只需要將值寫入SESSION執行之後,就已經放在SESSION中了,而不是等待頁面執行完畢,從PHP官網也能看到這個SESSION變量確實有這個問題,因此我們需要在寫入SESSION之後關閉寫入SESSION操作,加上session_write_close()函數則可以減少等待頁面加載完畢的這些無用時間。
2)file_get_contents()函數,這個函數意思是獲取遠程URL的頁面內容,但雖然這樣寫著,很多人都不會注意這樣一個問題”超時”,如果獲取不到頁面內容,程序將一直卡在這裏,很多人會聯系到設置頁面超時或者在php.ini文件中去設置max_execution_time最大執行超時時間,但如果使用的是php-fpm(也就是php-cgi)將對這個參數視爲無效,而需要在php-fpm配置文件中設置最大執行超時時間,最終這樣也無法起到作用,需要解決這個問題,仍然需要我們在至調用該函數的時候加上超時時間,這樣才能從根本上解決問題。

第三類、引用文件類型:

引用文件很多时间我们都习惯性的使用include ,但是这中间也隐含着一些使用技巧,如果经常使用框架开发程序的人就很熟悉,项目项目下面会有”include”字样类型的文件夹,程序在查找包含文件的顺序先是在当前工作目录根路径下include字样文件夹中下查找,然后再是当前该文件所在目录相对的include字样文件夹中查找。也就是这个include使用不当,程序将会按照这个方式在根路径下面依次查找,这样同样是一件很费解的事,所以大家应尽量将使用的文件写在最容易查找的位置,这样才有利于程序的执行效率。此外还有像echo输出多个字符串或变量的函数,使用”.”连接效率要比”,”连接执行效率低。

更詳細具體的總結如下:

1、用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的”函数”(译注:PHP手册中说echo是语言结构,不是真正的函数,故 把函数加上了双引号)。

2、如果能將類的方法定義成static,就盡量定義成static,它的速度會提升將近4倍。

3、$row[‘id’] 的速度是$row[id]的7倍。

4、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2。

5、在執行for循環之前確定最大循環數,不要每循環一次都計算最大值,最好運用foreach代替。

6、注銷那些不用的變量尤其是大數組,以便釋放內存。

7、盡量避免使用__get,__set,__autoload。

8、require_once()代價昂貴。

9、include文件時盡量使用絕對路徑,因爲它避免了PHP去include_path裏查找文件的速度,解析操作系統路徑所需的時間會更少。

10、如果你想知道脚本开始执行(译注:即服務器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。

11、函數代替正則表達式完成相同功能。

12、str_replace函數比preg_replace函數快,但strtr函數的效率是str_replace函數的四倍。

13、如果一個字符串替換函數,可接受數組或字符作爲參數,並且參數長度不太長,那麽可以考慮額外寫一段替換代碼,使得每次傳遞參數是一個字符,而不是只寫一行代碼接受數組作爲查詢和替換的參數。

14、使用选择分支语句(译注:即switch case)好于使用多个if,else if语句。

15、用@屏蔽錯誤消息的做法非常低效,極其低效。

16、打開apache的mod_deflate模塊,可以提高網頁的浏覽速度。

17、數據庫連接當使用完畢時應關掉,不要用長連接。

18、錯誤消息代價昂貴。

19、在方法中遞增局部變量,速度是最快的。幾乎與在函數中調用局部變量的速度相當。

20、遞增一個全局變量要比遞增一個局部變量慢2倍。

21、遞增一個對象屬性(如:$this->prop++)要比遞增一個局部變量慢3倍。

22、遞增一個未預定義的局部變量要比遞增一個預定義的局部變量慢9至10倍。

23、僅定義一個局部變量而沒在函數中調用它,同樣會減慢速度(其程度相當于遞增一個局部變量)。PHP大概會檢查看是否存在全局變量。

24、方法調用看來與類中定義的方法的數量無關,因爲我(在測試方法之前和之後都)添加了10個方法,但性能上沒有變化。

25、派生類中的方法運行起來要快于在基類中定義的同樣的方法。

26、調用帶有一個參數的空函數,其花費的時間相當于執行7至8次的局部變量遞增操作。類似的方法調用所花費的時間接近于15次的局部變量遞增操作。

27、Apache解析一個PHP腳本的時間要比解析一個靜態HTML頁面慢2至10倍。盡量多用靜態HTML頁面,少用腳本。

28、除非腳本可以緩存,否則每次調用時都會重新編譯一次。引入一套PHP緩存機制通常可以提升25%至100%的性能,以免除編譯開銷。

29、尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。

30、当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算, 只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步 骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。

(舉例如下)

if (strlen($foo) < 5) { echo “Foo is too short”$$ }

(與下面的技巧做比較)

if (!isset($foo{5})) { echo “Foo is too short”$$ }

調用isset()恰巧比strlen()快,因爲與後者不同的是,isset()作爲一種語言結構,意味著它的執行不需要函數查找和字母小寫化。也就是說,實際上在檢驗字符串長度的頂層代碼中你沒有花太多開銷。

31、当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或 Java代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个 临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为 一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服務提供商(ISPs)和服務器。

32、並不是事必面向對象(OOP),面向對象往往開銷很大,每個方法和對象調用都會消耗很多內存。

33、並非要用類實現所有的數據結構,數組也很有用。

34、不要把方法細分得過多,仔細想想你真正打算重用的是哪些代碼?

35、當你需要時,你總能把代碼分解成方法。

36、盡量采用大量的PHP內置函數。

37、如果在代碼中存在大量耗時的函數,你可以考慮用C擴展的方式實現它們。

38、評估檢驗(profile)你的代碼。檢驗器會告訴你,代碼的哪些部分消耗了多少時間。Xdebug調試器包含了檢驗程序,評估檢驗總體上可以顯示出代碼的瓶頸。

39、mod_zip可作爲Apache模塊,用來即時壓縮你的數據,並可讓數據傳輸量降低80%。

40、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用 file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题。

41、盡量的少進行文件操作,雖然PHP的文件操作效率也不低的。

42、优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过)。

43、盡可能的使用PHP內部函數(但是我卻爲了找個PHP裏面不存在的函數,浪費了本可以寫出一個自定義函數的時間,經驗問題啊!)。

44、循環內部不要聲明變量,尤其是大變量:對象(這好像不只是PHP裏面要注意的問題吧?)。

45、多維數組盡量不要循環嵌套賦值。

46、在可以用PHP內部字符串操作函數的情況下,不要用正則表達式。

47、foreach效率更高,盡量用foreach代替while和for循環。

48、用單引號替代雙引號引用字符串。

49、用i+=1代替i=i+1。符合c/c++的習慣,效率高。

50、對global變量,應該用完就unset()掉。