Php 具有多个数据库的单例
示例应用程序,包含员工信息,并由不同的应用程序(如payroll和pos)访问。我将员工数据放在一个数据库中,payroll数据和pos分别放在单独的数据库中 我有一个如下所示的数据库连接类,所以每次我想要连接到数据库时,我只需执行Php 具有多个数据库的单例,php,singleton,multiple-databases,Php,Singleton,Multiple Databases,示例应用程序,包含员工信息,并由不同的应用程序(如payroll和pos)访问。我将员工数据放在一个数据库中,payroll数据和pos分别放在单独的数据库中 我有一个如下所示的数据库连接类,所以每次我想要连接到数据库时,我只需执行$conn=database::getInstance(db1) 工作很好,但基本上是超慢的。使应用程序运行非常缓慢。关于为什么会这样或更好的替代方案,有什么建议吗 任何帮助都将不胜感激 <?php class Database { pr
$conn=database::getInstance(db1)
工作很好,但基本上是超慢的。使应用程序运行非常缓慢。关于为什么会这样或更好的替代方案,有什么建议吗
任何帮助都将不胜感激
<?php
class Database {
private $db;
static $db_type;
static $_instance;
private function __construct($db){
switch($db) {
case "db1":
try{
$this->db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
}
catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br />";
die();
}
break;
case "db2":
try{
$this->db = new PDO("mysql:host=" . DB_HOST_2 . ";dbname=" . DB_NAME_2, DB_USER_2, DB_PASSWORD_2);
}
catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br />";
die();
}
break;
}
self::$db_type = $db;
}
private function __clone(){}
static function getInstance($db_type){
if(!(self::$_instance) || $db != self::$db_type){
self::$_instance = new self($db_type);
}
return self::$_instance;
}
}
?>
将其更改为同时使用延迟加载怎么样。您不需要连接到承包商中的数据库。仅在第一次需要数据库时连接。这样,如果页面仅使用其中一个连接,则无需等待其他数据库。不要不断创建新对象。所发生的事情是,每次您请求另一个数据库类型时,您都会通过new关键字重新创建它(尽管在没有看到使用此关键字的代码的情况下很难确认)
$\实例是一个静态成员,所以在更改数据库类型时会不断覆盖它。那么$db_类型是否适用于该问题
虽然这对于您正在做的事情来说是多余的(为什么不为每个DB设置两个变量?)
<?php
class Database {
private $db;
static $db_types;
private function __construct($db){
switch($db) {
case "db1":
try{
$db_types[$db] = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
}
catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br />";
die();
}
break;
case "db2":
try{
$db_types[$db] = new PDO("mysql:host=" . DB_HOST_2 . ";dbname=" . DB_NAME_2, DB_USER_2, DB_PASSWORD_2);
}
catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br />";
die();
}
break;
}
}
private function __clone(){}
static function getInstance($db_type){
if(!inarray($db_types[$db_type]){
$db_types[$db_type] = new self($db_type);
}
return $db_types[$db_type];
}
}
?>
使用此设计。如果更改数据库,则会破坏与以前数据库的连接
为每个连接创建单独的对象,然后在连接对象之间切换
此外,出于同样的原因,这不是线程安全的。如果多个函数同时执行此操作,则一个函数可以在完成加载之前断开另一个函数
您确实应该为每个函数创建一个新的连接对象,而不是在函数或其他对象之间共享它。检查DB\u HOST和DB\u HOST\u 2的值。之前,我发现MySQL使用“127.0.0.1”连接速度非常慢,但使用“localhost”立即连接
这取决于服务器的设置方式,但我只是认为这可能会有所帮助。我不明白除了您不断切换连接之外,为什么这会让事情变得缓慢。这里我唯一能建议的是允许多个连接,而不是切换它们:
class Database {
protected static $connections;
protected $activeConnections = array();
protected static $instance;
protected function __construct() {
}
public static loadConnections(array $connections) {
self::$connections = $connections;
}
public function getConnection($name)
{
if(!isset($this->activeConnections[$name]) {
if(!isset(self::$connections[$name]) {
throw new Exception('Connection "' . $name . '" is not configured.');
}
$this->activeConnections[$name] = new PDO(
self::$connections[$name]['dsn'],
self::$connections[$name]['username'],
self::$connections[$name]['password']
);
}
return $this->activeConnections[$name];
}
}
// usage
Database::loadConnections(array(
'db1' => array(
'dsn' => "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
'user' => DB_USER,
'password' => DB_PASSWORD,
),
'db2' => array(
'dsn' => "mysql:host=" . DB_HOST2 . ";dbname=" . DB_NAME2,
'user' => DB_USER2,
'password' => DB_PASSWORD2,
)));
$conn1 = Database::getInstance()->getConnection('db1');
$conn2 = Database::getInstance()->getConnection('db2');
使用类似的方法,您实际上可以一次管理多个打开的连接,并且它们是延迟加载的-这意味着您在使用Database::getConnection
请求PDO连接之前,不会实际实例化PDO连接。同样,您可以随时向其中注入额外的DSN和凭据。就我个人而言,我会将表单配置直接加载到类中,而不是在类中使用常量对其进行硬编码。然后你可以这样做:
// gives us an array
$config = Config::load('path/to/db/config.yml');
Database::loadConnections($config);
连接到数据库不会花费很长时间,我也不认为你的应用程序总体上会“慢”,因为你要连接到不同的数据库。数据库是本地的吗?或者在远程服务器上?数据库都是本地的。我目前使用的是这种方法,加载它需要相当长的时间,相比之下,当我将所有内容都放在一个数据库中时,您可以通过在某些行之前或之后捕获microtime()来帮助找到特定的行,从而减慢速度。如果您能特别将问题隔离到连接到数据库的线路上,则可能会有所帮助。抱歉,不确定您的意思,请您再解释一下。让我尝试一下,然后让您知道。已成功解决此问题,但未解决速度问题。仍然需要相当长的时间来加载。我想可能是其他原因导致了这个问题,但我会尝试prodigitalson的解决方案进行比较,然后我会知道让我尝试一下,并让你知道它是如何运行的,这是否缺少一个静态函数getInstance()?它不是一个完整的类。。。我刚刚概述了与你的不同之处:-)太棒了!将其改为包含对象的数组,效果非常好!供他人参考:静态函数getInstance($db_type=”“){if(!isset(self::$connections[$db_type]){self::$connections[$db_type]=new self($db);}返回self::$connections[$db_type];}
@johnny-man对不起,已经快三年了。我都不记得了,哈哈。我想我在你的评论上面贴了些什么,但说实话,我甚至认不出来!已经有一段时间了。@user1239663不用担心。我忘了怎么回答一些问题。谢谢