From c1533ea2ebf4e712383616312dc4b260aa3b3d95 Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 13:19:43 +0200 Subject: [PATCH 1/4] Add last_query_error property to mysqli for query error tracking --- ext/mysqli/mysqli.c | 3 +++ ext/mysqli/mysqli_nonapi.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index a8a75eff70863..0d063e624e8cd 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -535,6 +535,9 @@ PHP_MINIT_FUNCTION(mysqli) mysqlnd_reverse_api_register_api(&mysqli_reverse_api); + /* Declare 'last_query_error' property to store last failed query */ + zend_declare_property_null(mysqli_link_class_entry, "last_query_error", sizeof("last_query_error")-1, ZEND_ACC_PUBLIC); + return SUCCESS; } /* }}} */ diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index e0e14eeccbc92..4e210a32eafc7 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -603,6 +603,8 @@ PHP_FUNCTION(mysqli_query) if (resultmode & MYSQLI_ASYNC) { if (mysqli_async_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + /* Save failed query string to 'last_query_error' */ + zend_update_property_string(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "last_query_error", sizeof("last_query_error")-1, query); RETURN_FALSE; } mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC; @@ -611,6 +613,8 @@ PHP_FUNCTION(mysqli_query) if (mysql_real_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + /* Save failed query string to 'last_query_error' */ + zend_update_property_string(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "last_query_error", sizeof("last_query_error")-1, query); RETURN_FALSE; } From 84f457e5f5e7576606c74be7ffd6b314f75052a8 Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 13:35:57 +0200 Subject: [PATCH 2/4] Add patch: last_query_error property to mysqli to store failed query --- mysqli_last_query_error.patch | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 mysqli_last_query_error.patch diff --git a/mysqli_last_query_error.patch b/mysqli_last_query_error.patch new file mode 100644 index 0000000000000..e9f1b122a6327 --- /dev/null +++ b/mysqli_last_query_error.patch @@ -0,0 +1,50 @@ +From c1533ea2ebf4e712383616312dc4b260aa3b3d95 Mon Sep 17 00:00:00 2001 +From: dome +Date: Sun, 1 Jun 2025 13:19:43 +0200 +Subject: [PATCH] Add last_query_error property to mysqli for query error + tracking + +--- + ext/mysqli/mysqli.c | 3 +++ + ext/mysqli/mysqli_nonapi.c | 4 ++++ + 2 files changed, 7 insertions(+) + +diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c +index a8a75eff70..0d063e624e 100644 +--- a/ext/mysqli/mysqli.c ++++ b/ext/mysqli/mysqli.c +@@ -535,6 +535,9 @@ PHP_MINIT_FUNCTION(mysqli) + + mysqlnd_reverse_api_register_api(&mysqli_reverse_api); + ++ /* Declare 'last_query_error' property to store last failed query */ ++ zend_declare_property_null(mysqli_link_class_entry, "last_query_error", sizeof("last_query_error")-1, ZEND_ACC_PUBLIC); ++ + return SUCCESS; + } + /* }}} */ +diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c +index e0e14eeccb..4e210a32ea 100644 +--- a/ext/mysqli/mysqli_nonapi.c ++++ b/ext/mysqli/mysqli_nonapi.c +@@ -603,6 +603,8 @@ PHP_FUNCTION(mysqli_query) + if (resultmode & MYSQLI_ASYNC) { + if (mysqli_async_query(mysql->mysql, query, query_len)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); ++ /* Save failed query string to 'last_query_error' */ ++ zend_update_property_string(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "last_query_error", sizeof("last_query_error")-1, query); + RETURN_FALSE; + } + mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC; +@@ -611,6 +613,8 @@ PHP_FUNCTION(mysqli_query) + + if (mysql_real_query(mysql->mysql, query, query_len)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); ++ /* Save failed query string to 'last_query_error' */ ++ zend_update_property_string(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "last_query_error", sizeof("last_query_error")-1, query); + RETURN_FALSE; + } + +-- +2.43.0 + From 96765f23bc07df90dedc6e5a5d7c0955546ca993 Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 13:43:23 +0200 Subject: [PATCH 3/4] Add .phpt test for last_query_error property on failed mysqli queries --- tests/mysqli/last_query_error.phpt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/mysqli/last_query_error.phpt diff --git a/tests/mysqli/last_query_error.phpt b/tests/mysqli/last_query_error.phpt new file mode 100644 index 0000000000000..16bad958e446f --- /dev/null +++ b/tests/mysqli/last_query_error.phpt @@ -0,0 +1,13 @@ +--TEST-- +Test last_query_error property on failed query +--FILE-- +query("SELECT * FROM unknown_table"); +} catch(mysqli_sql_exception $e) { + echo $mysqli->last_query_error; +} +--EXPECT-- +Test passed +?> From 7ffffbf1aee118e15afd20c5900cf2188031372c Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 16:16:25 +0200 Subject: [PATCH 4/4] rimozione last_query_error.phpt --- tests/mysqli/last_query_error.phpt | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 tests/mysqli/last_query_error.phpt diff --git a/tests/mysqli/last_query_error.phpt b/tests/mysqli/last_query_error.phpt deleted file mode 100644 index 16bad958e446f..0000000000000 --- a/tests/mysqli/last_query_error.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Test last_query_error property on failed query ---FILE-- -query("SELECT * FROM unknown_table"); -} catch(mysqli_sql_exception $e) { - echo $mysqli->last_query_error; -} ---EXPECT-- -Test passed -?>