你如何在PHP中管理数据库连接?

时间:2009-10-16 22:28:35

标签: php oop database-connection connection-pooling

所以最近我真的开始积极地使用php了,我需要一些关于使用数据库连接的不同方法的见解。

刚开始我只使用了简单的mysql_connect():

<?php
    $connection = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die(mysql_error());
    mysql_select_db(DB_DB, $connection);
?>

过了一段时间,我创建了一个数据库类,我开始在每个文件中包含并初始化 - 如下所示:

<?php
class MySQL_DB {

var $connection;

function MySQL_DB(){
    $this->connection = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die(mysql_error());
    mysql_select_db(DB_DB, $this->connection);
}

function query($q){
    $res = mysql_query($q, $this->connection) or die(mysql_error());
    return $res;
}
}

$database = New MySQL_DB;
?>

这就是我当时正在使用的 - 它工作正常 - 但总会有改进的方法。

所以我的问题是你如何管理你的数据库连接?

  • 你是否使用课程?
  • 你的课程包含什么(只是 连接甚至功能?)
  • 您推荐什么做法?

4 个答案:

答案 0 :(得分:9)

我建议使用PDO。不要重新发明。它是many database engines的一个很好的OO接口。 另外,我创建了一个小函数,它只是初始化PDO对象。因此,可以在一个地方更改所有连接设置。

答案 1 :(得分:5)

您当前的方法非常标准,效果很好。我用了很久了。确实像PDO这样的模块现在提供这样的基本功能,这也是非常好的,可以让你远离家庭酿造代码的问题。

但是,我已经将连接管理更进了一步。如果进入复杂的应用程序,可能会遇到多个数据库或数据库使用量很大的情况。包含单个数据库连接文件并具有全局$database变量对于多个数据库变得难以处理,并且对于可能不需要数据库连接的应用程序请求不是必需的。请记住,连接数据库非常昂贵。

我所做的是创建一个单独的DatabaseManager类来为我处理数据库对象,并确保不会实例化与给定数据库的多个连接。您可以在每次需要对象时调用DatabaseManager,而不是在应用程序顶部初始化新的数据库对象。

$db = DatabaseManager::getDatabase();

这是我为CodeIgniter项目掀起的一个示例类。您可以在getDatabase()函数中看到它只是加载CodeIgniter的默认数据库对象,如果您不使用CI,则可以替换自己的类(并为其运行连接例程)。这是一个非常简单的管理类,可以扩展到相当容易地管理到不同数据库的多个连接。

<?php

/**
 * Implements the Singleton pattern to prevent multiple instantiations and connections
 * to the application database.
 *
 */
class Database_manager
{
    private static $instance;
    public $db;

    /**
     * Constructor function is declared private to prevent instantiation.
     *
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * Returns an instance of a Database_manager.
     *
     * @return object Database_manager object
     */
    public static function getInstance()
    {
        if (self::$instance == null) {
            $className = __CLASS__;
            self::$instance = new $className();
        }
        return self::$instance;
    }

    public static function getDatabase()
    {
        $instance = self::getInstance();
        if ($instance->db == null) {
            //utilize CodeIgniter's database loader
            $instance->db = $instance->load->database('',true);
            if (! is_object($instance->db)) throw new Exception("Could not load database.");
        }
        return $instance->db;
    }
}

使用这种连接管理方式时,最常见的优势可能是我必须关闭数据库维护应用程序。通过在我需要之前不实例化数据库连接,我可以轻松地在站点上发布“正在进行维护”消息(短路正常的MVC调度),而不用担心在维护时对应用程序打开数据库连接的请求进展。

答案 2 :(得分:3)

使用类是增加自定义可重用性的方法。

将所有通用实现引入该类。你走在正确的轨道上。

This website has the following clean approach .

class connection {
    // Possible Modules are as follows:
    // DBX_MYSQL, DBX_ODBC, DBX_PGSQL, DBX_MSSQL, DBX_FBSQL, DBX_SYBASECT, DBX_OCI8, DBX_SQLITE
    private $module = DBX_MYSQL; 

    private $host = "localhost";
    private $database = "test";
    private $username = "testuser";
    private $password = "testpass";

    private $link;
    private $result;
    public $sql;

    function __construct($database=""){
            if (!empty($database)){ $this->database = $database; }
            $this->link = dbx_connect($this->module,$this->host,$this->database,$this->username,$this->password);
            return $this->link;  // returns false if connection could not be made.
    }

    function query($sql){
            if (!empty($sql)){
                    $this->sql = $sql;
                    $this->result = dbx_query($this->link,$sql,DBX_RESULT_UNBUFFERED);
                    return $this->result;
            }else{
                    return false;
            }
    }

    function fetch($result=""){
            if (empty($result)){ $result = $this->result; }
            return dbx_fetch_row($result);
    }

    function __destruct(){
            dbx_close($this->link);
    }
}

答案 3 :(得分:0)

在数据库管理器示例中,您没有为您的类定义父级。 因此,调用parent :: __ constructor()会产生异常, 而且,你不能使用代码ignitor的load属性。

您使用哪个类作为DatabaseManager的扩展?

由于我不知道你在哪里放置了数据库管理器代码,也没有知道你用作父类的类,我通过使getDatabase()方法接收一个我称为$ loader的输入参数来规避异常。 通常,此$ loader对象将是需要访问数据库的模型类。

public static function getDatabase($loader)   
{  
    $instance = self::getInstance();  
    if ($instance->db == null) {  
            //utilize CodeIgniter's database loader  
            $instance->db = $loader->load->database('default',true);  
            if (! is_object($instance->db)) throw new Exception("Could not load database.");  
    }  
    return $instance->db;  
}  

最好的问候。