This is an old revision of the document!
PHP RFC: Debugging PDO Prepared Statement Emulation
- Version: 0.4
- Date: 2016-10-17
- Author: Adam Baratz firstname.lastname@example.org
- Status: In Discussion
- First Published at: https://wiki.php.net/rfc/debugging_pdo_prepared_statement_emulation
PDO is built on the concept of prepared statements. It expects individual database drivers to manage statement execution, but also allows prepared statements to be emulated. Emulation means that the pdo extension, using no third-party code, generates a query string for literal execution by the driver. It identifies parameters within the statement string and interpolates escaped values. You must use separate logging or tracing tools to debug this process.
If you're a PHP developer, this can add time to the development process. Depending on the environment, you may not have access to these tools. This can make it difficult to use the pdo_dblib driver, since the DB-Library API doesn't support prepared statements. The pdo_mysql and pdo_pgsql drivers offer the option to emulate. In the case of pdo_mysql, it's enabled by default. I've seen many developers write ad hoc parsers in userland as a workaround.
If you're a PHP internals developer, this prevents you from writing good .phpt tests against pdo_sql_parser.re. Without being able to inspect the raw query string, you can only test the effects of the queries it generates. For example, you might want to verify an int is quoted as 1 and not '1'. A database might cast the string to an int, doing the right thing with it, but obscuring that to the developer.
People who use emulated prepared statements should be able to debug them within userland, without using additional tools. PDO already provides some debug functionality in the form of
PDOStatement::debugDumpParams(). This method would be extended to include the parsed query string:
/* Execute a prepared statement by binding PHP variables */ $calories = 150; $colour = 'red'; $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ? AND colour = ?'); $sth->bindParam(1, $calories, PDO::PARAM_INT); $sth->bindValue(2, $colour, PDO::PARAM_STR); $sth->execute(); $sth->debugDumpParams(); /* Output: SQL:  SELECT name, colour, calories FROM fruit WHERE calories < ? AND colour = ? Parsed SQL:  SELECT name, colour, calories FROM fruit WHERE calories < 150 AND colour = 'red' Params: 2 Key: Position #0: paramno=0 name= "" is_param=1 param_type=1 Key: Position #1: paramno=1 name= "" is_param=1 param_type=2 */
The “Parsed SQL” section will only be shown if the prepared statement emulation is enabled.
Backward Incompatible Changes
Proposed PHP Version(s)
Next PHP 7.x.
It's been suggested that PDO shouldn't allow prepare statement emulation. This new functionality would only engage if emulation is enabled, so it will self-destruct if emulation is dropped.
Proposed Voting Choices
This project requires a 50%+1 majority.
Initial discussion of this proposal on the internals mailing list: http://marc.info/?l=php-internals&m=147638162506291&w=2 http://marc.info/?l=php-internals&m=147734024403899&w=2 http://marc.info/?l=php-internals&m=147673258418764&w=2