2009-11-11 53 views
-1

很難解釋這種情況,但請參閱示例。PHP中的數據庫和麪向對象實踐

我編寫了一個網頁加載頁面,我初始化一個數據庫類。我將這個類作爲函數參數發送給需要訪問數據庫的任何函數。

我知道這是不好的方法,但目前我不知道如何以任何其他方式做到這一點。你能幫我麼。

class sms { 

    function log_sms($message, $db) { 

     $sql = "INSERT INTO `smslog` SET 
      `mesasge` = '$message' 
      "; 
     $db->query($sql); 

     if ($db->result) 
      return true; 
     return false; 
    } 

} 

然後在主網頁上..

$db = new db(username,pass,localhost,dbname); 

$sms = new sms; 

$sms->log_sms($message, $db); 

有沒有比這更好的辦法?

回答

8

有選項數目如何解決依賴性問題(對象A需要對象B):

構造注射

class Sms { 
     function __construct($db) .... 
    } 

    $sms = new Sms (new MyDbClass); 

setter注入

class Sms { 
     protected $db; 
    } 
    $sms = new Sms; 
    $sms->db = new MyDbClass; 

'的註冊表' 圖案

class Registry { 
    static function get_db() { 
      return new MyDbClass; 
}} 

class Sms { 
     function doSomething() { 
      $db = Registry::get_db(); 
      $db->.... 
    }} 

「服務定位器」模式

class Loader { 
    function get_db() { 
      return new MyDbClass; 
}} 

class Sms { 
     function __construct($loader) { 
     $this->loader = $loader; 

     function doSomething() { 
      $db = $this->loader->get_db(); 
      $db->.... 
    }} 

    $sms = new Sms(new Loader); 

自動化的基於容器的依賴注入,例如參見http://www.sitepoint.com/blogs/2009/05/11/bucket-is-a-minimal-dependency-injection-container-for-php

interface DataSource {...} 
    class MyDb implements DataSource {...} 

    class Sms { 
     function __construct(DataSource $ds) .... 


    $di = new Dependecy_Container; 
    $di->register('DataSource', 'MyDb'); 
    $sms = $di->get('Sms');  

僅舉幾例)

也是福勒的文章中,我之前給你真的很值得一讀

+0

你有每個處理時間的線索嗎?哪個更快,哪個更慢?或者,如果沒有太大的區別,那麼構造函數對我來說看起來最簡單:) – 2009-11-11 17:50:50

+0

哦,很好的概述。謝謝:) – Svish 2009-11-11 17:57:41

+0

你我理解'Registry'和'ServiceLocator'模式的不同。對我而言,您的註冊表看起來像一個ServiceLocator(知道如何實例化對象的註冊表),並且您的ServiceLocator看起來很像...一個ServiceLocator,通過組合實現到另一個類中。這裏沒有任何東西看起來像註冊表。 – 2009-11-11 18:11:03

2

對於初學者,您可以在每個需要使用數據庫的類中創建受保護的$ db變量。然後,您可以將$ db傳遞給類構造函數。下面是更新後的代碼:

$db = new db(username,pass,localhost,dbname); 
$sms = new sms($db); 
$sms->log_sms($message); 

class sms { 

    protected $db; 

    public function __construct($db) { 
     $this->db = $db; 
    } 

    public function log_sms($message) { 
     $sql = "INSERT INTO `smslog` SET 
       `mesasge` = '$message' 
       "; 
     $this->db->query($sql); 

     if ($this->db->result) 
       return true; 
     return false; 
    } 
} 

這個例子是在PHP 5

+0

靜態調用這是最好的方式?我有近14個類,所以我應該爲每個類添加一個構造函數? P.S這是一個社交網站 – 2009-11-11 17:17:40

+1

沒有最好的辦法。 cballou給出的方法當然是一種好方法。爲了知道它是否是您14個班級的好方法,我們需要知道它們是什麼。在任何情況下,如果你有像log($ msg,$ db)那樣的14個類的方法,那麼你將需要傳遞$ db對象多次(可能甚至更多),比你在作爲構造函數傳遞時要多論據。 – koen 2009-11-11 17:24:14

+0

是的14班我的意思是我有14個更多的類需要使用數據庫類(如配置文件,usersettings,專輯,視頻,認證,消息,網絡,推介,更新等),是的我提供數據庫在每個方法的論點。 我使用$ db作爲參數和大約50個或更多這樣的方法我相信。如果有更好的方法,我不介意更改完整的代碼,因爲有很多東西要添加到網站中。 – 2009-11-11 17:30:13

0

你既可以有一個具有兩個列表,可用連接的一個靜態類,其他的交給了聯繫,只是有一個連接池。或者,如果您正在使用具有快速連接時間的內容(例如MySQL),那麼只需在您的數據庫類中創建連接,執行該功能所需的所有查詢,然後關閉它。這是我首選的方法。

+0

即時通訊只使用1個連接,以節省資源,因爲該網站是在共享服務器上lol – 2009-11-11 17:23:12

+0

那麼爲什麼不只是排隊查詢,處理它們,並將結果傳遞給回調,打包,否則當遇到問題時會遇到問題兩個線程嘗試使用相同的連接。 – 2009-11-11 17:35:47

+0

我不能這樣做,因爲我爲每個函數編寫了一個類,例如一個用於驗證用戶的類,一個用於獲取用戶詳細信息,一個用於讀取用戶收件箱等等,並且它們使用主$ db類。它在索引文件之上初始化並且方法被一個接一個地處理 每個方法都有查詢來只提取所需的東西並返回一個數組。 HTML像MVC一樣在模板頁面上呈現。所以第二個查詢只在第一個查詢之後執行。 但是我討厭在每個函數中添加$ db,並且我有一個感覺,如果它讓事情變得緩慢 – 2009-11-11 17:47:29

1

辛格爾頓在應用程序設計中也是很好的實踐。它們對於避免在一次調用中重複查詢或計算非常有用。將數據庫對象傳遞給每個方法或構造函數不是一個好主意,而是使用Singleton。

擴展你的數據庫,或者在你的數據庫類中插入靜態方法。(我也分貝的構造方法中調用的配置)

class database extends db 
{ 
    public static function instance() 
    { 
     static $object; 

     if(!isset($object)) 
     { 
      global $config; 

      $object = new db($config['username'],$config['pass'],$config['localhost'],['dbname']); 
     } 

     return $object; 
    } 
} 

讓你的方法靜態

class sms { 

    public static function log($message) { 

     $sql = "INSERT INTO `smslog` SET `mesasge` = '$message'"; 

     database::instance()->query($sql); 

     return (bool) database::instance()->result; 
    } 
} 

您需要登錄短信下一次,只是做這樣

sms::log($message);