提高PHP性能的實用方法+40個技巧優化您的PHP代碼


1、用單引號代替雙引號來包含字符串,這樣做會更快一些。因為PHP會在雙引號包圍的字符串中搜尋變量,單引號則不會,注意:只有echo能這么做,它是一種可以把多個字符串當作參數的"函數"(譯注:PHP手冊中說echo是語言結構,不是真正的函數,故把函數加上了雙引號)。

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

 

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

 

4、echo 比 print 快,並且使用echo輸出時用逗號而不是句點代替字符串連接效率更高,比如 echo $str1,$str2。

 

5、在執行for循環之前確定最大循環數,不要把 count/strlen/sizeof 等每次都要重復做的但結果都一樣的事情放到 for 循環的條件語句中,另外最好運用foreach代替for循環。

 

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

 

7、require_once()代價昂貴,據測試數據來看,使用require_once比require慢3-4倍,具體的解決辦法可先檢查是否存在引用然后決定是都需要require。

 

8、include和require文件時盡量不要使用相對路徑,因為使用相對路徑的時候它會首先查找指定的php包含路徑,然后查找當前目錄,因此會檢查過多路徑,所以最佳選擇是使用絕對路徑。

 

9、如果你想知道腳本開始執行(即服務器端收到客戶端請求)的時間,使用$_SERVER['REQUEST_TIME']要好於time()。至於$_SERVER['REQUEST_TIME']的作用,文檔解釋是該變量保存的是頁面請求開始時的時間戳。從 PHP 5.1.0 起有效。和time函數效果一樣。

 

10、能夠使用函數代替正則表達式的地方盡量使用函數來完成。

 

11、str_replace函數比preg_replace函數快,但strtr函數的效率是str_replace函數的四倍。strtr() 函數的作用是轉換字符串中特定的字符。

 

12、不要做無謂的替換,即使沒有替換操作,使用 str_replace 也會為其參數分配內存。很慢!解決辦法:用 strpos 先查找相關信息看是否需要替換,如果需要,再替換。實際效率對比為:如果需要替換:效率幾乎相等,差別在 0.1% 左右。如果不需要替換:用 strpos 速度將提升 200%。

 

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

 

13、使用選擇分支語句(即switch case)好於使用多個if,else if語句。

 

14、不要濫用 @ 操作符。雖然 @ 看上去很簡單,但是實際上后台有很多操作。用 @ 比起不用 @,效率差距:3 倍。特別不要在循環中使用 @ 。

 

15、打開apache的mod_deflate模塊,可以提高網頁的瀏覽速度。mod_deflate 模塊提供了DEFLATE 輸出過濾器,允許服務器在將輸出內容發送到客戶端以前進行壓縮,以節約帶寬。具體如何設置請參考相關文檔。

 

16、在方法中遞增局部變量,速度是最快的。幾乎與在函數中調用局部變量的速度相當。而遞增一個全局變量要比遞增一個局部變量慢2倍。

 

17、在方法中遞增一個對象屬性(如:$this- >num++)要比遞增一個局部變量(如:$num)慢3倍。

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

25、盡量做緩存,可使用memcached。memcached是一款高性能的內存對象緩存系統,可用來加速動態Web應用程序,減輕數據庫負載。對運算碼 (OP code)的緩存很有用,使得腳本不必為每個請求做重新編譯。

 

26、當操作字符串並需要檢驗其長度是否滿足某種要求時,你想當然地會使用strlen()函數。此函數執行起來相當快,因為它不做任何計算,只返回在zval 結構(C的內置數據結構,用於存儲PHP變量)中存儲的已知字符串長度。但是,由於strlen()是函數,多多少少會有些慢,因為函數調用會經過諸多步驟,如字母小寫化(譯注:指函數名小寫化,PHP不區分函數名大小寫)、哈希查找,會跟隨被調用的函數一起執行。在某些情況下,你可以使用isset() 技巧加速執行你的代碼,如下面的例子:

 

<?php

if (strlen($str) < 6) { echo 'str不滿6個字符'; } ?>

(與下面的技巧做比較)

 

<?php

if (!isset ($str{6})) { echo 'str不滿6個字符' ; } ?>

 

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

 

27、當執行變量$i的遞增或遞減時,$i++會比++$i慢一些。這種差異是PHP特有的,並不適用於其他語言,所以請不要修改你的C或Java代碼並指望它們能立即變快,沒用的。++$i更快是因為它只需要3條指令(opcodes),$i++則需要4條指令。后置遞增實際上會產生一個臨時變量,這個臨時變量隨后被遞增。而前置遞增直接在原值上遞增。這是最優化處理的一種,正如Zend的PHP優化器所作的那樣。牢記這個優化處理不失為一個好主意,因為並不是所有的指令優化器都會做同樣的優化處理,並且存在大量沒有裝配指令優化器的互聯網服務提供商和服務器。

 

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

 

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

 

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

 

31、能使用PHP內置函數的地方盡量使用PHP內置函數。

 

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

 

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

 

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

 

35、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情況下,盡量用file_get_contents,因為他的效率高得多!但是要注意file_get_contents在打開一個URL文件時候的PHP版本問題;

 

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

 

37、優化Select SQL語句,除非表字段,SQL關鍵字盡量用大寫代替小寫。

 

38、循環內部不要聲明變量,尤其是大變量:對象,解決辦法是循環之前預定義需要聲明的變量。

 

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

 

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

 

41、foreach效率比while和for更高。

 

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

 

43、對global變量,應該用完就unset()掉;

 

44、有意忽略php關閉標簽(即? >)。

 

45、寫入或保存文件前,請先確保目錄是可寫的,假如不可寫,輸出錯誤信息。這會節約你很多調試時間。特別是 linux 系統中,需要處理權限,目錄權限不當會導致很多很多的問題,文件也有可能無法讀取等等。比如下面的例子:

 

<?php

$contents = "All the content";

$file_path = "/var/www/project/content.txt";

file_put_contents($file_path ,$contents); ?>

這大體上正確,但有些間接的問題,file_put_contents 可能會由於幾個原因失敗:

 

(1)父目錄不存在

 

(2)目錄存在,但不可寫

 

(3)文件被寫鎖住?

 

所以寫文件前做明確的檢查更好,正確寫法如下:

 

查看代碼打印

 

<?php

$contents='測試內容';

$dir='/var/www/project';

$file_path=$dir."/content.txt";

if(is_writable($dir)){

    file_put_contents($file_path,$contents);

}else{

    die('目錄不存在或者目錄不可寫!' );

} ?>

46、不要依賴submit按鈕值來檢查表單提交行為,比如下面的情況:

 

<?php

if($_POST['submit' ] == 'Save' ) { //Save the things } ?>

上面大多數情況正確,除了應用是多語言的。 'Save' 可能代表其它含義,你怎么區分它們呢,因此,不要依賴於submit按鈕的值。正確寫法如下:

 

<?php

if( $_SERVER['REQUEST_METHOD' ] == 'POST' and isset($_POST['submit' ]) ) { //Save the things } ?>

47、不要直接使用 $_SESSION 變量

 

舉個簡單的例子:

 

$_SESSION['username'] = $username; 或者 $username = $_SESSION['username'];

 

這會導致某些問題,如果在同個域名中運行了多個應用,session 變量可能會沖突,兩個不同的應用可能使用同一個session key,例如,一個前端門戶,和一個后台管理系統使用同一域名。對於這種情況,解決方案如下,使用應用相關的key和一個包裝函數:

 

 

<?php

define('APP_ID','abc_corp_ecommerce');

function session_get($key){

    $k=APP_ID.'.'.$key;

    if(isset($_SESSION[$k])){

        return $_SESSION[$k];

    }

    return false;

}

function session_set($key,$value){

    $k=APP_ID.'.'.$key;

    $_SESSION[$k]=$value;

    return true;

}?>

48、將你的工具函數封裝到類中,假如你在某文件中定義了很多工具函數,如下:

<?php

function utility_a(){

    //This function does a utility thing like string processing

}

function utility_b(){

    //This function does nother utility thing like database processing

}

function utility_c(){

    //This function is ..

}?>

但這些函數的使用分散到應用各處,那么你可以將他們封裝到某個類中:

 

<?php

class Utility {

    public static function utility_a(){}

    public static function utility_b(){}

    public static function utility_c(){}

}?>

調用方法如:$a=Utility::utility_a(); 或者 $b=Utility::utility_b();

 

這樣做的好處是,如果php內建有同名的函數,這樣就可以避免沖突,維護起來也相當容易。

 

49、使用array_map快速處理數組,比如說你想 trim 數組中的所有元素,新手可能會:

 

查看代碼打印

<?php

foreach($arr as $c => $v) { $arr[$c] = trim($v); }?>

 

但和上面的比起來使用 array_map 更簡單,比如:

 

<?php

$arr = array_map('trim',$arr); ?>

這會為$arr數組的每個元素都申請調用trim函數,另一個類似的函數是 array_walk,具體用法請查閱文檔學習更多技巧.

 

50、使用 php filter 驗證數據,你肯定曾使用過正則表達式驗證 email ,ip地址等,可以嘗試使用 php內置的 filter 擴展來完成相關驗證和檢查輸入。

 

51、確保你的腳本由始至終都使用單一的數據庫連接,在開始處正確的打開連接,使用它直到結束,最后關閉它,像下面這種在函數中打開連接是非常糟糕的:

<?php

function add_to_cart() {

    $db = new Database ();

    $db->query("INSERT INTO cart .....");

}

function empty_cart() {

    $db = new Database ();

    $db->query("DELETE FROM cart .....");

}?>

以上事例因為創建連接需要時間和占用內存,所以會拖慢應用的速度。數據庫的鏈接最好使用單例模式。

 

----------------------------------------------------------------

【40個技巧優化您的PHP代碼】

 

PHP代碼優化

1.如果一個方法能被靜態,那就聲明他為靜態的,速度可提高 1/4;

2.echo的效率高於print,因為 echo沒有返回值,print返回一個整型 ;

3.在循環之前設置循環的最大次數,而非在在循環中 ;

4.銷毀變量去釋放內存,特別是大的數組 ;

5.避免使用像__get, __set, __autoload等魔術方法 ;//程序設計

6.requiere_once() 比較耗資源 ;

7.在includes 和requires中使用絕對路徑,這樣在分析路徑花的時間更少 ;

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

9.能使用字符處理函數的,盡量用他們,因為效率高於正則 ;//php100.com

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

11.如果一個函數既能接受數組又能接受簡單字符做為參數,例如字符替換,並且參數列表不是太長,可以考慮多用一些簡潔的替換語句,一次只替換一個字符,而不是接受數組做為查找和替換參數。大事化小, 1+1>2;

12.用@ 掩蓋錯誤會降低腳本運行速度 ;

13.$row['id'] 比$row[id]速度快 7倍,建議養成數組鍵加引號的習慣 ;

14.錯誤信息很有用;

15.在循環里別用函數,例如 For($x=0; $x < count($array); $x), count() 函數在外面先計算 ;

16.在方法里建立局部變量速度最快, 97xxoo幾乎和在方法里調用局部變量一樣快 ;

17.建立一個全局變量要比局部變量要慢 2倍;

18.建立一個對象屬性(類里面的變量 )例如($this->prop++) 比局部變量要慢 3倍;

19.建立一個未聲明的局部變量要比一個初始化的局部變量慢 9-10倍;

20.聲明一個未被任何一個函數使用過的全局變量也會使性能降低 (和聲明相同數量的局部變量一樣 ),PHP 可能去檢查這個全局變量是否存在 ;

21.方法的性能和在一個類里面定義的方法的數目沒有關系,因為我添加 10個或多個方法到測試的類里面 (這些方法在測試方法的前后 )后性能沒什么差異;

22.在子類里方法的性能優於在基類中 ;//PHP100中文網

23.只調用一個參數並且函數體為空的函數運行花費的時間等於 7-8次$localvar++ 運算,而一個類似的方法 (類里的函數)運行等於大約 15次$localvar++ 運算;

24.Surrounding your string by ‘ instead of ” will make things interpret a little faster since php looks for variables inside “…” but not inside ‘…’. Of course you can only do this when you don’t need to have variables in the string.

25.當輸出字符串時用逗號代替點分割更快些。注意:這只對 echo起作用,這個函數能接受一些字符串作為參數 ;

26.在apache 服務器里一個 php腳本頁面比相應的HTML靜態頁面生成至少要多花 2-10倍的時間,建議多用些靜態 HTML頁面和少量的腳步;

27.除非你的安裝了緩存,不然你的 php腳本每次被訪問都需要被重編譯。建議安裝個 php緩存程序,這樣通過去除一些重復的編譯來很明顯的提高你 20-100%的性能;

28.建議用memcached ,高性能的分布式內存對象緩存系統,提高動態網絡應用程序性能,減輕數據庫的負擔 ;

29.使用ip2long() 和long2ip()函數把 IP地址轉成整型存放進數據庫而非字符型。這幾乎能降低 1/4的存儲空間。同時可以很容易對地址進行排序和快速查找 ;

30.使用checkdnsrr() 通過域名存在性來確認部分 email地址的有效性,這個內置函數能保證每一個的域名對應一個 IP地址;// 程序設計

31.如果你在使用php5和 mysql4.1以上的版本,考慮使用mysql_*的改良函數 mysqli_*;

32.試着喜歡使用三元運算符 (?:);

33.在你想在徹底重做你的項目前,看看 PEAR有沒有你需要的。PEAR是個巨大的資源庫,很多 php開發者都知道;

34.使用highlight_file() 能自動打印一份很好格式化的頁面源代碼的副本 ; //程序設計

35. 使用error_reporting(0) 函數來預防潛在的敏感信息顯示給用戶。理想的錯誤報告應該被完全禁用在 php.ini文件里。可是如果你在用一 個共享的虛擬主機,php.ini你不能修改,那么你最好添加 error_reporting(0)函數,放在每個腳本文件的第一行 (或用 require_once() 來加載)這能有效的保護敏感的 SQL查詢和路徑在出錯時不被顯示 ;

36.使用 gzcompress() 和gzuncompress()對容量大的字符串進行壓縮 (解壓) 在存進(取出 )數據庫時。這種內置的函數使用 gzip算法能壓縮到90%;

37.通過參數變量地址得引用來使一個函數有多個返回值。你可以在變量前加個“ &”來表示按地址傳遞而非按值傳遞 ;

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM