PHP & PDO - 有啥方法可以建立“安全”的持久连接吗?

Posted

技术标签:

【中文标题】PHP & PDO - 有啥方法可以建立“安全”的持久连接吗?【英文标题】:PHP & PDO - is there any method to make 'safe' persistent connections?PHP & PDO - 有什么方法可以建立“安全”的持久连接吗? 【发布时间】:2012-12-14 10:44:37 【问题描述】:

我知道(通过阅读 SO 和其他网站上的无数帖子)持久连接并不是绝大多数开发人员非常喜欢的东西(如果脚本突然终止,连接没有关闭,你可能会结束离开一些表被锁定等)但真的那么糟糕吗?

在我的开发机器(T3400 双核 CPU、4 GB RAM 和 5400RPM 硬盘)上,页面加载时间非常不同,具体取决于我使用的是持久性还是非持久性连接。非持久连接的 2.09 秒与持久连接的(大约)68 毫秒非常不同。以下是两个示例屏幕截图供您查看:non-persistent 与 persistent。

我了解持久连接的风险(我并没有真正每天使用它们,虽然我觉得这个概念很有趣并且我想探索它),但是没有任何方法可以检测到非关闭连接?

例如,类似于 mysqli 的 change_user 但对于 PDO 或某种 php 脚本,服务器作为 cron 作业每 X 秒运行一次以检查剩余物并随后关闭它们?我正在阅读有关register_shutdown_function 的信息,但是,如果我理解正确,它会在脚本完成后被调用,因此在实践中,这可能意味着每次脚本完成时它都会结束关闭我的持久连接。还是我错了?

编辑

为了准确起见,我忘了提及我的软件堆栈,所以让我来弥补一下。我当前的堆栈由以下元素组成:Windows 7 (x86) SP1 作为操作系统、Apache 2.4.3PHP 5.4.9(我总是使用最新版本)和MySQL 5.5.28。以localhost 的身份运行堆栈(我可能正在将其迁移到专用机器上,但目前它仍然是这样)。

【问题讨论】:

我觉得奇怪的是,在本地机器上建立 MySQL 连接的成本是 2 秒。这里有些可疑,您确定是持久性与非持久性导致性能发生如此剧烈的变化吗?使用持久连接可能无法解决问题,问题仍然存在,我会追捕罪魁祸首,而不是使用具有潜在危险的东西来纠正问题。 抱歉,就像我刚刚评论了@hek2mgl 的回答一样,我正在创建两个持久连接。一个用于核心应用程序数据库(我想在其中存储客户的账单信息和一些东西),一个用于客户端数据库(所有应用程序模块都将存储它们的数据,如报价单、订单、发票、交货单等)在)。我的实际代码测试看起来像$sql['core'] = $database->addConnection("core"); $sql['client'] = $database->addConnection("client");。因此,这两秒钟。每个连接一秒钟。 1 秒还是太多了。在没有负载且有足够可用 RAM 的机器上,数据库连接的时间不应超过几毫秒。 即使是非持久连接? 是的,太多了。在一台远不及你的机器上建立一个数据库连接实际上需要不到 10 毫秒。这里的罪魁祸首可能不是 MySQL 或 PDO。此外,由于您正在保存敏感的财务数据 - 只需忘记持久连接,这两个永远不应该在同一个句子中使用,更不用说思考了。 【参考方案1】:

为避免每次关机时连接都会关闭,您可以在关机功能中检查error_get_last()

请注意,error_get_last() 也会返回“错误”,例如 E_NOTICE 等。应根据您的需要将其过滤掉。

<?php

register_shutdown_function('shutdown');

function shutdown() 

    static $ignore = array (
        E_STRICT,
        E_NOTICE,
        E_USER_NOTICE,
        E_DEPRECATED,
        E_USER_DEPRECATED, // ...
    );

    $error = error_get_last();
    // if no error has been queued or it should be ignored ...
    if(is_null($error) || in_array($error['type'], $ignore)) 
        return; // do nothing
    

    // here comes your connection close code
    connection_close($your_connection);

但这是一个非常老套的解决方案,有很多限制see www.php.net。

我想知道,因为在使用非永久连接时服务页面需要大约 2 秒。这真的意味着建立与数据库服务器的连接需要大约 2 秒吗?如果是这样,我会注意这个,因为它看起来很长。您使用什么数据库服务器?数据库服务器是否位于不同的机器上?

【讨论】:

抱歉,我需要更具体一点。这 2 秒来自我两次调用我的 addConnection 方法(我正在创建两个持久连接),所以每个连接大约需要 1 秒。 好的,但我确认上面 N.B. 的评论。在您的硬件上建立连接应该不超过 10 毫秒。 它是 Windows 具有极其糟糕的地址解析(指定 127.0.0.1 而不是 'localhost' 缓解了我的缓慢问题)和使用真正的解决方案:使用 Linux 之间的组合。现在连接时间在 11 到 21 毫秒之间。现在这很正常:P

以上是关于PHP & PDO - 有啥方法可以建立“安全”的持久连接吗?的主要内容,如果未能解决你的问题,请参考以下文章

PHP & Sessions:有啥方法可以禁用 PHP 会话锁定?

php? PDO 或 mySQLi [重复]

通过 PDO 将 & 号插入 SQL 表

PHP,PDO,表单,更新用户类不按预期工作

如何在 Windows 开发环境中在 PHP 中使用 PDO 和 MSSQL?

php pdo操作数据库的方法