PHP優化寫法

1 字符串

1.1 少用正則表達式

能用PHP內部字符串操作函數的情況下,儘量用他們,不要用正則表達式, 因爲其效率高於正則。

str_replace函數要比preg_replace快得多,strtr函數又比str_replace來得快。

 

 

1.2 字符替換

str_replace字符替換比正則替換preg_replace快,但strtr比str_replace又快1/4。

另外,不要做無謂的替換,即使沒有替換,str_replace也會爲其參數分配內存。

用 strpos 先查找(非常快),看是否需要替換,如果需要,再替換。

 

1.3 壓縮大的字符串

使用 gzcompress() 和 gzuncompress() 對容量大的字符串進行壓縮和解壓,再存入和取出數據庫。

這種內置的函數使用gzip算法,能壓縮字符串90%。

 

1.4 echo 輸出

echo 字符串用逗號代替點連接符更快些。

雖然,echo是一種語言結構,不是真正的函數。

但是,它可以把逗號隔開的多個字符串當作“函數”參數傳入,所以速度會更快。

echo $str1, $str2;       // 速度快

echo $str1 . $str2;      // 速度稍慢

 

 

1.5 儘量用單引號

PHP 引擎允許使用單引號和雙引號來封裝字符串變量,但是它們的速度是有很大的差別的!

使用雙引號的字符串會告訴 PHP 引擎,首先去讀取字符串內容,查找其中的變量,並改爲變量對應的值。

一般來說字符串是沒有變量的,使用雙引號會導致性能不佳。

最好使用字符串連接,而不是雙引號字符串。

 

 

1.6 使用isset代替strlen

在檢驗字符串長度時,我們第一想法會使用 strlen() 函數。

此函數執行起來相當快,因爲它不做任何計算,只返回在zval結構(C的內置數據結構,用於存儲PHP變量)中存儲的已知字符串長度。

但是,由於strlen()是函數,多多少少會有些慢,因爲函數調用會經過諸多步驟,如字母小寫化、哈希查找,會跟隨被調用的函數一起執行。

在某些情況下,你可以使用 isset() 技巧加速執行你的代碼。例如:

if (strlen($foo) < 5) {

    echo "Foo is too short";

}

 

// 使用isset()

if (!isset($foo{5})) {

    echo "Foo is too short";

}

 

 

1.7 用split分割字符串

在分割字符串時,split()要比explode()快。

 

1.8 echo效率高於print

因爲echo沒有返回值,print返回一個整型。

 

2 語句

2.1 最好不用@

用@掩蓋錯誤會降低腳本運行速度,並且在後臺有很多額外操作。

用@比起不用,效率差距 3 倍。特別不要在循環中使用@。

 

2.2 避免使用魔術方法

對於__開頭的函數就命名爲魔術函數,它們都在特定的條件下觸發。

這些魔術函數包括:__construct()、__get()、__call()、__autoload()等等。

以__autoload() 爲例,如果不能將類名與實際的磁盤文件對應起來,將不得不做大量的文件存在判斷。

而判斷文件存在需要磁盤I/O操作,衆所周知,磁盤I/O操作的效率很低,因此這纔是使得autoload機制效率降低的原因。

因此,在系統設計時,需要定義一套清晰的、將類名與實際磁盤文件映射的機制。

 

2.3 別在循環裏用函數

例如:

for($x=0; $x < count($array); $x++) {

}

這種寫法在每次循環的時候都會調用 count() 函數,效率大大降低,建議這樣:

 

$len = count($array);

    for($x=0; $x < $len; $x++) {

}

 

2.4 使用三元運算符

在簡單的判斷語句中,三元運算符?:更簡潔高效。

 

2.5 使用選擇分支語句

switch、case好於使用多個if、else if語句,並且代碼更加容易閱讀和維護。

 

2.6 屏蔽敏感信息

使用 error_reporting() 函數來預防潛在的敏感信息顯示給用戶。

理想的錯誤報告應該被完全禁用在php.ini文件裏。

如果用的是共享虛擬主機,php.ini不能修改,最好添加 error_reporting() 函數。

放在每個腳本文件的第一行,或者用require_once()來加載,能有效的保護敏感的SQL查詢和路徑,在出錯時不被顯示。

 

2.7 不實用段標籤<?

不要使用開始標誌的縮寫形式,你正在使用這樣的符號嗎<?,應該用完整的<?php開始標籤。

當然,如果是輸出變量,用<?= $value ?>這種方式是鼓勵的,可以是代碼更加簡潔。

 

2.8 純PHP代碼不加結束標記

如果文件內容是純 PHP 代碼,最好在文件末尾刪除 PHP 結束標記?>。

這可以避免在 PHP 結束標記之後萬一意外加入了空格或者換行符,會導致 PHP 開始輸出這些空白,而腳本中此時並無輸出的意圖。

 

3 函數

3.1 儘量使用PHP內部函數

內置函數使用C語言實現,並且經過PHP官方優化,效率更高。

 

3.2 使用絕對路徑

在include和require中儘量使用絕對路徑。

如果包含相對路徑,PHP會在include_path裏面遍歷查找文件。

用絕對路徑就會避免此類問題,解析路徑所需的時間會更少。

 

3.3 包含文件

儘量不要用require_once和include_once包含文件,它們多一個判斷文件是否被引用的過程,能不用盡量不用。

而使用require、include方法代替。

 

3.4 函數快於類方法

調用只有一個參數、並且函數體爲空的函數,花費的時間等於7-8次$localvar++運算。

而同一功能的類方法大約爲15次$localvar++運算。

 

3.5 用子類方法

基類裏面只放能重用的方法,其他功能儘量放在子類中實現,子類裏方法的性能優於在基類中。

 

3.6 類的性能和其方法數量沒有關係

新添加10個或多個方法到測試的類後,性能沒什麼差異。

 

 

3.7 讀取文件內容

在可以用file_get_contents()替代file()、fopen()、feof()、fgets()等系列方法的情況下,儘量用file_get_contents()。

因爲他的效率高得多!

 

3.8  引用傳遞參數

通過參數地址引用的方式,實現函數多個返回值,這比按值傳遞效率高。

方法是在參數變量前加個 &。

 

4 變量

4.1 及時銷燬變量

數組、對象和GLOBAL變量在 PHP 中特別佔內存的,這個由於 PHP 的底層的zend引擎引起的。

 

4.2 使用$_SERVER變量

如果你需要得到腳本執行的時間,$_SERVER['REQUSET_TIME']優於time()。

 

4.3 方法裏建立局部變量

在類的方法裏建立局部變量速度最快,幾乎和在方法裏調用局部變量一樣快。

 

4.4 局部變量比全局變量快

由於局部變量是存在棧中的。

當一個函數佔用的棧空間不是很大的時候,這部分內存很有可能全部命中cache,CPU訪問的效率是很高的。

相反,如果一個函數同時使用全局變量和局部變量,當這兩段地址相差較大時,cpu cache需要來回切換,效率會下降。

 

4.5 局部變量而不是對象屬性

建立一個對象屬性(類裏面的變量,例如:$this->prop++)比局部變量要慢3倍。

 

4.6 提前聲明局部變量

建立一個未聲明的局部變量,要比建立一個已經定義過的局部變量慢9-10倍。

 

4.7 謹慎聲明全局變量

聲明一個未被任何一個函數使用過的全局變量,也會使性能降低。

這和聲明相同數量的局部變量一樣,PHP可能去檢查這個全局變量是否存在。

 

4.8 使用++$i遞增

當執行變量$i的遞增或遞減時,$i++會比++$i慢一些。

這種差異是PHP特有的,並不適用於其他語言,所以請不要修改你的C或Java代碼,並指望它們能立即變快,沒用的。

++$i更快是因爲它只需要3條指令(opcodes),$i++則需要4條指令。

後置遞增實際上會產生一個臨時變量,這個臨時變量隨後被遞增。

而前置遞增直接在原值上遞增。

 

 

4.9 不要隨便複製變量

有時候爲了使 PHP 代碼更加整潔,會把預定義好的變量,複製到一個名字更簡短的變量中。

其實這樣做的結果是增加了一倍的內存消耗,只會使程序更加慢。

// 不好的實踐

$description = $_POST['description'];

echo $description;

 

// 好的實踐

 echo $_POST['description'];

 

4.10 循環內部不要聲明變量

尤其是大變量,這好像不只是PHP裏面要注意的問題吧?

 

4.11 一定要對變量進行初始化

 

5 數組

5.1 用字符串而不是數組作爲參數

如果一個函數既能接受數組,又能接受簡單字符做爲參數,那麼儘量用字符作爲參數。

 

5.2 數組元素加引號

$row['id']比$row[id]速度快7倍。

如果不帶引號,例如$a[name],那麼PHP會首先檢查有沒有define定義的name常量。

如果有,就用這個常量值作爲數組鍵值。如果沒有,再查找鍵值爲字符串'name'的數組元素。

 

5.3 多維數組操作

多維數組儘量不要循環嵌套賦值。

 

5.4 循環用foreach

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

發佈了117 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章