我知道(通过阅读SO和其他网站上的无数帖子)持久连接并不是绝大多数开发人员非常喜欢的东西(如果脚本突然终止,连接不会关闭,你可能会结束离开一些桌子被锁定等等)但它真的那么糟糕吗?
在我的开发机器上(T3400双核CPU,4 GB RAM和5400RPM硬盘),页面加载时间非常不同取决于我是使用持久性还是非持久性连接。与持久连接的非持久性与(大约)68ms的2.09s非常不同。以下是两个示例屏幕截图供您查看:non-persistent与persistent。
我理解持续连接的风险(我实际上并不是每天使用它们,虽然我觉得这个概念很有意思,我想探索它),但是没有任何方法可以检测到非关闭连接?
例如,等同于mysqli的change_user
,但对于PDO或某种PHP脚本,服务器每X秒运行一次作为cron作业来检查剩余时间,然后关闭它们?我正在阅读register_shutdown_function
但是,如果我理解正确,它会在脚本完成后调用,所以在实践中,这可能意味着每次脚本完成时它都会结束我的持久连接。或者我错了吗?
修改
为了准确起见,我忘了提及我的软件堆栈,所以让我修改一下。我当前的堆栈由以下元素组成:Windows 7 (x86) SP1
作为操作系统,Apache 2.4.3
,PHP 5.4.9
(我总是使用最新版本)和MySQL 5.5.28
。将堆栈作为localhost
运行(我可能正在将其迁移到专用计算机,但是现在,它仍然是这样的。)
答案 0 :(得分:2)
为避免在每次关机时关闭连接,您可以在关机功能中检查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秒?如果是这样,我会照顾它,因为它似乎很长。你使用什么数据库服务器?数据库服务器是否位于不同的计算机上?