From a0389fafa271082facaabc7310f2c642dff1eb11 Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 13:19:43 +0200 Subject: [PATCH 1/5] 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 caefd9432d14..298f908d868a 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -543,6 +543,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 2e51dca3100f..0e1bce8a677f 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -595,6 +595,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; @@ -603,6 +605,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 e3db92bcb2d1c1eb0d07d8a9f1078627e7abc1ad Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 13:35:57 +0200 Subject: [PATCH 2/5] 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 000000000000..e9f1b122a632 --- /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 4fac139ebe705cf83dd42060e3a83384a1275af9 Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 13:43:23 +0200 Subject: [PATCH 3/5] 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 000000000000..16bad958e446 --- /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 ae0f7b7d3ae5b6331a53c8d8b016dc3979c8ba27 Mon Sep 17 00:00:00 2001 From: dome Date: Sun, 1 Jun 2025 16:16:25 +0200 Subject: [PATCH 4/5] 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 16bad958e446..000000000000 --- 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 -?> From ec807ad571f5f3d6664060a2943de2c91dd42f97 Mon Sep 17 00:00:00 2001 From: dome Date: Tue, 24 Mar 2026 11:35:36 +0100 Subject: [PATCH 5/5] avanzamento --- ext/mysqli/mysqli_nonapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 0e1bce8a677f..2c8d926afb8e 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -594,9 +594,9 @@ 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' */ + /* Save failed query string to 'last_query_error' before reporting error (which may throw) */ zend_update_property_string(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "last_query_error", sizeof("last_query_error")-1, query); + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC; @@ -604,9 +604,9 @@ 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' */ + /* Save failed query string to 'last_query_error' before reporting error (which may throw) */ zend_update_property_string(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "last_query_error", sizeof("last_query_error")-1, query); + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; }