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

Fif*_*ion 14 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);
?>
Run Code Online (Sandbox Code Playgroud)

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

<?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;
?>
Run Code Online (Sandbox Code Playgroud)

这就是我当时正在使用的 - 它工作得很好 - 但总有办法改进.

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

  • 你上课了吗?
  • 你的类包含什么(只是连接甚至函数?)
  • 你推荐什么做法?

Iva*_*uev 9

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


zom*_*bat 5

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

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

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

$db = DatabaseManager::getDatabase();
Run Code Online (Sandbox Code Playgroud)

这是我为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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Sha*_*10N 3

使用类是提高定制可重用性的方法。

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

该网站采用以下干净方法。
该网站链接不再存在。存档链接

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);
    }
}
Run Code Online (Sandbox Code Playgroud)