提高PHP代码质量需要注意的地方三
19. Bunch of silly tips
>>使用echo取代print
>>使用str_replace取代preg_replace, 除非你絕對需要
>>不要使用 short tag
>>簡單字符串用單引號取代雙引號
>>head重定向后記得使用exit
>>不要在循環中調用函數
>>isset比strlen快
>>始中如一的格式化代碼
>>不要刪除循環或者if-else的括號
不要這樣寫代碼:
| 1 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">if($a== true) $a_count++;</span> |
這絕對WASTE.
寫成:
| 1234 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">if($a== true){$a_count++;}</span> |
不要嘗試省略一些語法來縮短代碼. 而是讓你的邏輯簡短.
>>使用有高亮語法顯示的文本編輯器. 高亮語法能讓你減少錯誤.
20. 使用array_map快速處理數組
比如說你想 trim 數組中的所有元素. 新手可能會:
| 1234 | foreach($arras$c=> $v){$arr[$c] = trim($v);} |
但使用 array_map 更簡單:
| 1 | $arr= array_map('trim', $arr); |
這會為$arr數組的每個元素都申請調用trim. 另一個類似的函數是 array_walk. 請查閱文檔學習更多技巧.
21. 使用 php filter 驗證數據
你肯定曾使用過正則表達式驗證 email , ip地址等. 是的,每個人都這么使用. 現在, 我們想做不同的嘗試, 稱為filter.
php的filter擴展提供了簡單的方式驗證和檢查輸入.
22. 強制類型檢查
| 12 | $amount= intval( $_GET['amount'] );$rate= (int) $_GET['rate']; |
這是個好習慣.
23. 如果需要,使用profiler如xdebug
如果你使用php開發大型的應用, php承擔了很多運算量, 速度會是一個很重要的指標. 使用profile幫助優化代碼. 可使用xdebug和webgrid.
24. 小心處理大數組
對于大的數組和字符串, 必須小心處理. 常見錯誤是發生數組拷貝導致內存溢出,拋出Fatal Error of Memory size 信息:
| 123 | $db_records_in_array_format; //This is a big array holding 1000 rows from a table each having 20 columns , every row is atleast 100 bytes , so total 1000 * 20 * 100 = 2MB$cc= $db_records_in_array_format; //2MB moresome_function($cc); //Another 2MB ? |
當導入或導出csv文件時, 常常會這么做.
不要認為上面的代碼會經常因內存限制導致腳本崩潰. 對于小的變量是沒問題的, 但處理大數組的時候就必須避免.
確保通過引用傳遞, 或存儲在類變量中:
| 12 | $a= get_large_array();pass_to_function(&$a); |
這么做后, 向函數傳遞變量引用(而不是拷貝數組). 查看文檔.
| 123456789101112 | classA{functionfirst(){$this->a = get_large_array();$this->pass_to_function();}functionpass_to_function(){//process $this->a}} |
盡快的 unset 它們, 讓內存得以釋放,減輕腳本負擔.
25. 由始至終使用單一數據庫連接
確保你的腳本由始至終都使用單一的數據庫連接. 在開始處正確的打開連接, 使用它直到結束, 最后關閉它. 不要像下面這樣在函數中打開連接:
| 12345678910 | functionadd_to_cart(){$db= newDatabase();$db->query("INSERT INTO cart .....");}functionempty_cart(){$db= newDatabase();$db->query("DELETE FROM cart .....");} |
使用多個連接是個糟糕的, 它們會拖慢應用, 因為創建連接需要時間和占用內存.
特定情況使用單例模式, 如數據庫連接.
26. 避免直接寫SQL, 抽象之
不厭其煩的寫了太多如下的語句:
| 12 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">$query= "INSERT INTO users(name , email , address , phone) VALUES('$name' , '$email' , '$address' , '$phone')";$db->query($query); //call to mysqli_query()</span> |
這不是個建壯的方案. 它有些缺點:
>>每次都手動轉義值
>>驗證查詢是否正確
>>查詢的錯誤會花很長時間識別(除非每次都用if-else檢查)
>>很難維護復雜的查詢
因此使用函數封裝:
| 123456789101112131415 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">functioninsert_record($table_name, $data){foreach($dataas$key=> $value){//mysqli_real_escape_string$data[$key] = $db->mres($value);}$fields= implode(',', array_keys($data));$values= "'". implode("','", array_values($data)) . "'";//Final query$query= "INSERT INTO {$table}($fields) VALUES($values)";return$db->query($query);}$data= array('name'=> $name, 'email'=> $email, 'address'=> $address, 'phone'=> $phone);insert_record('users', $data);</span> |
看到了嗎? 這樣會更易讀和擴展. record_data 函數小心的處理了轉義.
最大的優點是數據被預處理為一個數組, 任何語法錯誤都會被捕獲.
該函數應該定義在某個database類中, 你可以像 $db->insert_record這樣調用.
查看本文, 看看怎樣讓你處理數據庫更容易.
類似的也可以編寫update,select,delete方法. 試試吧.
27. 將數據庫生成的內容緩存到靜態文件中
如果所有的內容都是從數據庫獲取的, 它們應該被緩存. 一旦生成了, 就將它們保存在臨時文件中. 下次請求該頁面時, 可直接從緩存中取, 不用再查數據庫.
好處:
>>節約php處理頁面的時間, 執行更快
>>更少的數據庫查詢意味著更少的mysql連接開銷
28. 在數據庫中保存session
基于文件的session策略會有很多限制. 使用基于文件的session不能擴展到集群中, 因為session保存在單個服務器中. 但數據庫可被多個服務器訪問, 這樣就可以解決問題.
在數據庫中保存session數據, 還有更多好處:
>>處理username重復登錄問題. 同個username不能在兩個地方同時登錄.
>>能更準備的查詢在線用戶狀態.
29. 避免使用全局變量
>>使用 defines/constants
>>使用函數獲取值
>>使用類并通過$this訪問
30. 在head中使用base標簽
沒聽說過? 請看下面:
| 1234567 | <head><basehref="http://www.domain.com/store/"></head><body><imgsrc="happy.jpg"/></body></html> |
base 標簽非常有用. 假設你的應用分成幾個子目錄, 它們都要包括相同的導航菜單.
www.domain.com/store/home.php
www.domain.com/store/products/ipad.php
在首頁中, 可以寫:
| 12 | <a href="home.php">Home</a><a href="products/ipad.php">Ipad</a> |
但在你的ipad.php不得不寫成:
| 12 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><a href="../home.php">Home</a><a href="ipad.php">Ipad</a></span> |
因為目錄不一樣. 有這么多不同版本的導航菜單要維護, 很糟糕啊.
因此, 請使用base標簽.
| 12345678 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><head><base href="http://www.domain.com/store/"></head><body><a href="home.php">Home</a><a href="products/ipad.php">Ipad</a></body></html></span> |
現在, 這段代碼放在應用的各個目錄文件中行為都一致.
31. 永遠不要將 error_reporting 設為 0
關閉不相的錯誤報告. E_FATAL 錯誤是很重要的.
| 12 | <span style="color:#333333;font-family:'Helvetica, Arial, sans-serif';">ini_set('display_errors', 1);error_reporting(~E_WARNING & ~E_NOTICE & ~E_STRICT);</span> |
32. 注意平臺體系結構
integer在32位和64位體系結構中長度是不同的. 因此某些函數如 strtotime 的行為會不同.
在64位的機器中, 你會看到如下的輸出.
| 12345678 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">$ php -aInteractive shellphp > echostrtotime("0000-00-00 00:00:00");-62170005200php > echostrtotime('1000-01-30');-30607739600php > echostrtotime('2100-01-30');4104930600</span> |
但在32位機器中, 它們將是bool(false). 查看這里, 了解更多.
33. 不要過分依賴 set_time_limit
如果你想限制最小時間, 可以使用下面的腳本:
| 12 | <span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">set_time_limit(30);//Rest of the code</span> |
高枕無憂嗎? 注意任何外部的執行, 如系統調用,socket操作, 數據庫操作等, 就不在set_time_limits的控制之下.
因此, 就算數據庫花費了很多時間查詢, 腳本也不會停止執行. 視情況而定.
34. 使用擴展庫
一些例子:
>>mPDF — 能通過html生成pdf文檔
>>PHPExcel — 讀寫excel
>>PhpMailer — 輕松處理發送包含附近的郵件
>>pChart — 使用php生成報表
使用開源庫完成復雜任務, 如生成pdf, ms-excel文件, 報表等.
35. 使用MVC框架
是時候使用像 codeigniter 這樣的MVC框架了. MVC框架并不強迫你寫面向對象的代碼. 它們僅將php代碼與html分離.
>>明確區分php和html代碼. 在團隊協作中有好處, 設計師和程序員可以同時工作.
>>面向對象設計的函數能讓你更容易維護
>>內建函數完成了很多工作, 你不需要重復編寫
>>開發大的應用是必須的
>>很多建議, 技巧和hack已被框架實現了
36. 時常看看 phpbench
phpbench 提供了些php基本操作的基準測試結果, 它展示了一些徽小的語法變化是怎樣導致巨大差異的.
轉載于:https://blog.51cto.com/jinjiang2009/1354848
總結
以上是生活随笔為你收集整理的提高PHP代码质量需要注意的地方三的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nagios 监控平台搭建
- 下一篇: [Android开发] 启程