一、不要使用相對路徑php
例如html
require_once('../../lib/some_class.php');
該方法有不少缺點:前端
1)它首先查找指定的php包含路徑, 而後查找當前目錄mysql
2)若是該腳本被另外一目錄的腳本包含, 它的基本目錄變成了另外一腳本所在的目錄sql
3)當定時任務運行該腳本, 它的上級目錄可能就不是工做目錄了shell
所以正確的寫法是:數據庫
define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME)); require_once(ROOT . '../../lib/some_class.php');
二、不要直接使用 require, include, include_once, required_onceapache
require_once('lib/Database.php'); require_once('lib/Mail.php'); require_once('helpers/utitlity_functions.php');
這種用法至關原始. 應該更靈活點. 應編寫個助手函數包含文件數組
function load_class($class_name) { $path = ROOT . '/lib/' . $class_name . '.php'); require_once( $path ); } load_class('Database'); load_class('Mail');
有什麼不同嗎? 該代碼更具可讀性,將來你能夠按需擴展該函數,瀏覽器
function load_class($class_name) { $path = ROOT . '/lib/' . $class_name . '.php'); if(file_exists($path)){ include( $path ); } }
還可作得更多:
1)爲一樣文件查找多個目錄
2)能很容易的改變放置類文件的目錄, 無須在代碼各處一一修改
3)可以使用相似的函數加載文件, 如html內容
不過強烈建議使用include、require 代替include_once ,require_once
三、使用可跨平臺的函數執行命令
system, exec, passthru, shell_exec 這4個函數可用於執行系統命令. 每一個的行爲都有細微差異. 問題在於, 當在共享主機中, 某些函數可能被選擇性的禁用. 大多數新手趨於每次首先檢查哪一個函數可用, 然而再使用它.
更好的方案是封成函數一個可跨平臺的函數.
/** Method to execute a command in the terminal Uses : 1. system 2. passthru 3. exec 4. shell_exec */ function terminal($command) { if(function_exists('system')) { ob_start(); system($command , $return_var); $output = ob_get_contents(); ob_end_clean(); } elseif(function_exists('passthru')) { ob_start(); passthru($command , $return_var); $output = ob_get_contents(); ob_end_clean(); } elseif(function_exists('exec')) { exec($command , $output , $return_var); $output = implode("\n" , $output); } elseif(function_exists('shell_exec')) { $output = shell_exec($command) ; } else { $output = 'Command execution not possible on this system'; $return_var = 1; } return array('output' => $output , 'status' => $return_var); } terminal('ls');
四、忽略php關閉標籤
<?php class super_class { function super_function() { } } //No closing tag
這會更好
五、在某地方收集全部輸入, 一次輸出給瀏覽器
這稱爲輸出緩衝, 假如說你已在不一樣的函數輸出內容:
function print_header() { echo "<div id='header'>Site Log and Login links</div>"; } function print_footer() { echo "<div id='footer'>Site was made by me</div>"; } print_header(); for($i = 0 ; $i < 100; $i++) { echo "I is : $i '; } print_footer();
替代方案, 在某地方集中收集輸出. 你能夠存儲在函數的局部變量中, 也可使用ob_start和ob_end_clean. 以下:
function print_header() { $o = "<div id='header'>Site Log and Login links</div>"; return $o; } function print_footer() { $o = "<div id='footer'>Site was made by me</div>"; return $o; } echo print_header(); for($i = 0 ; $i < 100; $i++) { echo "I is : $i '; } echo print_footer();
爲何須要輸出緩衝:
1)能夠在發送給瀏覽器前更改輸出. 如 str_replaces 函數或多是 preg_replaces 或添加些監控/調試的html內容
2)輸出給瀏覽器的同時又作php的處理很糟糕
六、爲mysql鏈接設置正確的字符編碼
//Attempt to connect to database $c = mysqli_connect($this->host , $this->username, $this->password); //Check connection validity if (!$c) { die ("Could not connect to the database host: ". mysqli_connect_error()); } //Set the character set of the connection if(!mysqli_set_charset ( $c , 'UTF8' )) { die('mysqli_set_charset() failed'); } //一旦鏈接數據庫, 最好設置鏈接的 characterset. 你的應用若是要支持多語言, 這麼作是必須的
七、不要在應用中使用gzip壓縮輸出, 讓apache處理
考慮過使用 ob_gzhandler 嗎? 不要那樣作. 毫無心義. php只應用來編寫應用. 不該操心服務器和瀏覽器的數據傳輸優化問題、使用apache的mod_gzip/mod_deflate 模塊壓縮內容
八、寫文件前, 檢查目錄寫權限
$contents = "All the content"; $dir = '/var/www/project'; $file_path = $dir . "/content.txt"; if(is_writable($dir)) { file_put_contents($file_path , $contents); } else { die("Directory $dir is not writable, or does not exist. Please check"); }
九、爲函數內總具備相同值的變量定義成靜態變量
//Delay for some time function delay() { $sync_delay = get_option('sync_delay'); echo "Delaying for $sync_delay seconds..."; sleep($sync_delay); echo "Done "; } 用靜態變量取代: //Delay for some time function delay() { static $sync_delay = null; if($sync_delay == null) { $sync_delay = get_option('sync_delay'); } echo "Delaying for $sync_delay seconds..."; sleep($sync_delay); echo "Done "; }
十、不要直接使用 $_SESSION 變量
$_SESSION['username'] = $username; $username = $_SESSION['username'];
這會致使某些問題. 若是在同個域名中運行了多個應用, session 變量可能會衝突. 兩個不一樣的應用可能使用同一個session key. 例如, 一個前端門戶, 和一個後臺管理系統使用同一域名.
//從如今開始, 使用應用相關的key和一個包裝函數: define('APP_ID' , 'abc_corp_ecommerce'); //Function to get a session variable function session_get($key) { $k = APP_ID . '.' . $key; if(isset($_SESSION[$k])) { return $_SESSION[$k]; } return false; } //Function set the session variable function session_set($key , $value) { $k = APP_ID . '.' . $key; $_SESSION[$k] = $value; return true; }
十一、實用的寫法
>>使用echo取代print >>使用str_replace取代preg_replace, 除非你絕對須要 >>不要使用 short tag >>簡單字符串用單引號取代雙引號 >>head重定向後記得使用exit >>不要在循環中調用函數 >>isset比strlen快 >>始中如一的格式化代碼 >>不要刪除循環或者if-else的括號 >>不要嘗試省略一些語法來縮短代碼. 而是讓你的邏輯簡短 >>使用有高亮語法顯示的文本編輯器. 高亮語法能讓你減小錯誤 >>使用 php filter >>驗證數據強制類型檢查 >>若是須要,使用profiler如xdebug >>由始至終使用單一數據庫鏈接 >>避免直接寫SQL, 抽象之 >>在head中使用base標籤 >>永遠不要將 error_reporting 設爲 0 eg:error_reporting(~E_WARNING & ~E_NOTICE & ~E_STRICT);
十二、使用array_map快速處理數組
$arr = array_map('trim' , $arr);
這會爲$arr數組的每一個元素都申請調用trim. 另外一個相似的函數是 array_walk. 請查閱文檔學習更多技巧
1三、 避免使用全局變量
>>使用 defines/constants >>使用函數獲取值 >>使用類並經過$this訪問
1四、不要過度依賴 set_time_limit
注意任何外部的執行, 如系統調用,socket操做, 數據庫操做等, 就不在set_time_limits的控制之下.所以, 就算數據庫花費了不少時間查詢, 腳本也不會中止執行. 視狀況而定
參考原文地址:http://www.binarytides.com/40-techniques-to-enhance-your-php-code-part-2/