Hello PHP,
I am writing per the RFC guidelines and requesting initial feedback, as I
am considering an RFC to add a PDO::disconnect method as well as to improve
handling (or removal?) of persistent connections during PDO object creation
and deletion.
Should the RFC go forward, I would propose to implement any changes. I have
submitted a preliminary pull request where some discussion has occurred,
and an implementation proof-of-concept relayed.
The following is the rationale provided in the pull request for a
disconnect method.
Current recommendations in PDO application integration avoid the need for
an explicit disconnect routine and workaround the [below] described issues
through prescribed use of a single PDO object instance for any given
database connection, and which database connection is terminated upon
either PDO object destruct or, in the case of persistent connections, at
the end of script execution. While the use of a singleton object for
database connection handling within applications is a common implementation
pattern, the tight integration of database disconnect behavior with PHP's
object free hook has imposed a need to further manage PDO object references
within an application in order to reliably replace and/or shutdown a db
connection instance, an effort which scales with application complexity.
This reality is further complicated by the PDO statement object, which also
holds a reference to a PDO object and thus must also be managed from a
reference standpoint, as well as by PHP itself, which governs the time at
which an object free hook is invoked, subject to influence by bug or design.
That latter point about PHP's imperfect invocation of the object free hook
may raise eyebrows, but it is actually the precursor to this project for
me. I recently tripped over a confluence of factors involving persistent
PDO connections, exceptions, and xdebug, in which a PDO object's free hook
is not being invoked upon removal of all object references and instead
occurs at an inopportune time during use of a subsequent PDO object, also
prompting an undesirable transaction rollback on the shared inner database
connection. I can provide more detail here, and/or an example to reproduce,
but I'm not sure it's desirable, given the involvement of xdebug and the
development mode that implies. Rather, it is a case in point to promote a
preference for an explicit interface governing PDO end-of-life behavior,
putting more control in users' hands.
A disconnect method has been suggested before, and several times at that
(see below references), but I have not found an RFC for it.
- https://marc.info/?l=php-internals&m=145338688709155
- [contd.] https://marc.info/?l=php-internals&m=145346982831131
- https://bugs.php.net/bug.php?id=62065
- https://bugs.php.net/bug.php?id=67473
- https://bugs.php.net/bug.php?id=40681
As for persistent PDO connections, I understand the feature is much
disliked, which I suspect is owing to the memory constraints it places on
PDO extensions that have not been perfectly abided by. In the above pull
request, I am smoothing over a couple rough edges (see:
https://bugs.php.net/bug.php?id=63343), but testing reveals there are more.
Perhaps the better service I can be here is to propose the removal of this
feature altogether? The added complexity of the feature seems to outweigh
the benefits, which as best I can gather, is primarily to allow for ad-hoc
PDO object creation. If that is truly all it brings in benefit, this is a
use case easily supported by the user via singleton.
From what I have seen of PDO implementation, persistent connection behavior
is based upon the "PERSISTENT" constructor attribute and the internal sense
variable "is_persistent", such that this feature is rather auxiliary and
may be easily culled. The "is_persistent" PDO struct member could remain
for the foreseeable future, to allow PDO extensions more grace in their own
removal of feature support.
It may be that these ideas would warrant two RFCs, but I'll leave it at
that for now and await further feedback.
Thank you,
Robert Wolf
The added complexity of the feature seems to outweigh the benefits, which
as best I can gather, is primarily to allow for ad-hoc PDO object creation.
If that is truly all it brings in benefit, this is a use case easily
supported by the user via singleton.
The primary benefit and use case is for slow network connections between
PHP and MySQL. Persistent connection helps avoid the overhead involved in
creating and authorizing a new connection on the server.
The main disadvantage is the confusion it brings to an average user who has
to be aware of many pitfalls that come with reusable connections.
Persistent connection helps avoid the overhead involved in creating and
authorizing a new connection on the server.
That only applies if you are creating multiple PDO objects and expecting
re-use of the kept-alive underlying connection, correct?
If persistent connections were removed, it is true that any users utilizing
PDO in this ad-hoc fashion and expecting connection keepalive would be
impacted. Granted, that potential impact may not be tenable, but the
workaround would seem rather straightforward to communicate to users and to
implement - that workaround being for the user to introduce a PDO singleton
to hold the object reference as long as you wish the connection to live for.
Persistent connection helps avoid the overhead involved in creating and
authorizing a new connection on the server.
That only applies if you are creating multiple PDO objects and expecting
re-use of the kept-alive underlying connection, correct?If persistent connections were removed, it is true that any users
utilizing PDO in this ad-hoc fashion and expecting connection keepalive
would be impacted. Granted, that potential impact may not be tenable, but
the workaround would seem rather straightforward to communicate to users
and to implement - that workaround being for the user to introduce a PDO
singleton to hold the object reference as long as you wish the connection
to live for.
No, They are reusable across different http requests. There's no point in
reusing them in the same request.
On the first access to the website a new connection is established. On the
second access the same connection is reused provided the first request is
done with it. This way consecutive requests to the website do not need to
open a new costly connection.
No, They are reusable across different http requests.
Whelp, I have certainly misunderstood this. That considered, it does not
make good sense to propose to remove the feature.
A disconnect method has been suggested before, and several times at that (see below references), but I have not found an RFC for it.
I had filed https://github.com/php/php-src/issues/15749 which was perhaps a
bit more general, but I'm interested in such a proposal. I support users
using PDO w/ persist connections, and occasionally they get wedged.
Unfortunately, there's no recovery possible like there is with the
procedural DB extensions.