php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #62065 PDO should have a disconnect method
Submitted: 2012-05-18 20:26 UTC Modified: 2017-10-24 03:25 UTC
Votes:61
Avg. Score:4.4 ± 0.9
Reproduced:50 of 53 (94.3%)
Same Version:22 (44.0%)
Same OS:32 (64.0%)
From: b12 at bsdpower dot com Assigned: willfitch (profile)
Status: Assigned Package: PDO related
PHP Version: 5.3.13 OS: Any
Private report: No CVE-ID: None
 [2012-05-18 20:26 UTC] b12 at bsdpower dot com
Description:
------------
Currently the advertised way of having pdo disconnect from the database is to assign "null" to the pdo handle.

This may work acceptably well in tutorials, however in real life this approach is impractical.

When testing with, say, phpunit (dbunit), the setup code creates a connection and gives a pdo instance to phpunit. What phpunit subsequently does with that instance and in particular how many times the pdo variable is copied and assigned to cyclical and/or permanently referenced structures, is not something that connection management code can control.

Example code from phpbb: https://github.com/phpbb/phpbb3/blob/develop/tests/test_framework/phpbb_database_test_connection_manager.php#L38 - connect function is called by phpunit.

Currently in phpbb tests the database connections are not closed by pdo. This requires for example postgresql and oracle databases to be configured to allow more concurrent database connections than we have tests in the test suite.

You might be tempted to say that it's phpunit's fault for not closing database connections, or there is a bug in phpbb test code which results in connections not being closed. Consider how such a bug might be found. If I close a connection when I think it should no longer be used, and subsequently it is used, I will receive an error pointing to the responsible party. How would you diagnose the same bug if there is no way to close a database connection explicitly?

Not to mention that disconnecting from the database is a core operation of any sane db api.

There is no need to change existing behavior of connection closing on finalization. The disconnect method should be in addition to existing functionality.

Expected result:
----------------
PDO should provide a method on connections to disconnect from the database.


Patches

PHP72_Add_PDO_Close.patch (last revision 2018-05-31 09:34 UTC by cato at timeanddate dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-09-13 04:06 UTC] ssufficool@php.net
-Type: Bug +Type: Feature/Change Request
 [2013-02-07 10:35 UTC] ionut dot stan at hostway dot ro
On a billing application the recurring services run on separate and consecutive 
transactions, so in case one fails with error the others are not blocked.

At some point an error did occur (sooner or later it has to happen) - some data 
anomaly caused by some upgrade which didn't consider some scenario, and the 
application throws when it catches it.

The uncommited transaction for the PDO object which will not be commited because 
of some assertion failure (app specific, not PDO related) was deadlocking future 
transactions.

It would be nice if the PDO object could be disconnected *for sure*. The 
variable was already beeing unset before reuse, yet that was not enough.

This doesn't like a big deal, I'm sure it can be done. Even without exception 
mode, a disconnected PDO object can happen (internet drops, MySQL dies, etc.), 
so that is not an argument against implementing a disconnect method.
 [2014-01-10 02:16 UTC] willfitch@php.net
-Assigned To: +Assigned To: willfitch
 [2014-01-10 03:23 UTC] willfitch@php.net
This is really semantics, but I agree.  The current documented approach (http://www.php.net/manual/en/pdo.connections.php) is to set the connection variable to null, which isn't elegant, but in reality, is no different than a method call:

$dbh->close();

vs.

$dbh = null;

Both would achieve the same thing, but one is more attractive than the other.  

I'll look into adding a close/disconnect method and implement on existing drivers.
 [2014-01-10 03:44 UTC] willfitch@php.net
I want to also note that any close/disconnect functionality will not affect persistent connectivity.
 [2014-01-19 00:50 UTC] willfitch@php.net
-Status: Assigned +Status: Closed
 [2014-01-19 00:50 UTC] willfitch@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

This will be available in the next releases of PHP 5
 [2014-01-19 00:51 UTC] willfitch@php.net
-Status: Closed +Status: Assigned
 [2014-01-19 00:51 UTC] willfitch@php.net
Updated wrong ticket.  My apologies.  I am still looking into this.
 [2015-03-11 17:00 UTC] bpolaszek at gmail dot com
Hello,

Actually unset($pdo) or $pdo = null works well as soon as there aren't any PDOStatement object initialized somewhere.

When working on prepared statements, unsetting the PDO instance has the following behaviour :

$pdo = new PDO([...]);
$stmt = $pdo->prepare("SELECT * FROM mytable WHERE mycolumn = :myvalue");
$stmt->bindValue(':myvalue', 'oh hi');
$stmt->execute();
$myvalue = $stmt->fetch(PDO::FETCH_COLUMN);
unset($myvalue); // $myvalue == null
unset($stmt); // $stmt == null
unset($pdo); // $pdo == null
sleep(30); // for 30 seconds, I can see the PDO connection is still alive on my MySql server, despite $pdo is null. This wouldn't happen if I didn't prepare a statement.

Tested on PHP 5.3, PHP 5.4, PHP 5.5.

Do you plan a fix for this ? To avoid hundreds of sleeping connections while parsing big files, PHP should really disconnect from the database when asked to.
 [2016-01-08 09:46 UTC] theunis dot botha1 at gmail dot com
Dear willfitch@php.net

This is the MOST REDICULOUS statement I have ever seen :

"but in reality, is no different than a method call:

$dbh->close();

vs.

$dbh = null;

Both would achieve the same thing, but one is more attractive than the other."

These two statements ARE COMPLETELY DIFFERENT.

$dbh->close() would call into C or C++ or whichever language the WHOLE PDO MESS was written in, allows you to re-use the $dbh object FROM PHP.

$dbh = null simply unsets the object in PHP and relies on the garbage collection mechanism (however it is configured) to do the cleanup for you.

So I DO NOT KNOW in WHICH WORLD some person got the idea of : 'lets provide a connect() function but no disconnect() function'

And $dbh = null IS SIMPLY NOT ELEGANT.

Please stop trying to BS everyone.

Provide a bloody disconnect() function for PDO and stop trying to convince everyone its not needed. IT IS NEEDED. 

Also, PDO persistent connections is the worst IDEA EVER.
 [2016-01-08 13:28 UTC] willfitch@php.net
Hi theunis.botha1@gmail.com.

Thanks for your input.  While I agree the statements aren't the same, the conversation wasn't about the syntax/reuse of the object, but rather closing a connection.  I also agree that a disconnect/close method is ideal while still allowing the reuse of the instance.

I will correct your statement:  'lets provide a connect() function but no disconnect() function'.  There is no connect() method, and the documentation clearly points out the intent of connection handling: http://php.net/manual/en/pdo.connections.php.

Please remember this is an Open Source project and a large scale one at that. We aren't paid to do this, have lives outside of our contributions, and have priorities with the many feature requests/bugs reported on a daily basis. 

If you feel strongly about this, you can definitely checkout the source, make the changes and provide a pull request.

Thanks for bumping this ticket.
 [2016-04-06 21:33 UTC] doug at opendns dot com
Hey there,

I just wanted to add a vote for this feature, and also to note a connection to https://bugs.php.net/bug.php?id=62847, wherein PDOStatement appears to hold onto a reference to the connection when a query error occurs. At that point, setting the connection to null doesn't actually release the connection. In that case it would be great to be able to manually force a disconnect.
 [2016-07-01 08:08 UTC] cmb@php.net
Related to doc bug #69730.
 [2017-10-24 03:25 UTC] kalle@php.net
Will, if this is something you still are intending to work on, then please submit an RFC for it.

On a personal note, I agree with the reporter that this behavior is poor design of PDO
 [2018-05-31 09:39 UTC] cato at timeanddate dot com
Hi,

I've added a patch to this task which provides a forced close() method to the PDO object. The patch was made in the PHP 7.2 branch in Git. I'm not too familiar with PHP internals, so I don't know if this is the right way to go, but I verified that it does close the connection (though I've only tried it on MySQL).

- Cato Auestad
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Oct 03 17:01:26 2024 UTC