rfc:debugging_pdo_prepared_statement_emulation
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:debugging_pdo_prepared_statement_emulation [2016/10/26 15:56] – expanded introduction adambaratz | rfc:debugging_pdo_prepared_statement_emulation [2016/11/16 23:03] – fix formatting around discussion links adambaratz | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Debugging PDO Prepared Statement Emulation ====== | ====== PHP RFC: Debugging PDO Prepared Statement Emulation ====== | ||
- | * Version: 0.2 | + | * Version: 0.4 |
* Date: 2016-10-17 | * Date: 2016-10-17 | ||
* Author: Adam Baratz adambaratz@php.net | * Author: Adam Baratz adambaratz@php.net | ||
- | * Status: | + | * Status: |
* First Published at: https:// | * First Published at: https:// | ||
Line 14: | Line 14: | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | 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 '' | + | 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 '' |
- | + | ||
- | ==== Consistency Between Prepared Statement Emulation And PDO:: | + | |
- | The piece of functionality that usually needs to be debugged is how values are escaped. There is already a method, '' | + | |
<code php> | <code php> | ||
- | $db = new PDO(...); | + | /* Execute a prepared statement by binding PHP variables */ |
+ | $calories | ||
+ | $colour = ' | ||
- | $stmt = $db->query(' | + | $sth = $dbh->prepare(' |
- | $stmt->bindValue(': | + | FROM fruit |
- | $stmt->execute(); // => SELECT 1 | + | WHERE calories < ? AND colour = ?'); |
+ | $sth->bindParam(1, $calories, PDO:: | ||
+ | $sth->bindValue(2, $colour, PDO:: | ||
+ | $sth->execute(); | ||
- | $stmt = $db->query(' | + | $sth->debugDumpParams(); |
- | $stmt-> | + | |
- | </ | + | |
- | I say typically, because the behavior of PDO:: | + | /* |
- | Currently, the prepared statement emulator escapes values like [[https:// | + | Output: |
- | * Bool, int, and null values are handled within the emulator. | + | |
- | * Other values have their zvals cast to a string, which is passed to the driver' | + | |
- | This logic could be moved to a common PDO C API, which '' | + | SQL: [82] SELECT name, colour, calories |
+ | FROM fruit | ||
+ | WHERE calories < ? AND colour = ? | ||
+ | Parsed SQL: [88] SELECT name, colour, calories | ||
+ | FROM fruit | ||
+ | WHERE calories < 150 AND colour = 'red' | ||
+ | Params: 2 | ||
+ | Key: Position #0: | ||
+ | paramno=0 | ||
+ | name=[0] "" | ||
+ | is_param=1 | ||
+ | param_type=1 | ||
+ | Key: Position #1: | ||
+ | paramno=1 | ||
+ | name=[0] "" | ||
+ | is_param=1 | ||
+ | param_type=2 | ||
- | This approach doesn' | + | */ |
- | + | ||
- | ==== PDO:: | + | |
- | Since prepared statements are only mandatory for pdo_dblib, a driver-specific attribute could produce the parsed query: | + | |
- | + | ||
- | <code php> | + | |
- | $db = new PDO(...); | + | |
- | + | ||
- | // works with statements without bound values | + | |
- | $stmt = $db-> | + | |
- | var_dump($stmt-> | + | |
- | + | ||
- | $stmt = $db-> | + | |
- | $stmt-> | + | |
- | + | ||
- | // returns unparsed query before execution | + | |
- | var_dump($stmt-> | + | |
- | + | ||
- | // returns parsed query after execution | + | |
- | $stmt-> | + | |
- | var_dump($stmt-> | + | |
</ | </ | ||
- | Since this would be a debug tool, the attribute shouldn' | + | The "Parsed SQL" |
- | + | ||
- | This is a slightly awkward use of an attribute -- the existing debug hook, '' | + | |
- | + | ||
- | ==== PDOStatement:: | + | |
- | Similar to the above, but as an API addition: | + | |
- | + | ||
- | <code php> | + | |
- | $db = new PDO(...); | + | |
- | + | ||
- | // works with statements without bound values | + | |
- | $stmt = $db-> | + | |
- | var_dump($stmt-> | + | |
- | + | ||
- | $stmt = $db-> | + | |
- | $stmt-> | + | |
- | + | ||
- | // returns unparsed query before execution | + | |
- | var_dump($stmt-> | + | |
- | + | ||
- | // returns parsed query after execution | + | |
- | $stmt-> | + | |
- | var_dump($stmt-> | + | |
- | </ | + | |
- | + | ||
- | This feels like the least disruptive solution to this problem. If more guardrails are desired, an error could be raised via '' | + | |
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | The first proposal could introduce functionality changes, but they would be in the interest of more consistent behavior across PDO. | + | N/A |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
Next PHP 7.x. | Next PHP 7.x. | ||
- | |||
- | ===== RFC Impact ===== | ||
- | The second proposal would introduce a new constant. | ||
===== Future Scope ===== | ===== Future Scope ===== | ||
- | It's been suggested that PDO shouldn' | + | It's been suggested that PDO shouldn' |
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
This project requires a 50%+1 majority. | This project requires a 50%+1 majority. | ||
- | ===== Patches and Tests ===== | + | <doodle title=" |
- | A working implementation, | + | * Yes |
- | + | * No | |
- | If one of the other proposals is accepted, I could do the implementation myself. | + | </ |
===== References ===== | ===== References ===== | ||
- | Initial discussion of this proposal on the internals mailing list: http:// | + | Initial discussion of this proposal on the internals mailing list: |
+ | * http:// | ||
+ | * http:// | ||
+ | * http:// |
rfc/debugging_pdo_prepared_statement_emulation.txt · Last modified: 2018/03/01 23:27 by carusogabriel