2016-10-19 39 views
1

在我的應用程序中,我只使用了一個數據庫,並且創建了類以提供一些常用方法。 現在我需要實現額外的數據庫。從Db類繼承 - 兩個數據庫連接| PHP

因此,我不想創建單獨的Db類來做同樣的事情,我想調用與db相關的參數的Db類。

問題是,當我嘗試使用提供方法到應用程序的類擴展Db類時,數據庫連接未建立 - 它爲空。

Main和User都使用不同的數據庫。

Class Main extends Db; 類用戶擴展Db;

爲什麼這樣的東西不起作用?

class Db { 

    protected $link; 
    private $host; 
    private $user; 
    private $pass; 
    private $dbName; 

    public function __construct($host, $user, $pass, $db) { 
     $this->host = $host; 
     $this->user = $user; 
     $this->pass = $pass; 
     $this->dbName = $db; 
     $this->connect(); 
    } 

public function connect() { 

     try 
     { 

      $this->link = new PDO("mysql:host=" . $this->host . 
        ";dbname=" . $this->dbName . ";charset=utf8mb4", $this->user, $this->pass); 
      $this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
      $this->link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

     } catch (PDOException $exc) 
     { 
      $this->setMessage($exc->getMessage()); 
     } 
    } 
} 
$db = new Db(HOST, USER,PASS,DB) 

class Main extends DB { 

    public function __construct() { 

    } 
    /** App methods bellow*/ 
    } 

$db2 = new Db(HOST2,USER2,PASS2,DB2); 
class User extends DB { 

    public function __construct() { 

    } 
    /** App methods bellow*/ 
    } 

什麼是最簡單的解決方案來實現兩個不同的數據庫連接?

謝謝!

編輯:

更新我的代碼的建議後,我有一個訪問數據庫的連接屬性的問題,所以我不能夠做查詢的主要和用戶類。

讓我困惑的是,爲什麼這個屬性對Main類不可見?

主要類的方法是在數據庫鏈接嚴重依賴,而我不知道如何解決這個問題..

更新代碼:

class Main { 

    protected $db; 

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

public function showFreeSlotsPerPlan() { 

     try 
     { 
      $SQL = "some query"; 

      $stmt = $this->db->prepare($SQL); 
/** Prepared statements bellow **/ 
    } 
    } 

class Db { 

    protected $link; 
    private $host; 
    private $user; 
    private $pass; 
    private $dbName; 

    public function __construct($host, $user, $pass, $db) { 
     $this->host = $host; 
     $this->user = $user; 
     $this->pass = $pass; 
     $this->dbName = $db; 
     $this->connect(); 
    } 
    } 

,把它作爲建議:

$db = new Db(HOST, USER, PASS, DB); 
$main = new Main($db); 

如果我嘗試調用方法fe showFreeSlotsPerPlan()

Fatal error: Call to undefined method Db::prepare() in /var/www/html/Master/class/Main.class.php 

後來,當我調試主的情況下,我得到如下:

Main Object 
(
    [db:protected] => Db Object 
     (
      [link:protected] => PDO Object 
       (
       ) 

      [host:Db:private] => localhost 
      [user:Db:private] => root 
      [pass:Db:private] => password 
      [dbName:Db:private] => dbname 
     ) 

) 

EDIT2: 解決方法是增加prepare方法將DB.php,我是能夠成功地執行查詢。

儘管如此,我仍然不確定這是否是最好的答案。我承認我的設計是不擅長所有:(

public function prepare($sqlQuery) { 
    return $this->link->prepare($sqlQuery); 
} 
+1

爲什麼您的'Main'和'User'類會從'DB'擴展?爲什麼不把'DB'對象作爲參數傳遞給構造函數並將其作爲屬性存儲?當然,你不能說你的用戶是數據庫,你能嗎? –

+1

在子類中使用'public function __construct()'意味着將使用這個構造函數(它什麼都不做)。 –

+0

如果我不使用一個空的構造函數,我得到以下內容: 'Db :: __ construct()缺少參數1,在344行調用/var/www/html/Master/class/User.php並且在第19行中定義在/var/www/html/Master/class/DB.php上 3個參數的其餘部分相同 在344行上,我有一個User類的實例化對象: $ user = new User(); – fugitive

回答

1

@u_mulder描述你所面對的正確技術問題。父Db構造不會自動從一個孩子構造方法調用。你可以嘗試來解決這個問題通過顯式調用父類的構造:

class Main extends DB 
{ 

    public function __construct() 
    { 
     parent::__construct(); 
    } 
    // ... 
} 

的問題是,你的父母(DB)需要的參數給它的構造函數,所以你也必須把它們放到你的孩子:

class Main extends DB 
{ 

    public function __construct($host, $user, $pass, $db) 
    { 
     parent::__construct($host, $user, $pass, $db); 
    } 
    // ... 
} 

但是這沒有意義。你最大的問題是設計。相反,你應該favor composition of objects over inheritance,特別是在這種情況下。嘗試重組你的班級:

class Main 
{ 
    protected $db; 

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

$mainDb = new Db(HOST, USER,PASS,DB) 
$main = new Main($mainDb); 

併爲User類做同樣的事情。當你這樣做時,你的protected $link屬性將不再在你的Main類中可見。這是好的,因爲,真的,你的MainUser類別不應該具有該屬性的可見性,因爲什麼是具有Db類的點,無論如何?您可以通過在Db課程中添加一些公開方法(例如public function query($sql, $parameters))來解決此問題,然後從您的MainUser課程中調用該方法。

一旦你得到這個工作,我建議你看看Active Record Pattern,或者看看廢棄你的方法,有利於合併已經可用的許多open source ORMs之一。

+0

非常感謝@Jeff Lambert爲您的想法和方法!我會嘗試應用這個。 再次感謝! – fugitive

+0

@MilosM沒問題,很樂意幫忙。 –