【问题标题】:How to connect to two different MySQL DB in the same class如何连接到同一类中的两个不同的 MySQL DB
【发布时间】:2014-12-16 07:13:30
【问题描述】:

我有一个名为 dataBase 的课程。看起来像这样

    class dataBase
    {

        private $conexion;
        private $paisConexion;
        var $db;
        function __construct($db='default')
        {
            $this->db = $db;
            include '../settings/variables.php';

            if(isset($bbdd)){

            $conexion = mysql_connect($bbdd["server"], $pais[0]['user'], $pais[0]['pass']) or die('No se pudo conectar: '.mysql_error());
            // Seleccionamos la base de datos
            mysql_select_db($x[0]['database']) or die('No se pudo seleccionar la base de datos');

            if($conexion)
            {   
            $paisConexion = mysql_connect($bbdd["server"], $pais[$this->db]['user'], $pais[$this->db]['pass']) or die('No se pudo conectar: '.mysql_error());

            mysql_select_db($pais[$this->db]['database']) or die('No se pudo seleccionar la base de datos');

            }


            }
            else{
                echo 'El sistema no se pudo conectar a la base de datos.';
                exit;
            }
        }

public function execute($sql)
    {
        $result = mysql_query($sql) or die("ERROR: Ejecuci&oacute;n de consulta: $sql<br>\n");
        return $result;
    }
}

我正在尝试使用变量 $conexion$paisConexion 与两个不同的数据库建立两个连接。

我的问题是可以做这样的事情。

我的意思是假设我正在为这样的类创建一个对象

$obj = new dataBase(1); $res = obj->execute($sql);

那么类将如何决定它必须使用哪个连接? .

我认为我这样做是错误的。如果有人有任何想法,请告诉我

提前致谢

【问题讨论】:

  • 可能是错字,但首先是dataBase != database
  • @Ghost 是的,这是一个错字,我已修复,抱歉

标签: php mysql class


【解决方案1】:

可以做这样的事情,但是您建议的方法对我来说似乎非常有限,因此我冒昧地使用 PDO 编写替代方案,因为不推荐使用 mysql_* 函数。 Mysql_* functions official documentation here

通过使用 PHP 提供的 PDO 类,您可以获得参数化查询和事务的好处。 PDO documentation here

为了让您以后更容易添加其他连接,我编写了一个包含绝对裸骨的小类。为简单起见,我留下了许多诸如错误处理之类的东西,因为这仅用作演示。

/*
 * DO NOT USE THIS IN PRODUCTION
 */
class DatabaseConnectionManager {

private $connections = [];

public function __construct(array $credentials) {

    foreach($credentials as $identifier => $information) {

        $this->connections[$identifier] = $this->openConnection(
            $information['host'],
            $information['database'],
            $information['username'],
            $information['password']
        );

    }

}

public function __destruct() {

    /* If the object is destroyed before the script closes or is disrupted (fatal errors), we 
     * destroy all database connections as good practice.
     */
    $this->connections = [];

}

public function getConnection($identifier) {

    if(!array_key_exists($identifier, $this->connections)) {
        throw new LogicException('Unknown database connection: ' . $identifier);
    }

    return $this->connections[$identifier];

}

private function openConnection($host, $database, $username, $password) {

    $dsn = "mysql:host{$host};dbname={$database}";

    return new PDO($dsn, $username, $password);

}

}

通过它,您可以提供一系列不同的数据库连接信息。用法如下。

$credentials = [

    'primary' => [
        'host'     => 'localhost',
        'database' => 'number1',
        'username' => 'awesome',
        'password' => 'secret'
    ],

];

$connections = new DatabaseConnectionManager($credentials);

要获得可以执行不同数据库相关任务的连接(PDO 对象),只需使用getConnection() 方法指定连接标识符。

$db = $connections->getConnection('primary');

重要

此代码尚未准备好生产,仅用于演示目的。几乎没有错误检查或错误处理。如果提供的数组所需参数不足,您将收到错误消息。 同时,目前不可能在不硬编码的情况下为 PDO 对象提供选项。

希望这可以帮助您朝着正确的方向前进。

【讨论】:

    【解决方案2】:

    您不能为两个数据库创建一个类。除非您传递一些指定要使用的女巫连接的参数。此外,您必须为不同的连接使用两个不同的变量。并且不要使用已弃用的mysql_* 函数

    class DataBase {
        // only private variables accessed by functions
        private $localDb, $remoteDb;
        // Always use constants instead of magic numbers
        const LOCAL = 1, REMOTE = 2
    
        public function _construct() {
            $this->localDb= new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
            $this->remoteDb= new PDO('mysql:host=remore;dbname=test2', 'username', 'password');
        }
    
        // Can't use constants in function header           - - - - -v
        public function execute($queryString, $params = [], $useDb = 1) {
            // static:: will take variable from this class and not from parent class (if extends something)
            if ($useDb == static::LOCAL) {
                $db = $this->local;
            } elseif ($useDb == static::REMOTE) {
                $db = $this->remote;
            }
    
            $query = $db->prepare($queryString);
    
            // Usage of prepared statement
            return $query->execute($params);
        }
    }
    
    $db = new DataBase();
    $db->execute(
        'SELECT * FROM table WHERE column = :columnVal', // named placeholders instead of tons of '?' 
        [':columnVal' => 5], // some parameters
        DataBase::LOCAL // Constant from class
    );
    

    【讨论】:

    • 你能告诉我函数 prepare() 到底会做什么吗?
    • 我的班级也必须根据传递的参数做出响应。例如,如果我调用 obj=new dataBase(2); 则该类必须加载本地 DB 和与值相关的 DB 2 。如果我通过 3 那么它必须加载与 3 相关的本地数据库和数据库
    【解决方案3】:

    保存到私有字段的连接并在执行中使用它:

    function __construct($db='default')
    {
        ...
        $this->paisConexion = mysql_connect(...
        ...
    }
    
    public function execute($sql)
    {
        $result = mysql_query($sql, $this->paisConexion);
        return $result;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 2022-08-15
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多