提升PHP編碼的一些技巧

一、不要使用相對路徑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/

相關文章
相關標籤/搜索