示例应用程序,具有员工信息并由不同的应用程序(如工资单和pos)访问。我将员工数据放在一个数据库,工资单数据和pos各自的数据库中。
我有一个如下所示的数据库连接类,所以每次我想获得与数据库的连接时,我只需$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;
}
}
?>
答案 0 :(得分:1)
不要经常创建新对象。发生的事情是,每当您请求另一种数据库类型时,您都是通过new关键字重新创建它(尽管很难确认,但没有看到使用它的代码)。
$ _ instance是一个静态成员,因此在更改数据库类型时会不断覆盖它。那个问题是$ db_type
虽然这对你正在做的事情来说太过分了(为什么每个数据库只有两个变量?),你可以尝试更多这样的事情:
<?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];
}
}
?>
注意:语法可能已关闭。只是想展示模式。
答案 1 :(得分:1)
采用这种设计。如果更改数据库,则会破坏与先前数据库的连接。
为每个连接创建单独的对象,然后在连接对象之间切换。
此外,出于同样的原因,这不是线程安全的。如果多个函数同时发生这种情况,可以在完成加载之前断开另一个函数。
你真的应该为每个函数创建一个新的连接对象,而不是在函数或其他对象之间共享它。
答案 2 :(得分:1)
我不明白为什么除了不断切换连接之外,这会让事情变慢。我在这里唯一建议的是允许多个连接而不是切换它们:
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');
使用这样的东西,你实际上可以一次管理多个打开的连接,并且它们是延迟加载的 - 这意味着你实际上不会实例化PDO连接,直到你用Database::getConnection
请求它同样你可以注入额外的DSN和凭证随时可用。就个人而言,我会将表单配置加载到类中,而不是使用常量int类对其进行硬编码。那么你可以这样:
// gives us an array
$config = Config::load('path/to/db/config.yml');
Database::loadConnections($config);
答案 3 :(得分:0)
如何更改它以使用延迟加载。您无需连接承包商的数据库。仅在首次需要数据库时才连接。这样,如果页面只使用其中一个连接,则不需要等待其他数据库。
答案 4 :(得分:0)
检查DB_HOST和DB_HOST_2的值。以前我发现MySQL使用“127.0.0.1”连接速度极慢,但使用“localhost”立即连接。
这取决于您的服务器的设置方式,但只是认为它可能会有所帮助。