我们在手写mysql连接操作的时候,通常使用mysql_close()来关闭数据库连接操作。但是在现代开发中,框架的普遍使用会让我们忽略底层的包,而大多数框架已经默认使用PDO来进行数据库操作。那么,你知道PDO是如何关闭数据连接的吗?按照官方的说法,为了关闭连接,需要销毁对象以确保删除所有剩余的对它的引用,并且可以为对象变量赋一个NULL值。如果您没有明确地这样做,PHP将在脚本结束时自动关闭连接。$pdo=newPDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test','root','');$pdo=null;官方文档说的很清楚,就是为PDO对象赋值NULL即可。但这真的那么简单吗?实际测试让我们做一个这样的测试。一般情况下,我们打开数据库连接后,不会直接关闭,而是需要进行一些操作。$pdo=newPDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test','root','');$stmt=$pdo->prepare('SELECT*FROMzyblog_test_user');$stmt->execute();$pdo=null;sleep(60);运行上面的代码后,我们在数据库中使用showfullprocesslist;查看连接过程,我们会发现当前连接并没有立即关闭,而是等到60秒后,也就是执行完成后才会关闭页面。似乎$pdo=null;这句话没有执行成功。其实官方文档中已经对这种情况进行了说明,只是大家可能没有太在意而已。【需要销毁该对象以确保删除所有剩余的对它的引用】,上述代码中\$stmt预编译SQL语句的函数调用了$pdo对象中的方法,它们之间存在引用依赖关系,本例直接赋值$pdo=null;没有效果,我们还需要将null分配给$stmt。$pdo=newPDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test','root','');$stmt=$pdo->prepare('SELECT*FROMzyblog_test_user');$stmt->execute();$stmt=null;$pdo=null;sleep(60);mysqlitest然后使用mysqli默认的扩展组件,即在mysqli对象中使用close()关闭数据库连接将有这个问题吗?或者直接用代码测试测试。(mysql扩展已经过时,不推荐,如果想封装数据库操作类或者写个小demo,还是用mysqli好)$conn=newmysqli('127.0.0.1','root','','blog_test');$result=$conn->query('SELECT*FROMzyblog_test_user');$stmt=$conn->prepare("SELECT*FROMzyblog_test_user");$stmt->execute();$conn->close();sleep(60);运行上面的代码后,我们在查看数据库中的连接过程时,是看不到还在执行的连接的,也就是说调用了里面的close()方法mysqli可以直接立即关闭与数据库的连接。小结其实今天的内容也是官方文档中关于数据库连接的一个Note里面的信息。有高手很早就发现了这个问题并分享出来,但是大部分人根本不知道,很多人甚至不知道PDO也可以关闭数据库连接。框架在给我们带来方便的同时,也确实把很多东西封装的很好,以至于很多朋友并不关心一些底层的内容。但是,当你走向更高层次的时候,这些底层的东西往往会成为你的阻碍。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PHP%E4%B8%ADPDO%E5%85%B3%E9%97%AD%E8%BF%9E%E6%8E%A5%E7%9A%84%E9%97%AE%E9%A2%98.php参考文档:https://www.php.net/manual/zh/pdo.connections.phphttps://www.php.net/manual/zh/pdo.connections.php#114822各媒体平台均可搜索【硬核项目经理】
