2008-11-13 24 views
8

我正在開發面向對象的PHP網站,並試圖確定從系統其餘部分抽象數據庫功能的最佳方式。現在,我有一個DB類來管理系統使用的所有連接和查詢(它幾乎是MDB2的一個接口)。但是,在使用這個系統時,我意識到我的代碼中隨處可見很多SQL查詢字符串。例如,在我的用戶類中,我有這樣的東西:從數據庫功能中分離代碼

function checkLogin($email,$password,$remember=false){ 
    $password = $this->__encrypt($password); 
    $query = "SELECT uid FROM Users WHERE email=? AND pw=?"; 

    $result = $this->db->q($query,array($email,$password)); 

    if(sizeof($result) == 1){ 
     $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); 
     $uid = $row['uid']; 
    }else{ 
     return false; 
    } 

    /* Rest of the login script */ 
} 

我想要做的是找出減少內聯SQL的最佳技術。我明白,一種方法是在User中爲每個用戶使用的查詢編寫函數(如下所示),但這可能會導致相當多的函數。

function checkLogin($email,$password,$remember=false){ 
    $password = $this->__encrypt($password); 
    $uid = $this->do_verify_login_query($email,$password); 

    /* Rest of the login script */ 
} 

function do_verify_login_query($email,$encpw){ 
    $query = "SELECT uid FROM Users WHERE email=? AND pw=?"; 
    $result = $this->$db->q($query,array($email,$encpw)); 

    if(sizeof($result) == 1){ 
     $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC); 
     return $row['uid']; 
    }else{ 
     return false; 
    } 
} 

所以......我的問題。管理典型數據庫應用程序使用的大量查詢的最佳技術是什麼?我描述的方式是否是處理這種情況的正確方法?或者,在DB類中註冊一個查詢列表,並將每個傳遞到DB查詢函數的唯一ID(例如USER_CHECKLOGIN)關聯起來呢?這種方法也可以有助於安全性,因爲它會限制只能在列表中註冊的查詢,但在編寫所有類功能時還需要記住一點。思考?

回答

7

把SQL分解成單獨的函數是一個體面的開始。您可以執行的其他操作:

  • 爲數據庫訪問代碼創建單獨的類。這將有助於確保您的所有PHP文件中都沒有SQL函數。
  • 從外部文件加載SQL。這完全分離了你的SQL代碼和你的PHP代碼,使兩者更易於維護。
  • 儘可能使用存儲過程。這將完全從您的PHP代碼中刪除SQL,並通過降低外部SQL執行的風險來幫助提高數據庫安全性。
+0

存儲過程是否需要內聯SQL語句才能執行它們,因爲它們只存在於數據庫中?或者當我說使用存儲過程時,我不明白你的意思嗎? – cmptrgeekken 2008-11-13 03:52:14

+0

MySQL實際上只是添加了存儲過程,而且我讀過的語法並不像在SQL Server中那樣靈活。海事組織,存儲過程是真正無用的,除非你需要編寫一個廣泛或複雜的查詢。 – Kevin 2008-11-13 04:03:10

4

您可能想要考慮實施ActiveRecord Pattern。使用諸如此類的設計模式,可以在處理來自表格的數據方面提供一致性。這些方法可能存在一些缺點,主要表現爲某些類型的查詢,但可以解決。

4

另一個選擇可能是使用ORM的,PHP最強大的是:

都允許您使用一組對象的訪問數據庫,爲存儲和查詢數據提供了一個簡單的API,它們都有自己的查詢語言,它們在內部被轉換爲目標DBMS原生SQL,這將簡化將應用程序從一個RDBMS遷移到另一個RDBMS的簡單配置。 nges。我也喜歡這樣一個事實,即可以封裝數據模型邏輯來添加驗證,例如只通過擴展模型類。

3

既然你說你正在做OO PHP,那你爲什麼要把SQL分散到所有的方法中呢?更常見的模型是:

  1. 使用ORM並讓它處理數據庫。
  2. 爲您的類提供一個或多個使用單個查詢的「加載」方法將所有對象的數據拖入內存,以及使用單個查詢更新數據庫中的所有內容的「save」方法。所有其他方法只需要進行內存中操作,數據庫交互僅限於加載/保存方法。

第一個選項通常會更健壯,但第二個選項可能會運行得更快,並且與您習慣做事的方式相比,可能會更加熟悉,如果其中任何一個都是擔憂的話。

您的登錄例如,我會做到這一點的話,會是簡單地通過電子郵件地址加載用戶,呼叫$user->check_password($entered_password),並拋出一個異常/返回false /如果check_password失敗什麼的。 check_password和任何登錄處理代碼都不需要關注數據庫,或者甚至不知道數據庫是用戶從哪裏加載的。

0

另一種選擇是將查詢視爲數據並將它們存儲在數據庫中。例如,您可以創建一個存儲帶查詢名稱的查詢表和存儲該查詢參數的另一個表。然後在PHP中創建一個函數,該函數使用查詢的名稱和一個參數數組並執行查詢,返回任何結果。您還可以將其他元數據附加到查詢以限制對某些用戶的訪問,對結果應用後期功能等。