From fa8049c5b6b72a26ce32a9f2d04bb42ddb17696b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Jacobs?= Date: Fri, 7 Feb 2025 20:05:01 +0100 Subject: [PATCH] Fix warning on null query parameter (#722) * Check if hljs has language (#699) * Fix PHP 8 warning in `TracedStatement::getSqlWithParameters()` when null was bound Since PHP 8.0, [built-in functions like `strtr()` will emit a warning when passing `null` to required string parameters](docs): ``` strtr(): Passing null to parameter #1 ($string) of type string is deprecated ``` This can happen when e.g. binding `PDO::PARAM_NULL` to your query. [docs]: https://www.php.net/manual/en/migration81.deprecated.php#migration81.deprecated.core.null-not-nullable-internal --------- Co-authored-by: Barry vd. Heuvel --- .../DataCollector/PDO/TracedStatement.php | 9 ++++-- tests/DebugBar/Tests/TracedStatementTest.php | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/DebugBar/DataCollector/PDO/TracedStatement.php b/src/DebugBar/DataCollector/PDO/TracedStatement.php index 0a78fa6..5912499 100644 --- a/src/DebugBar/DataCollector/PDO/TracedStatement.php +++ b/src/DebugBar/DataCollector/PDO/TracedStatement.php @@ -114,9 +114,12 @@ class TracedStatement foreach ($this->parameters as $k => $v) { - $backRefSafeV = strtr($v, $cleanBackRefCharMap); - - $v = "$quoteLeft$backRefSafeV$quoteRight"; + if (null === $v) { + $v = 'NULL'; + } else { + $backRefSafeV = strtr($v, $cleanBackRefCharMap); + $v = "$quoteLeft$backRefSafeV$quoteRight"; + } if (is_numeric($k)) { $marker = "\?"; diff --git a/tests/DebugBar/Tests/TracedStatementTest.php b/tests/DebugBar/Tests/TracedStatementTest.php index 89b3b42..0e0171d 100644 --- a/tests/DebugBar/Tests/TracedStatementTest.php +++ b/tests/DebugBar/Tests/TracedStatementTest.php @@ -119,6 +119,37 @@ class TracedStatementTest extends DebugBarTestCase $this->assertEquals($expected, $result); } + /** + * Check if literal `NULL` query parameters are replaced without triggering a deprecation warning since PHP 8.0.0. + * This can happen when e.g. binding `PDO::PARAM_NULL` to your prepared statement. + * + * @link https://www.php.net/manual/en/migration81.deprecated.php#migration81.deprecated.core.null-not-nullable-internal + */ + public function testReplacementParamsContainingLiteralNullValueGeneratesCorrectString() + { + $sql = 'UPDATE user SET login_failed_reason = :nullable_reason WHERE id = :id'; + + $params = [ + 'id' => 1234, + 'nullable_reason' => 'Life happens', + ]; + + $traced = new TracedStatement($sql, $params); + $expected = 'UPDATE user SET login_failed_reason = "Life happens" WHERE id = "1234"'; + $result = $traced->getSqlWithParams('"'); + $this->assertEquals($expected, $result); + + $params = [ + 'id' => 1234, + 'nullable_reason' => null, + ]; + + $traced = new TracedStatement($sql, $params); + $expected = 'UPDATE user SET login_failed_reason = NULL WHERE id = "1234"'; + $result = $traced->getSqlWithParams('"'); + $this->assertEquals($expected, $result); + } + /** * Check if query parameters are being replaced in the correct way * @bugFix Before fix it : select *