2009-08-17 55 views
2

我一直在嘗試使OOP PHP5代碼。但我認爲我的嘗試很笨拙。這些是我的問題:OOP php5結構

  • 他們是一個更好,更精簡的方式來包含數據庫配置信息?
  • 我可以以某種方式避免在每個函數中聲明$ db = new Db()嗎?
  • 我應該使用PEAR作爲數據庫抽象層而不是Mysqli_database.php嗎?

Mysqli_database.php

<?php 
class Db { 
    private $connection; 

    private function open_connection() { 
     if (file_exists('config.inc.php')) { 
      require('config.inc.php'); 
     } else { 
      require('../config.inc.php'); 
     } 
     try 
     { 
      $this->connection = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname); 
     } 
     catch (Exception $e) 
     { 
      throw $e; 
     } 
    } 
    private function close_connection() { 
     try 
     { 
      mysqli_close($this->connection); 
     } 
     catch (Exception $e) 
     { 
      throw $e; 
     } 
    } 
    public function query($query) { 
     try 
     { 
      $this->open_connection(); 
      $result = mysqli_query($this->connection,$query); 
      return $result; 
     } 
     catch (Exception $e) 
     { 
      throw $e; 
     } 
     $this->close_connection(); 
    } 
    public function fetchArray($query) { 
     $row = mysqli_fetch_assoc($query); 
     return $row; 
    } 
    public function count_rows($query) { 
     $row = mysqli_num_rows($query); 
     return $row; 
    } 
    public function rows_affected() { 
     $row = mysqli_affected_rows($this->connection); 
     return $row; 
    } 
    public function created_id() { 
     $row = mysqli_insert_id($this->connection); 
     return $row; 
    } 
} 
?> 

Test_data.php

<?php 
class Test_data { 
    public function show_text() { 
     $db = new Db(); 
     $sql = $db->query("SELECT * FROM test_table"); 
     $row = $db->fetchArray($sql); 
     echo 'This is the output: '.$row['text']; 
    } 
} 
?> 

的config.inc.php

<?php 
$dbname  = 'database_name'; 
$dbhost  = 'localhost'; 
$dbuser  = 'database_user'; 
$dbpass  = 'database_password'; 
?> 

includes.php

<?php 
require_once('config.inc.php'); 
require_once('Mysqli_database.php'); 
$db = new Db(); 
$test_data = new Test_data(); 
?> 

的index.php

<?php 
require_once('includes.php'); 
$test_data->show_text(); 
?> 

回答

3

的配置信息是口味的問題。但是最好將它存儲在一個配置對象中,然後以更多的OO方式進行檢索,然後包含來自另一個文件的全局變量。

您可以通過使用singleton pattern避開創建新對象。

您選擇的抽象層越多,從一個數據庫移動到另一個數據庫越容易。你也可以看看PDO

+0

權,配置信息的保存是一個口味問題,我喜歡使用CONSTANTS,那麼你知道它在全球範圍內不會改變。 – null 2009-08-17 17:29:37

3

建立數據庫連接有一些非常常見的模式:Singleton,Factory和有時註冊表。

下面是人們看起來的樣子。

<?php 

class DbConn 
{ 
    const CONN_DEV_1 = 'dev.db1'; 
    const CONN_PROD_1 = 'prod.db1'; 
    const CONN_DEV_2 = 'dev.db2'; 
    const CONN_PROD_2 = 'prod.db2'; 

    protected static $instances = array(); 

    protected $conn; 

    public static function factory($database, $env) 
    { 
    $connectionName = "$env.$database"; 
    if (!isset(self::$instances[$connectionName])) 
    { 
     switch ($connectionName) 
     { 
     case self::CONN_DEV_1: 
      $dbname = 'dev1'; 
      $dbhost = 'localhost'; 
      $dbuser = 'database_user'; 
      $dbpass = 'database_password'; 
      break; 
     case self::CONN_PROD_1: 
      $dbname = 'prod1'; 
      $dbhost = 'some.server'; 
      $dbuser = 'database_user'; 
      $dbpass = 'database_password'; 
      break; 
     case self::CONN_DEV_2: 
      $dbname = 'dev2'; 
      $dbhost = 'localhost'; 
      $dbuser = 'database_user'; 
      $dbpass = 'database_password'; 
      break; 
     case self::CONN_PROD_2: 
      $dbname = 'prod2'; 
      $dbhost = 'some.server'; 
      $dbuser = 'database_user'; 
      $dbpass = 'database_password'; 
      break; 
     default: 
      throw new Exception('Unrecognized database connection!'); 
     } 
     self::$instances[$connectionName] = new self($dbhost,$dbuser,$dbpass,$dbname); 
    } 
    return self::$instances[$connectionName]; 
    } 

    private function __construct($dbhost, $dbuser, $dbpass, $dbname) 
    { 
    $this->conn = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname); 
    } 

    /* all your other methods here */ 
} 

和使用

$db1 = DbConn::factory('db1', 'dev'); 

顯然,這裏的關鍵是從當前應用程序的配置,只要可能來自拉動值$env

現在在使用方面,一般你想傳遞/ hand函數/類的數據庫連接,而不是讓他們自己負責建立連接。這提供了更鬆散的耦合。要使用你的例子:

<?php 
class Test_data 
{ 
    protected $db; 

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

    public function show_text() 
    { 
     $sql = $this->db->query("SELECT * FROM test_table"); 
     $row = $this->db->fetchArray($sql); 
     echo 'This is the output: '.$row['text']; 
    } 
} 
?> 
2

至於在每個功能捕獲一個實例,像這樣的DB對象是Singleton模式給予事實上的例子。它確實很適合在這裏。

這裏有一個粗略的例子:

class DB 
{ 

    // Private Constructor so external code cannot directly instantiate 
    private function __construct() { 

    } 

    public static function instance() { 
    static $instance = false; 

    if (!$instance) 
     $instance = new DB(); 

    return $instance; 

    } 

} 

和一個小的變化,如果你想有多個數據庫連接開放(到不同的數據庫)將是一個實例方法是這樣的:

public static function instance($dsn) { 
    static $instances = array(); 

    if (!isset($instances[$dsn])) 
     $instances[$dsn] = new DB($dsn); 

    return $instances[$dsn]; 

}