【问题标题】:FreeTDS: Properly close a PHP PDO connection, not working correctlyFreeTDS:正确关闭 PHP PDO 连接,无法正常工作
【发布时间】:2014-10-05 16:26:49
【问题描述】:

我有一个旧的 CodeIgniter 实例,正在尝试与 PHP PDO 一起使用。这是基于“cickes”修改(见下面的链接)。它在小请求负载下运行良好,但在重请求负载下连接似乎会挂起很长时间。最终我用完了可用的连接,数据库返回并出现错误:SQLSTATE[] (null) (severity 0)。

https://github.com/cickes/PDOinCodeigniter2

我正在使用带有 PHP PDO 的 MS SQL Server 2008。 MSSQL 的 PHP 驱动程序是 FreeTDS 驱动程序,可以通过 phpinfo() 输出查看。 FreeTDS PHPINFO 如下图所示:

mssql
MSSQL Support   enabled
Active Persistent Links 1
Active Links    1
Library version FreeTDS
Directive   Local Value Master Value
mssql.allow_persistent  On  On
mssql.batchsize 0   0
mssql.charset   no value    no value
mssql.compatability_mode    Off Off
mssql.connect_timeout   5   5
mssql.datetimeconvert   On  On
mssql.max_links Unlimited   Unlimited
mssql.max_persistent    Unlimited   Unlimited
mssql.max_procs Unlimited   Unlimited
mssql.min_error_severity    10  10
mssql.min_message_severity  10  10
mssql.secure_connection Off Off
mssql.textlimit Server default  Server default
mssql.textsize  Server default  Server default
mssql.timeout   60  60

我已将 DB 处理程序设置为 null 以及 unset() DB 处理程序。这两种变化都无济于事。最终我的连接用完了。

我认为我可以尝试在连接期间传递一个属性选项,正如 PHP 网站上所建议的那样。不幸的是,FreeTDS 驱动程序不支持属性。定义的第一个 $DB 正在工作,但我相信它使用持久连接。

$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);

注意:驱动不支持以下属性设置示例。

$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password'], array(
    PDO::ATTR_PERSISTENT => false
));

消息:PDO::__construct(): SQLSTATE[IM001]:驱动程序不支持此功能:驱动程序不支持设置属性

$DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username '], $params['密码']);

PDO::__construct(): SQLSTATE[IM001]: 驱动不支持此功能:驱动不支持设置属性。

也许是持久链接导致了问题?我认为该服务器上还使用了非持久性 mssql_connect() 函数。也许有人可以为 FreeTDS 驱动程序建议更好的配置?

Laravel 测试(2014 年 8 月 14 日添加):

我决定在“同一台服务器”上使用相同的数据库连接设置测试 Laravel。它不会产生同样的问题。我可以连续多次点击它而不会出现“挂起”或数据库错误。那么,这就引出了一个问题:Laravel 做 PHP PDO 的方式有何不同?

【问题讨论】:

  • 您正在尝试连接到示例中的 mysql 数据库
  • @fortune - 啊,这只是 PHP 站点的副本。我会用我的实际代码更正。

标签: php pdo


【解决方案1】:

如果可能,尝试重用连接,不要自己关闭它们(PDO 足够聪明,可以这样做)。

在创建新连接之前检查连接是否为null

if($DB == null){
    $DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);
    $DB->setAttribute(PDO::ATTR_PERSISTENT, false);    
}

否则重用同一个对象。

【讨论】:

  • 不幸的是,当我尝试设置 PDO::ATTR_PERSISTENT 时,驱动程序不支持它。消息:PDO::setAttribute(): SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes.
【解决方案2】:

CodeIgniter 的 Cickles PDO 更改包含我发现的一个错误。 DB 函数被多次调用,因此数据库连接被多次调用 (9)。为了防止这种情况,我首先检查对全局 DB 变量的引用,以确保我没有创建另一个到数据库的连接。我希望这个答案可以帮助其他可能遇到同样问题的人。

参见 Github 项目:

https://github.com/cickes/PDOinCodeigniter2

文件:

https://github.com/cickes/PDOinCodeigniter2/blob/master/system/database/DB.php

if (!empty($GLOBALS['DB'])) $DB = $GLOBALS['DB'];
//var_dump($DB);
//echo "DB Function Called."."<br />";

if (empty($DB)) {

// Using PDO: connect to a database using PDO
try {

    echo "Creating new PDO Connection!";
    $DB = new PDO($params['dbdriver'].':host='.$params['hostname'].'; dbname='.$params['database'], $params['username'], $params['password']);

    if (ENVIRONMENT == 'development') {
        $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } elseif (ENVIRONMENT == 'production') {
        $DB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
    }
    $DB->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
    $DB->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_NATURAL);
    $DB->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
    //$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    $GLOBALS['DB'] = $DB;

} catch(PDOException $e) {

    //print_r($params);
    echo $e->getMessage();
}

}

【讨论】:

    猜你喜欢
    • 2018-04-24
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    相关资源
    最近更新 更多