首页 文章

PDO中的MySQL数据库连接管理

提问于
浏览
10

我是PHP / MySQL的新手,我正在学习的东西 . 我学到的最新的事情之一是,对于给定的用户名,可以为数据库 Build 最大数量的连接 . 当我第一次开始在Wordpress上构建我的网站时,我使用的是旧的mysql_query()命令 . 我从来没有必要连接到MySQL数据库,因为Wordpress只是通过登录网站保持活动连接 . 当我决定将所有MySQL查询切换到PDO扩展时,我再也无法利用Wordpress的活动连接,并且必须启动自己的数据库连接 . 我是在一个单独的PHP配置文件中完成的,我在每个运行脚本的页面中都包含这个文件 . PHP代码如下所示:

try {
    $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
}
catch(PDOException $e) {  
    echo "Select DB Error: " .$e->getMessage(). "</br>";
}

不幸的是,现在,我不断收到以下错误:

“SQLSTATE [42000] [1203]用户已超过'max_user_connections'活动连接”

基于一些在线研究,我尝试了各种不同的方法来解决这个问题 . 首先,我尝试在每个脚本的末尾将数据库连接设置为null(尽管这应该是PHP PDO的默认值?) . 然后我尝试在每次数据库查询后将每个语句句柄设置为 null (这是一个无望的努力) . 最后,我尝试通过更改配置文件中的以下行来使用持久连接:

$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

这似乎都不起作用,我仍然得到同样的错误 . 该网站准备好后,每天需要能够处理100-200人,输入大量不同的数据 . 即使我可以弄清楚如何利用WordPP的PDO主动连接,这将是一个良好的开端 . 我很感激我能得到的任何帮助 .

更新:

我在我的一个代码中运行 SHOW FULL PROCESSLIST 作为MySQL查询,我的行为非常奇怪 . 这是我脚本的第一部分(不包括 SHOW FULL PROCESSLIST 查询):

<?php

include 'config.php';

if(isset($_POST['submit']))
{
//Get Current User Login
global $current_user;
$current_user = wp_get_current_user();
$ulog = $current_user->user_login;
$tablename_cc = "cc_".$ulog;
$tablename_db = "db_".$ulog;
$tablename_misc = "misc_".$ulog;
$tablename_cash = "cash_".$ulog;

try {
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_cc. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), cc_num TEXT(4), cc_amnt DECIMAL(8,2), cc_app TEXT(20), cc_date VARCHAR(10), cc_time VARCHAR(10))");            
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_db. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), db_num TEXT(20), db_amnt DECIMAL(8,2), db_date VARCHAR(10), db_time VARCHAR(10))");        
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_misc. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), misc_item TEXT(1000), misc_amnt DECIMAL(8,2), misc_date VARCHAR(10), misc_time VARCHAR(10))");       
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_cash. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), cash_amnt DECIMAL(8,2), cash_time VARCHAR(10))");
}
catch(PDOException $e) {  
    echo "Create Tables Error: " .$e->getMessage();
}
} ?>

如果我尝试在if语句之外运行 SHOW PROCESS LIST 查询,我会得到一个结果,表明我有一个活动连接;但是,如果我尝试在if语句中运行 SHOW FULL PROCESSLIST 查询,我会收到超出连接数的错误 . 基于这个结果,我想可能在页面顶部的 include 行可能会导致用户提交表单时出现问题(本质上是尝试连接数据库两次),所以我把它移到了if语句中,但是也没有任何区别 . 我不知道为什么会发生这种情况 .

更新/答案(仍有一些问题):

我弄清楚我的问题是什么 . 完成我的一个脚本后,会出现一个javascript命令来弹出一个窗口,其中另一个脚本将为它们打印出发票 . 第二个脚本还尝试使用配置文件 Build 与数据库的连接 . 用户使用的表单是动态的(他们可以根据需要输入尽可能少的数据集),因此当用户插入少量数据时,PDO查询执行速度非常快,并且之间没有冲突连接数量;但是,如果用户输入大量数据,则需要花费更多的时间,并且服务器可以达到最大连接数 . 问题实际上存在于糟糕的服务器环境和低效查询的组合中(仍在学习PHP) . 在这一点上,我能想到的唯一解决方案是在我的第二个脚本(已经使用3秒睡眠)上进行更长时间的睡眠,让其他脚本赶上,但在某些时候,这将花费太长时间 . 我不确定你们有没有更好的建议?

3 回答

  • 0

    在文件中使用 include_once('config.php')require_once('config.php') 而不是 include 'config.php' 可能是避免重复数据库连接的解决方案 .

  • 1

    如果您有另一个可以为您提供与数据库连接的工具,您可能希望查看实际 Build 的连接数 . 在紧要关头, phpmyadmin 可以做到这一点 .

    通常,您可以看到所有活动查询和连接:

    SHOW PROCESSLIST
    

    如果您在PDO连接例程中犯了错误,则可能正在为您尝试运行的每个查询 Build 连接,而不是在请求期间连接 . 您可能还需要检查每个请求是否未为您创建未正确关闭的大型连接池 . 您可能需要尝试连接选项 .

  • 2

    你需要什么被称为PDO“单身”类 . 这是一个例子:

    http://tonylandis.com/php/php5-pdo-singleton-class/

    它不是最好的例子,因为构造函数需要太多参数 . 只需将$ dsn,..,args硬编码到构造函数即 . _construct()并且您可以在任何使用PDO()的地方使用新的sdb() . 除了课程一次之外,不需要任何包含或要求声明 .

    $ pdo对象作为静态变量存储在类中,因此始终可以访问 .

相关问题