欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

高質(zhì)量PHP代碼的50個實用技巧必備(下)

 更新時間:2016年01月22日 17:20:52   投稿:lijiao  
這篇文章主要為大家分享了50個高質(zhì)量PHP代碼的實用技巧,大家必備的php實用代碼,感興趣的小伙伴們可以參考一下

接著上篇《高質(zhì)量PHP代碼的50個實用技巧必備(上)》繼續(xù)研究。

26. 避免直接寫SQL, 抽象之
不厭其煩的寫了太多如下的語句:

<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>

這不是個建壯的方案. 它有些缺點:

  • >>每次都手動轉(zhuǎn)義值
  • >>驗證查詢是否正確
  • >>查詢的錯誤會花很長時間識別(除非每次都用if-else檢查)
  • >>很難維護復雜的查詢

因此使用函數(shù)封裝:

<span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">function insert_record($table_name , $data)
 {
 foreach($data as $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 函數(shù)小心的處理了轉(zhuǎn)義。最大的優(yōu)點是數(shù)據(jù)被預處理為一個數(shù)組, 任何語法錯誤都會被捕獲。該函數(shù)應(yīng)該定義在某個database類中, 你可以像 $db->insert_record這樣調(diào)用。查看本文, 看看怎樣讓你處理數(shù)據(jù)庫更容易。類似的也可以編寫update,select,delete方法. 試試吧.

27. 將數(shù)據(jù)庫生成的內(nèi)容緩存到靜態(tài)文件中
如果所有的內(nèi)容都是從數(shù)據(jù)庫獲取的, 它們應(yīng)該被緩存. 一旦生成了, 就將它們保存在臨時文件中. 下次請求該頁面時, 可直接從緩存中取, 不用再查數(shù)據(jù)庫.
好處:
>>節(jié)約php處理頁面的時間, 執(zhí)行更快
>>更少的數(shù)據(jù)庫查詢意味著更少的mysql連接開銷

28. 在數(shù)據(jù)庫中保存session
基于文件的session策略會有很多限制. 使用基于文件的session不能擴展到集群中, 因為session保存在單個服務(wù)器中. 但數(shù)據(jù)庫可被多個服務(wù)器訪問, 這樣就可以解決問題.
在數(shù)據(jù)庫中保存session數(shù)據(jù), 還有更多好處:
>>處理username重復登錄問題. 同個username不能在兩個地方同時登錄.
>>能更準備的查詢在線用戶狀態(tài).

29. 避免使用全局變量

  • >>使用 defines/constants
  • >>使用函數(shù)獲取值
  • >>使用類并通過$this訪問

30. 在head中使用base標簽
沒聽說過? 請看下面:

<head>
 <base >
 </head>
 <body>
 <img src="happy.jpg" />
 </body>
 </html>

base 標簽非常有用. 假設(shè)你的應(yīng)用分成幾個子目錄, 它們都要包括相同的導航菜單.

  • www.domain.com/store/home.php
  • www.domain.com/store/products/ipad.php

在首頁中, 可以寫:

<a href="home.php">Home</a>
<a href="products/ipad.php">Ipad</a>

但在你的ipad.php不得不寫成:

<span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><a href="../home.php">Home</a>
 <a href="ipad.php">Ipad</a></span>

因為目錄不一樣. 有這么多不同版本的導航菜單要維護, 很糟糕啊。因此, 請使用base標簽.

<span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';"><head>
 <base >
 </head>
 <body>
 <a href="home.php">Home</a>
 <a href="products/ipad.php">Ipad</a>
 </body>
 </html></span>

現(xiàn)在, 這段代碼放在應(yīng)用的各個目錄文件中行為都一致.

31. 永遠不要將 error_reporting 設(shè)為 0
關(guān)閉不相的錯誤報告. E_FATAL 錯誤是很重要的.

<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. 注意平臺體系結(jié)構(gòu)
integer在32位和64位體系結(jié)構(gòu)中長度是不同的. 因此某些函數(shù)如 strtotime 的行為會不同.
在64位的機器中, 你會看到如下的輸出.

<span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">$ php -a 
 Interactive shell 
 php > echo strtotime("0000-00-00 00:00:00"); 
 -62170005200 
 php > echo strtotime('1000-01-30'); 
 -30607739600 
 php > echo strtotime('2100-01-30'); 
 4104930600</span> 

但在32位機器中, 它們將是bool(false). 查看這里, 了解更多.

33. 不要過分依賴 set_time_limit
如果你想限制最小時間, 可以使用下面的腳本:

<span style="color:#333333;font-family:''Helvetica, Arial, sans-serif'';">set_time_limit(30);
 //Rest of the code</span>

高枕無憂嗎? 注意任何外部的執(zhí)行, 如系統(tǒng)調(diào)用,socket操作, 數(shù)據(jù)庫操作等, 就不在set_time_limits的控制之下.
因此, 就算數(shù)據(jù)庫花費了很多時間查詢, 腳本也不會停止執(zhí)行. 視情況而定.

34. 使用擴展庫
一些例子:

  • >>mPDF — 能通過html生成pdf文檔
  • >>PHPExcel — 讀寫excel
  • >>PhpMailer — 輕松處理發(fā)送包含附近的郵件
  • >>pChart — 使用php生成報表

使用開源庫完成復雜任務(wù), 如生成pdf, ms-excel文件, 報表等.

35. 使用MVC框架
是時候使用像 codeigniter 這樣的MVC框架了. MVC框架并不強迫你寫面向?qū)ο蟮拇a. 它們僅將php代碼與html分離.

  • >>明確區(qū)分php和html代碼. 在團隊協(xié)作中有好處, 設(shè)計師和程序員可以同時工作.
  • >>面向?qū)ο笤O(shè)計的函數(shù)能讓你更容易維護
  • >>內(nèi)建函數(shù)完成了很多工作, 你不需要重復編寫
  • >>開發(fā)大的應(yīng)用是必須的
  • >>很多建議, 技巧和hack已被框架實現(xiàn)了

36. 時??纯?phpbench
phpbench 提供了些php基本操作的基準測試結(jié)果, 它展示了一些徽小的語法變化是怎樣導致巨大差異的.
查看php站點的評論, 有問題到IRC提問, 時常閱讀開源代碼, 使用Linux開發(fā).

37. 如何正確的創(chuàng)建一個網(wǎng)站的Index頁面
創(chuàng)建每一個網(wǎng)站時,建立網(wǎng)站的index頁面是首要做的事情之一。如果你是一個PHP新手,在編寫index頁面時典型的做法是只對index頁面所需的內(nèi)容進行編程,其它鏈接創(chuàng)建另一個頁面。不過,如果想學習一種更高效的方式來實現(xiàn)PHP編程,可以采用“index.php?page=home”模式,許多網(wǎng)站都在采用這種模式。

38. 使用Request Global Array抓取數(shù)據(jù)
實際上我們沒有任何理由使用$_GET和$_POST數(shù)組來抓取數(shù)值。$_REQUEST這個全局數(shù)組能夠讓你獲取一個get或form請求。因此,多數(shù)情況下解析數(shù)據(jù)的更高效代碼大體如下:

$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 0;

39. 利用var_dump進行PHP代碼調(diào)試
如果你在尋找php調(diào)試技術(shù),我必須說var_dump應(yīng)該是你要找的目標。在顯示php信息方面這個命令可以滿足你的所有需要。而調(diào)試代碼的多數(shù)情況與得到PHP中的數(shù)值有關(guān)。

40. PHP處理代碼邏輯,Smarty處理展現(xiàn)層
Smarty是一個使用PHP寫出來的模板PHP模板引擎,是目前業(yè)界最著名的PHP模板引擎之一。它分離了邏輯代碼和外在的內(nèi)容,提供了一種易于管理和使用的方法,用來將原本與HTML代碼混雜在一起PHP代碼邏輯分離。簡單的講,目的就是要使PHP程序員同前端人員分離,使程序員改變程序的邏輯內(nèi)容不會影響到前端人員的頁面設(shè)計,前端人員重新修改頁面不會影響到程序的程序邏輯,這在多人合作的項目中顯的尤為重要。

41. 的確需要使用全局數(shù)值時,創(chuàng)建一個Config文件
動輒創(chuàng)建全局數(shù)值是一種糟糕的做法,不過有時候?qū)嶋H情況的確又需要這么做。對于數(shù)據(jù)庫表或數(shù)據(jù)庫連接信息使用全局數(shù)值是一個不錯的想法,但不要在你的PHP代碼中頻繁使用全局數(shù)值。另外,更好的一種做法是把你的全局變量存放在一個config.php文件中。

42. 如果未定義,禁止訪問!
如果你正確的創(chuàng)建了頁面,那么任何其他人沒有理由訪問index.php或home.php之外的index.php頁面。一旦index.php被訪問后,你可以通過獲得變量的方式來打開需要的頁面。你的index頁面應(yīng)該包含類似的以下代碼:

define('yourPage',1);

然后,其它頁面應(yīng)該包含:

if (!defined('yourPage')) die('Access Denied');

這么做的目的是防止直接訪問你的其它php頁面。這樣,任何試圖不通過index.php訪問其它網(wǎng)頁的人,將得到“訪問被拒絕”的消息。

43. 創(chuàng)建一個數(shù)據(jù)庫類
如果你正在進行數(shù)據(jù)庫編程(在PHP中非常常見的任務(wù)),一個不錯的想法是創(chuàng)建一個數(shù)據(jù)庫類來處理任何數(shù)據(jù)庫管理功能。示例代碼如下:

public function dbExec($query)  
    
 {  
    
   $result = $this->db->exec($query);  
    
   if (PEAR::isError($result))  
    
     errorRedirect($result->getMessage(), true);  
    
   else 
    
     return $result;  
    
 }

這個函數(shù)僅接收一個查詢語句并對其執(zhí)行。它還處理可能出現(xiàn)的任何錯誤。你還可以在這兒包含審核代碼,不過我更喜歡使用一個類似的審核函數(shù):

// checks if arguments given are integer values not less than 0 - has multiple arguments  
    
 function sanitizeInput()  
    
 {  
    
   $numargs = func_num_args();  
    
   $arg_list = func_get_args();  
    
   for ($i = 0; $i < $numargs; $i++) {  
    
     if (!is_numeric($arg_list[$i]) || $arg_list[$i] < 0)  
    
       errorRedirect("Unexpected variable value", true);  
    
   }  
    
 }

44. 一個php文件處理輸入,一個class.php文件處理具體功能
不讓代碼變得混亂的一個重要方法是:獲取用戶輸入后,將其重定向到其它函數(shù)來進行處理。原理非常簡單,php文件獲得我們需要的任何輸入,然后將其執(zhí)行重定向到類文件中的一個函數(shù)。舉例來講,假設(shè)有一個類似“index.php?page=profile&action=display”的URL。由profile.php來檢索該網(wǎng)址并得到操作是“display”。然后使用一個簡單的switch函數(shù),我們來執(zhí)行真正的顯示函數(shù):

require_once PROJECTROOT.'libs/messages.class.php';  
    
$message = new Message();  
    
switch ($action) 
    
{ 
    
  case 'display': 
    
    $message->display(); 
    
    break;  
    
...



如上所示,我使用了一個消息類,然后開始進行switch檢查。$message只是被類中的調(diào)用函數(shù)使用的一個對象。

45. 了解你的SQL語句,并總是對其審查(Sanitize)
正如我以前所提到的,任何php網(wǎng)站中最重要的部分有99%的可能是數(shù)據(jù)庫。因此,你需要非常熟悉如何正確的使用sql。學會關(guān)聯(lián)表和更多高級技術(shù)。下面我將展示一個使用MySQL的函數(shù)示例,并使用本文第7條函數(shù)進行審查。

private function getSentMessages($id)  
    
 {  
    
$this->util->sanitizeInput($id);  
    
  $pm_table = $GLOBALS['config']['privateMsg'];  
    
 $users = $GLOBALS['config']['users'];  
    
   $sql = "SELECT PM.*, USR.username as name_sender FROM $pm_table PM, $users USR  
    
     WHERE id_sender = '$id' AND sender_purge = FALSE AND USR.id = PM.id_receiver AND is_read = TRUE  
    
     ORDER BY date_sent DESC";  
    
 $result = $this->dbQueryAll($sql);  
    
  return $result;  
    
 }

首先,我們對用戶輸入進行檢查(通過一個GET變量傳遞消息id),然后我們執(zhí)行我們的SQL命令。注意這兒SQL的用法。你需要了解如何使用別名和關(guān)聯(lián)表。

46. 當你只需要一個對象時,使用單例模式
在PHP中相當常見的一種情形時,我們只需要創(chuàng)建一個對象一次,然后在我們的整個程序中使用它。一個很好的例子就是smarty變量,一旦被初始化后就可以在任何地方使用。這種情形的一個很好實現(xiàn)方案就是單例模式。示例代碼如下:

function smartyObject()  
    
 {  
    
   if ($GLOBALS['config']['SmartyObj'] == 0)  
    
   {  
    
     $smarty = new SmartyGame();  
    
     $GLOBALS['config']['SmartyObj'] = $smarty;  
    
   }  
    
   else 
    
     $smarty = $GLOBALS['config']['SmartyObj'];  
    
   return $smarty;  
    
 }

注意,我們擁有一個全局smarty變量(該示例中它在config.php中被初始化),如果它的值為0,我們將創(chuàng)建一個新smarty對象。否則,它意味著該對象已經(jīng)被創(chuàng)建,我們只需要返回它。

47. 關(guān)于PHP重定向
方法一:header("Location:index.php");
方法二:echo"<script>window.location=\"$PHP_SELF\";</script>";
方法三:echo"<METAHTTP-EQUIV=\"Refresh\"CONTENT=\"0;URL=index.php\">";

48. 獲取訪問者瀏覽器

functionbrowse_infor()
{
$browser="";$browserver="";
$Browsers=array("Lynx","MOSAIC","AOL","Opera","JAVA","MacWeb","WebExplorer","OmniWeb");
$Agent=$GLOBALS["HTTP_USER_AGENT"];
for($i=0;$i<=7;$i++)
{
if(strpos($Agent,$Browsers[$i]))
{
$browser=$Browsers[$i];
$browserver="";
}
}
if(ereg("Mozilla",$Agent)&&!ereg("MSIE",$Agent))
{
$temp=explode("(",$Agent);$Part=$temp[0];
$temp=explode("/",$Part);$browserver=$temp[1];
$temp=explode("",$browserver);$browserver=$temp[0];
$browserver=preg_replace("/([\d\.]+)/","\1",$browserver);
$browserver="$browserver";
$browser="NetscapeNavigator";
}
if(ereg("Mozilla",$Agent)&&ereg("Opera",$Agent))
{
$temp=explode("(",$Agent);$Part=$temp[1];
$temp=explode(")",$Part);$browserver=$temp[1];
$temp=explode("",$browserver);$browserver=$temp[2];
$browserver=preg_replace("/([\d\.]+)/","\1",$browserver);
$browserver="$browserver";
$browser="Opera";
}
if(ereg("Mozilla",$Agent)&&ereg("MSIE",$Agent))
{
$temp=explode("(",$Agent);$Part=$temp[1];
$temp=explode(";",$Part);$Part=$temp[1];
$temp=explode("",$Part);$browserver=$temp[2];
$browserver=preg_replace("/([\d\.]+)/","\1",$browserver);
$browserver="$browserver";
$browser="InternetExplorer";
}
if($browser!="")
{
$browseinfo="$browser$browserver";
}
else
{
$browseinfo="Unknown";
}
return$browseinfo;
}
//調(diào)用方法$browser=browseinfo();直接返回結(jié)果

49.獲取訪問者操作系統(tǒng)

functionosinfo(){
$os="";
$Agent=$GLOBALS["HTTP_USER_AGENT"];
if(eregi('win',$Agent)&&strpos($Agent,'95')){
$os="Windows95";
}
elseif(eregi('win9x',$Agent)&&strpos($Agent,'4.90')){
$os="WindowsME";
}
elseif(eregi('win',$Agent)&&ereg('98',$Agent)){
$os="Windows98";
}
elseif(eregi('win',$Agent)&&eregi('nt5\.0',$Agent)){
$os="Windows2000";
}
elseif(eregi('win',$Agent)&&eregi('nt',$Agent)){
$os="WindowsNT";
}
elseif(eregi('win',$Agent)&&eregi('nt5\.1',$Agent)){
$os="WindowsXP";
}
elseif(eregi('win',$Agent)&&ereg('32',$Agent)){
$os="Windows32";
}
elseif(eregi('linux',$Agent)){
$os="Linux";
}
elseif(eregi('unix',$Agent)){
$os="Unix";
}
elseif(eregi('sun',$Agent)&&eregi('os',$Agent)){
$os="SunOS";
}
elseif(eregi('ibm',$Agent)&&eregi('os',$Agent)){
$os="IBMOS/2";
}
elseif(eregi('Mac',$Agent)&&eregi('PC',$Agent)){
$os="Macintosh";
}
elseif(eregi('PowerPC',$Agent)){
$os="PowerPC";
}
elseif(eregi('AIX',$Agent)){
$os="AIX";
}
elseif(eregi('HPUX',$Agent)){
$os="HPUX";
}
elseif(eregi('NetBSD',$Agent)){
$os="NetBSD";
}
elseif(eregi('BSD',$Agent)){
$os="BSD";
}
elseif(ereg('OSF1',$Agent)){
$os="OSF1";
}
elseif(ereg('IRIX',$Agent)){
$os="IRIX";
}
elseif(eregi('FreeBSD',$Agent)){
$os="FreeBSD";
}
if($os=='')$os="Unknown";
return$os;
}
//調(diào)用方法$os=os_infor();



50. 文件格式類

$mime_types=array(
'gif'=>'image/gif',
'jpg'=>'image/jpeg',
'jpeg'=>'image/jpeg',
'jpe'=>'image/jpeg',
'bmp'=>'image/bmp',
'png'=>'image/png',
'tif'=>'image/tiff',
'tiff'=>'image/tiff',
'pict'=>'image/x-pict',
'pic'=>'image/x-pict',
'pct'=>'image/x-pict',
'tif'=>'image/tiff',
'tiff'=>'image/tiff',
'psd'=>'image/x-photoshop',
  
'swf'=>'application/x-shockwave-flash',
'js'=>'application/x-javascript',
'pdf'=>'application/pdf',
'ps'=>'application/postscript',
'eps'=>'application/postscript',
'ai'=>'application/postscript',
'wmf'=>'application/x-msmetafile',
  
'css'=>'text/css',
'htm'=>'text/html',
'html'=>'text/html',
'txt'=>'text/plain',
'xml'=>'text/xml',
'wml'=>'text/wml',
'wbmp'=>'image/vnd.wap.wbmp',
  
'mid'=>'audio/midi',
'wav'=>'audio/wav',
'mp3'=>'audio/mpeg',
'mp2'=>'audio/mpeg',
  
'avi'=>'video/x-msvideo',
'mpeg'=>'video/mpeg',
'mpg'=>'video/mpeg',
'qt'=>'video/quicktime',
'mov'=>'video/quicktime',
  
'lha'=>'application/x-lha',
'lzh'=>'application/x-lha',
'z'=>'application/x-compress',
'gtar'=>'application/x-gtar',
'gz'=>'application/x-gzip',
'gzip'=>'application/x-gzip',
'tgz'=>'application/x-gzip',
'tar'=>'application/x-tar',
'bz2'=>'application/bzip2',
'zip'=>'application/zip',
'arj'=>'application/x-arj',
'rar'=>'application/x-rar-compressed',
  
'hqx'=>'application/mac-binhex40',
'sit'=>'application/x-stuffit',
'bin'=>'application/x-macbinary',
  
'uu'=>'text/x-uuencode',
'uue'=>'text/x-uuencode',
  
'latex'=>'application/x-latex',
'ltx'=>'application/x-latex',
'tcl'=>'application/x-tcl',
  
'pgp'=>'application/pgp',
'asc'=>'application/pgp',
'exe'=>'application/x-msdownload',
'doc'=>'application/msword',
'rtf'=>'application/rtf',
'xls'=>'application/vnd.ms-excel',
'ppt'=>'application/vnd.ms-powerpoint',
'mdb'=>'application/x-msaccess',
'wri'=>'application/x-mswrite',
);
5、php生成excel文檔
<?
header("Content-type:application/vnd.ms-excel");
header("Content-Disposition:filename=test.xls");
echo"test1\t";
echo"test2\t\n";
echo"test1\t";
echo"test2\t\n";
echo"test1\t";
echo"test2\t\n";
echo"test1\t";
echo"test2\t\n";
echo"test1\t";
echo"test2\t\n";
echo"test1\t";
echo"test2\t\n";
?>

//改動相應(yīng)文件頭就可以輸出.doc.xls等文件格式了 

以上就是本文的全部內(nèi)容,大家結(jié)合前一篇進行深入學習,一定會有所收獲。

相關(guān)文章

最新評論