最佳化PHP程式

來源:互聯網
上載者:User
 網上很多文章介紹最佳化php程式,是通過安裝Zend Optimizer之類的加速軟體實現的,但這種加速是有限的。本文主要從程式碼著手介紹一些最佳化手段。

1、程式的抽象層越多,各抽象層分離得越嚴格,程式效率越低。

最原始的應用於網頁的php程式模式莫過於指令碼嵌入模式,即僅僅在一個網頁中需要動態處理或顯示資料的地方通過加入標識符嵌入php指令碼。一般來說這是php程式員最早學習的模式,它只有一個抽象層,就是網頁,故本文稱其為單層模式。

隨著網站規模逐漸增大,程式員可能會發現單層模式的程式很難維護,當想對程式修改或擴充功能時,會發現代碼非常混亂,感覺無從下手。於是模板類誕生了,它使一個網頁由兩個檔案組成:一個php程式檔案,一個html模板檔案。常用的模板類有PHPLib庫帶的Template模板類,Smarty模板類等。由於加入了額外的處理常式(模板類),程式效率下降了。你若不信可自己測試一下。其實一般情況下,不用函數(最原始的編程方法)比用函數(面向過程)的效率高,而用函數的效率又比對象封裝(物件導向)高。所以就算在編譯語言中,需要高效率的地方會用C寫而不用C++,例如FreeBSD作業系統的核心;而需要極端高效的地方還要用彙編寫。

為了使程式可以適應多種資料庫系統,或者方便隨時轉換資料庫系統,常常還會用一個類把跟資料庫打交道的函數封裝起來,這樣當轉換資料庫系統時只要把封裝類換掉就行了,主程式不需要修改。這裡又用了一個類,效率又打折扣了。

上述模板類的使用,使程式分成兩個抽象層:程式層和表現層。而資料庫類的使用又把程式層分為資料介面層和資料處理層。

項目越龐大,需要分離的抽象層就越多,這樣使得分工清晰,方便管理,但是以犧牲程式執行效率為代價。

對於抽象層造成的效率下降,最佳化的方法有二:減小抽象層、最佳化抽象層之間的介面。一般地,不應該為了提高效率而盲目減小抽象層,這樣會使得代碼混亂、難於管理。但是不應該為小項目建立過多的抽象層,除非你有將來把它做得很大的計劃。關於如何恰當分割抽象層,本文不作更深入討論。

對於上文說的兩個分層例子,最佳化抽象層之間的介面分別是模板類和資料庫操作類。抽象層介面在程式中需要被頻繁調用,以在不同層之間交換資訊,所以層介面是很值得最佳化的。對於資料庫介面類,可能僅僅是封裝一些資料庫函數,最佳化餘地恐怕不大。對於模板類,很多時候是有較大最佳化餘地的。一般地,模板模型越通用,模板類功能越強大,效率就越低,例如PHPLib庫帶的Template類就有極大的最佳化餘地。而Smarty模板類比PHPLib的Template更複雜,我沒有用過,據稱有緩衝機制,不知是否可以彌補其效能損耗。下面就來看看PHPLib的Template類有多少東西可以最佳化掉。

(1) 讀入模板檔案時,file函數效率低,改用get_file_content函數。

(2) 匹配子模板時,Regex替換函數preg_replace效率低,改用str_pos函數進行定位和用str_replace函數進行替換操作。此最佳化手段後文會詳細分析。

(3) 模板模型通用性很強,能適應各種情況,但在具體細節的處理上,通用的方法效率可能很低。可以對模板模型作適當修改。我的做法是建一個相對通用的模板類,然後再派生出一個只適用於特定程式的模板類。在通用模板類的模板模型上可以作些最佳化(相對於PHPLib的Template),例如在處理二維資料表的時候用PHPLib的Template處理就比較複雜,需要多次調用類方法(本質上是函數調用),所以重寫的時候可以把處理二維資料表的功能封裝到一個高效率的方法中,直接避免方法的多次調用。

(4) 調試功能在小項目上不需要用,跟調試相關的代碼全部去掉。

我在按上面4點重寫了模板類之後,一個複雜頁面的執行時間縮小了一個數量級(除模板外沒有作其它最佳化)。

現在就最佳化你的程式的抽象層之間的介面,特別是當這些介面是使用現成的函數或類的時候。因為這些函數或類在設計時會為了適應普遍情況而犧牲一些效率,而且它們的作者也可能沒有考慮效率問題。像如此著名的PHPLib的模板類的效率也不見得就高。

2、細節代碼最佳化

(1) 上文模板類最佳化已提到的,Regex匹配比一般字串匹配慢得多,儘可能用字串匹配而不用Regex匹配。有時候雖然用Regex匹配使程式碼更簡潔,而一般字串匹配使代碼更冗繁,但很多時候字串匹配仍比Regex高效。

(2) 字串替換函數str_replace和preg_replace都是可以接受數組參數的。有時候需要對字串進行批量替換,則用數組參數比迴圈調用替換函數來得高效。例如下面的代碼:

for ($i = 0; $i < $n; $i++) {
$str = str_replace($search[$i], $replace[$i], $str);
}

應該換成:

$str = str_replace($search, $replace,

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.