diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index e9d7f986d5801..a05e8e352dc53 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -1291,12 +1291,23 @@ public function _real_escape( $data ) { /** * Escapes data. Works on arrays. * + * The `$data is string` case must come first in the conditional return type below. PHPStan + * does not treat the documented types as certain, so it still analyzes the nested + * `is_array()` check even though `$v` is a `string`, narrowing `$v` to `never` there. A + * `never` argument satisfies whichever case is tested first, so testing for `string` first + * makes the recursive call resolve to `string`. Testing for the array case first would + * instead resolve it to an array, widening `$data` and contradicting the return type. + * * @since 2.8.0 * * @uses wpdb::_real_escape() * - * @param string|array $data Data to escape. - * @return string|array Escaped data, in the same type as supplied. + * @param string|string[] $data Data to escape. + * @return string|string[] Escaped data, in the same type as supplied. + * + * @phpstan-template TKey of array-key + * @phpstan-param string|array $data + * @phpstan-return ( $data is string ? string : array ) */ public function _escape( $data ) { if ( is_array( $data ) ) { diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 74a28109b6536..b20c08e380e71 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4521,8 +4521,12 @@ function _deep_replace( $search, $subject ) { * * @global wpdb $wpdb WordPress database abstraction object. * - * @param string|array $data Unescaped data. - * @return string|array Escaped data, in the same type as supplied. + * @param string|string[] $data Unescaped data. + * @return string|string[] Escaped data, in the same type as supplied. + * + * @phpstan-template TKey of array-key + * @phpstan-param string|array $data + * @phpstan-return ( $data is string ? string : array ) */ function esc_sql( $data ) { global $wpdb;