2012-05-02 96 views
1

我對PDO和OOP都很新穎。我試圖編寫一個連接到數據庫的類並更新插入並修改它。我有幾個問題:PHP PDO類構造

  1. 在構造函數中連接數據庫的好習慣?

  2. 一個類應該更新,插入,修改和連接,還是應該分成幾個類?

  3. 爲什麼runQuery不起作用?我認爲它是因爲$ pdo是在不同的範圍內定義的。我將如何得到這個工作?

  4. 如果該類包含在每個頁面的頂部,那麼這意味着每次加載新頁面時都會重新連接到數據庫,並且會導致安全問題?

對於問題超載的道歉。預先感謝任何答案。

<?php 
class Login{ 

private $_username; 
private $_password; 
private $_host; 
private $_database; 
private $_driver; 

//Connect to the database 

function __construct($configFile){ 

    $connectionDetails = parse_ini_file($configFile); 

    $this->_username = $connectionDetails['username']; 
    $this->_password = $connectionDetails['password']; 
    $this->_host = $connectionDetails['host']; 
    $this->_database = $connectionDetails['database']; 
    $this->_driver = $connectionDetails['driver']; 

    $pdo = new PDO("$this->_driver:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 

} 

public function loginAllowed($user, $pw){ 

    $sth = $pdo->setFetchMode(PDO::FETCH_ASSOC); 
    print_r($sth); 
} 

public function runQuery($query, $params){ 
    $sth = $this->pdo->prepare($query); 
    $sth->execute($params); 
} 
} 

回答

7

因爲$pdo是在構造函數中的局部變量和你的方法loginAllowed。你應該把它作爲一個實例變量(private $pdo),所以你可以通過$this->pdo來調用它。我也建議在這裏使用type hinting,在構造函數中給PDO作爲參數。

<?php 
class Login { 
    private $pdo; 
    // Your other instance variables 

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

    // Your other methods 
} 

$pdo = new PDO("..."); 
$login = new Login($pdo); 

你不應該閱讀設置打擾你的類和初始化數據庫連接(絕對了解separation of concerns),保持它的類。只需將PDO對象作爲參數(我使用type hinting,這樣您就可以提供PDO類型的對象)。另一個好處是,你現在可以確保你只有一個活動的數據庫連接(你可以在你的代碼庫中進行管理),創建多個連接是不必要的,而且絕對不需要(性能明智)。

還使用require_once來包含您的類定義。否則,你會得到很多關於重新聲明的錯誤(並且你想避免這種錯誤)。

+0

感謝您的真棒答案即時通訊將您的所有建議付諸實踐。當我通過$ pdo對象時,我遇到了類型提示的一個小問題(出現這種情況),出現以下錯誤: _Catchable致命錯誤:傳遞給Login :: __ construct()的參數1必須是PDO實例,字符串給定_ 我已經使用gettype來確保變量im傳遞實際上是一個對象。我很困惑..... – Shane

+0

你給一個字符串作爲參數。你必須做的是在你的類之外創建一個PDO實例,並將這個實例作爲參數。 (類型提示是非常強大的,因爲你現在可以強制參數是一個類型(只在這個時候纔有類)。) – Styxxy

+0

我這樣做:$ pdo = new PDO(「$ driver:host = $ host; dbname = $ database「,$ username,$ password);'(在類之外),那麼這個'$ login = new Login($ pdo);'當我嘗試打印變量時,我傳遞($ pdo)這:PDO類的_Object無法轉換爲string_ – Shane

1
  1. 連接到你發現最方便的地方。試着確保只有一個連接。更多的連接到相同的數據庫是浪費時間和資源。

  2. 您引用的類在MVC體系結構中稱爲模型。它通常執行給定表格上的所有操作。只要代碼具有可讀性和可維護性,我認爲在爲所有需求使用單個類時都沒有錯。

  3. 這不起作用,因爲$pdo是一個局部變量。在ctor中,改爲實例化$this->pdo

  4. 包括一個類不等於實例化它。一個新的實例將會建立另一個連接。多次包括它只會給你一個多重聲明錯誤:)。改爲使用require_once。如果你希望在多個文件中使用實例,我強烈建議你快速搜索Singleton模式。使用單例對象將確保您始終只有一個模型對象的實例。

0

1)在構造函數中連接數據庫的好習慣?

否good.just連接befor查詢

if($this->pdo == null) { 
$this->pdo = new PDO("...."); 

}

2)如果所述一個類是更新,插入,修改和連接或是否應該分成幾類? 添加方法

3)爲什麼runQuery不起作用?我認爲它是因爲$ pdo是在不同的範圍內定義的。我將如何得到這個工作? 使用$ this-> pdo代替

4)如果類是包含在每個頁面的頂部,這是否意味着每次加載新頁面時都會重新連接到數據庫並導致安全問題? 使用靜態$ PDO 然後自我:: $ PDO將是唯一一個連接器

if(self::$pdo == null) { 
self::$pdo = new PDO("...."); 

}

1

不要所有的隨機的東西打擾,只是replacethis在你的構造:

$pdo = new PDO("$this->_driver:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 

$this->pdo = new PDO("$this->_driver:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 

和參考我t從現在開始$ this-> pdo。就如此容易!!