From f132601ed3b32a2786fd094d80e4b97fb6787f9f Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Mon, 23 Feb 2026 10:52:48 +0100 Subject: [PATCH 01/15] Docs: Replace void with null in union return types in class-wpdb.php Fixes #64703. See #64694. Co-Authored-By: xateman --- src/wp-includes/class-wpdb.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 23c865b87d817..810840208ef05 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -1453,11 +1453,11 @@ private function _escape_identifier_value( $identifier ) { * individual arguments. * @param mixed ...$args Further variables to substitute into the query's placeholders * if being called with individual arguments. - * @return string|void Sanitized query string, if there is a query to prepare. + * @return string|null Sanitized query string, if there is a query to prepare. */ public function prepare( $query, ...$args ) { if ( is_null( $query ) ) { - return; + return null; } /* @@ -2117,7 +2117,7 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool|void True if the connection is up. + * @return bool True if the connection is up. */ public function check_connection( $allow_bail = true ) { // Check if the connection is alive. @@ -3056,7 +3056,7 @@ public function get_var( $query = null, $x = 0, $y = 0 ) { * correspond to an stdClass object, an associative array, or a numeric array, * respectively. Default OBJECT. * @param int $y Optional. Row to return. Indexed from 0. Default 0. - * @return array|object|null|void Database query result in format specified by $output or null on failure. + * @return array|object|null Database query result in format specified by $output or null on failure. */ public function get_row( $query = null, $output = OBJECT, $y = 0 ) { $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; From 80da52a730b7ced03e5cba724b0d3642dc154b10 Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Mon, 23 Feb 2026 11:17:58 +0100 Subject: [PATCH 02/15] Update src/wp-includes/class-wpdb.php Co-authored-by: Mukesh Panchal --- src/wp-includes/class-wpdb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 810840208ef05..46c30bdf222d4 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -2117,7 +2117,7 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool True if the connection is up. + * @return bool True if the connection is up, false otherwise. */ public function check_connection( $allow_bail = true ) { // Check if the connection is alive. From 254b43996c69ea50e0b5d1b78438e40cc4311b5d Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Tue, 24 Feb 2026 09:18:58 +0100 Subject: [PATCH 03/15] Docs: Add `@return never` to `dead_db()`. --- src/wp-includes/functions.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 4b6330a697780..e4b96c6418c63 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5501,6 +5501,8 @@ function wp_ob_end_flush_all() { * @since 2.3.2 * * @global wpdb $wpdb WordPress database abstraction object. + * + * @return never */ function dead_db() { global $wpdb; From 0b5d819321090707daf55683dc994773cd8dcb1d Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Tue, 24 Feb 2026 10:42:28 +0100 Subject: [PATCH 04/15] fix(phpstan): Ignore return.never on dead_db() PHPStan cannot verify that wp_die() always terminates due to its conditional return type and treatPhpDocTypesAsCertain being disabled. --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index e4b96c6418c63..101585166bd65 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5521,7 +5521,7 @@ function dead_db() { } // Otherwise, be terse. - wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); + wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); // @phpstan-ignore return.never (wp_die() always exits by default.) } /** From 8cf94431c3eec4d3cb9626f09e8e90cca8a0d407 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 24 Feb 2026 15:18:55 -0800 Subject: [PATCH 05/15] Fix phpstan-return syntax Co-authored-by: Christoph Daum --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 101585166bd65..afc421079772a 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3766,7 +3766,7 @@ function wp_nonce_ays( $action ) { * } * @return never|void Returns void if `$args['exit']` is false, otherwise exits. * - * @phpstan-return ( $args['exit'] is false ? void : never ) + * @phpstan-return ( $args is array{exit: false} ? void : never ) */ function wp_die( $message = '', $title = '', $args = array() ) { global $wp_query; From 7b4fbe7a33d954165630127691a942ba9a1c1102 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 24 Feb 2026 15:19:03 -0800 Subject: [PATCH 06/15] Remove now-unnecessary phpstan-ignore --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index afc421079772a..8bf46ef0b871f 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5521,7 +5521,7 @@ function dead_db() { } // Otherwise, be terse. - wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); // @phpstan-ignore return.never (wp_die() always exits by default.) + wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); } /** From fffe2f6b8700af8cba2dc03e013a04b0399e4b9e Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Wed, 25 Feb 2026 08:14:38 +0100 Subject: [PATCH 07/15] docs: Refine phpdoc of dead_db() Co-authored-by: Weston Ruter --- src/wp-includes/class-wpdb.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 46c30bdf222d4..8168e0b5c515c 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -2117,7 +2117,9 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool True if the connection is up, false otherwise. + * @return bool|never Whether the connection is up. + * + * @phpstan-return ( $allow_bail is true ? bool|never : bool ) */ public function check_connection( $allow_bail = true ) { // Check if the connection is alive. From 9e7c83d3957b481b4d2d1f2f4c27abf4d07013cf Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 20:50:13 -0700 Subject: [PATCH 08/15] Remove never from unions --- src/wp-includes/class-wpdb.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 8168e0b5c515c..6021d7a8c4557 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -2117,9 +2117,7 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool|never Whether the connection is up. - * - * @phpstan-return ( $allow_bail is true ? bool|never : bool ) + * @return bool Whether the connection is up. */ public function check_connection( $allow_bail = true ) { // Check if the connection is alive. From f57015e0a35c1139bb1209bc078bb266024dc1a6 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 20:51:53 -0700 Subject: [PATCH 09/15] Document exiting --- src/wp-includes/class-wpdb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 6021d7a8c4557..2f4d775b9a617 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -2117,7 +2117,7 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool Whether the connection is up. + * @return bool Whether the connection is up. Exits if down and $allow_bail is true. */ public function check_connection( $allow_bail = true ) { // Check if the connection is alive. From 612def3d67cafdedc5cd5d129d1c010dd227113b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 20:54:15 -0700 Subject: [PATCH 10/15] Add explicit return null to wpdb::get_row() --- src/wp-includes/class-wpdb.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 2f4d775b9a617..ecfa62c78765b 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -3087,6 +3087,7 @@ public function get_row( $query = null, $output = OBJECT, $y = 0 ) { } else { $this->print_error( ' $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N' ); } + return null; } /** From cffb2a203b25343bb05ca403643dfae7132f12a9 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 20:56:58 -0700 Subject: [PATCH 11/15] =?UTF-8?q?Fix=20print=5Ferror()=20return=20type:=20?= =?UTF-8?q?void|false=20=E2=86=92=20null|false?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add explicit return null at the end of the method to match the documented return type. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/wp-includes/class-wpdb.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index ecfa62c78765b..bfd6fac092994 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -1794,7 +1794,7 @@ public function esc_like( $text ) { * @global array $EZSQL_ERROR Stores error information of query and error string. * * @param string $str The error to display. - * @return void|false Void if the showing of errors is enabled, false if disabled. + * @return null|false Null if the showing of errors is enabled, false if disabled. */ public function print_error( $str = '' ) { global $EZSQL_ERROR; @@ -1855,6 +1855,8 @@ public function print_error( $str = '' ) { $query ); } + + return null; } /** From 972bbb6f6422636f34e17295cbef6be1bdde3dfe Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 20:58:53 -0700 Subject: [PATCH 12/15] =?UTF-8?q?Fix=20bail()=20return=20type:=20void|fals?= =?UTF-8?q?e=20=E2=86=92=20false?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When show_errors is true, wp_die() is called which never returns. When false, it returns false. So the only actual return value is false. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/wp-includes/class-wpdb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index bfd6fac092994..8b30f08044f00 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -3940,7 +3940,7 @@ public function timer_stop() { * @param string $message The error message. * @param string $error_code Optional. A computer-readable string to identify the error. * Default '500'. - * @return void|false Void if the showing of errors is enabled, false if disabled. + * @return false False if the showing of errors is disabled. */ public function bail( $message, $error_code = '500' ) { if ( $this->show_errors ) { From 7327f0c62a0b9175c1b77dae8be69396dd4b11c8 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 21:30:24 -0700 Subject: [PATCH 13/15] =?UTF-8?q?Fix=20check=5Fdatabase=5Fversion()=20retu?= =?UTF-8?q?rn=20type:=20void|WP=5FError=20=E2=86=92=20WP=5FError|null?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add explicit return null when the version check passes. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/wp-includes/class-wpdb.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 8b30f08044f00..f419124e5368a 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -3998,7 +3998,7 @@ public function close() { * @since 2.5.0 * * @global string $required_mysql_version The minimum required MySQL version string. - * @return void|WP_Error + * @return WP_Error|null */ public function check_database_version() { global $required_mysql_version; @@ -4009,6 +4009,8 @@ public function check_database_version() { /* translators: 1: WordPress version number, 2: Minimum required MySQL version number. */ return new WP_Error( 'database_version', sprintf( __( 'Error: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ) ); } + + return null; } /** From a669b85985617b420ca4e968b34493786f1ce4f0 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 21:36:29 -0700 Subject: [PATCH 14/15] Fix bare return statements in prepare() to return null Two early-exit paths used bare return; instead of return null; to match the documented @return string|null type. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/wp-includes/class-wpdb.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index f419124e5368a..fa24ee361dc64 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -1666,7 +1666,7 @@ public function prepare( $query, ...$args ) { '6.2.0' ); - return; + return null; } $args_count = count( $args ); @@ -1684,7 +1684,7 @@ public function prepare( $query, ...$args ) { '4.9.0' ); - return; + return null; } else { /* * If we don't have the right number of placeholders, From 31173c3171df4d043d113259830e735053c1f125 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 29 Mar 2026 21:40:11 -0700 Subject: [PATCH 15/15] Add explicit return null to get_col_info() fallthrough path When col_info is empty, the method fell through without an explicit return statement. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/wp-includes/class-wpdb.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index fa24ee361dc64..e5300e6d75122 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -3905,6 +3905,8 @@ public function get_col_info( $info_type = 'name', $col_offset = -1 ) { return $this->col_info[ $col_offset ]->{$info_type}; } } + + return null; } /**