2009-08-17 58 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]; 

}