Skip to content

Conversation

@jnoordsij
Copy link

As a follow-up to #547, this PR aims to implement a full-fledged set of polyfills for the driver specific PDO subclasses introduced in PHP 8.4; see also https://wiki.php.net/rfc/pdo_driver_specific_subclasses.

As of PHP 8.5, the driver specific constants and methods available on the base PDO class will be deprecated, to be removed in PHP 9.0. See also https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_driver_specific_pdo_constants_and_methods.

This PR adds a polyfill to use the driver-specific child classes for PHP versions prior to PHP 8.4. This in turn allows one to already refer to the 'new' constant, to prevent deprecation errors on PHP 8.5, while retaining backwards compatibility. This can be particularly useful for code requiring support for multiple versions; see e.g. laravel/framework#57141.

The classes should be suitable for constructing on older PHP versions.

Note the PDO::connect static method that has been introduced simultaneously has not been polyfilled, as I can't think of a proper way to do such a thing currently.

@jnoordsij jnoordsij marked this pull request as draft October 16, 2025 12:51
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add the static connect method to every child class, since we can polyfill it there?
How does this method behave when given a DSN for another driver and when it's called on a child class?

@jnoordsij jnoordsij force-pushed the add-pdo-subdriver-constant-polyfill branch from 325af09 to f0b0b10 Compare October 16, 2025 12:57
@jnoordsij
Copy link
Author

Should we add the static connect method to every child class, since we can polyfill it there? How does this method behave when given a DSN for another driver and when it's called on a child class?

We could, but that feels a bit off to me. The whole idea of the PDO::connect static method is that it is able to detect the type of driver and thus subclass to use from the provided dsn, making it generic. Calling e.g. \Pdo\Mysqlite::connect(...) instead of just new \Pdo\Mysqlite(...) makes little sense to me, and probably should not be something to actively encourage in any userland code?

@nicolas-grekas
Copy link
Member

About the connect method on child classes, I'd still add it, for completness of the polyfill

@jnoordsij jnoordsij force-pushed the add-pdo-subdriver-constant-polyfill branch from 97852db to 8034458 Compare October 16, 2025 13:48
@jnoordsij
Copy link
Author

I probably will look into the last bits next week; if anyone is eager to finalize on the connect method or think of additional tests to throw in here, feel free to add them.

@derrabus
Copy link
Member

derrabus commented Oct 16, 2025

Calling e.g. \Pdo\Mysqlite::connect(...) instead of just new \Pdo\Mysqlite(...) makes little sense to me, and probably should not be something to actively encourage in any userland code?

But if you are on PHP 8.4, would you really call the constructor of those subclasses instead of PDO::connect()? So either way, we're encouraging userland code that is different with the polyfill than with the real thing, mainly because we cannot polyfill PDO::connect(). 😕

@jnoordsij jnoordsij force-pushed the add-pdo-subdriver-constant-polyfill branch from 8034458 to a89fdfe Compare October 20, 2025 08:58
@jnoordsij
Copy link
Author

jnoordsij commented Oct 20, 2025

But if you are on PHP 8.4, would you really call the constructor of those subclasses instead of PDO::connect()? So either way, we're encouraging userland code that is different with the polyfill than with the real thing, mainly because we cannot polyfill PDO::connect(). 😕

To be fair, if one is currently only using something like new PDO("sqlite:foo");, then migrating towards new Pdo\Sqlite("sqlite:foo"); does not seem like a weird strategy to me. In particular for projects were the driver class is already predetermined and you want to have the added benefit of stricter types for static analysis, one could prefer this over PDO::connect which will from a static point of view only ever return PDO. However I do agree that the main usecase would still be to used PDO::connect, which unfortunately is not something we can provide.

@jnoordsij jnoordsij marked this pull request as ready for review October 20, 2025 09:10
@jnoordsij jnoordsij force-pushed the add-pdo-subdriver-constant-polyfill branch from ecd99c0 to f42017a Compare October 20, 2025 09:16
@jnoordsij
Copy link
Author

I think this should be complete now as is. Additional feature-like tests could be nice, but on the other hand are probably very hard to implement in practice without any real database and I think the current set should suffice to prove this should work in practice. In particular the migration towards 'polyfilled' constants should be very safe to do with this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants