Skip to content

Commit 4e804fb

Browse files
committed
Docs: Clarify return value semantics of wpdb query methods.
This eliminates over 400 PHPStan errors from the core codebase. * Clarify the inline documentation for the four `wpdb` query methods — `get_results()`, `get_row()`, `get_col()`, and `get_var()`. * Add `@phpstan-return` conditional types that mirror each method's runtime dispatch on `$query` and `$output`. * Add `@phpstan-param` tags narrowing `$output` to the documented constants. * Document that `get_var()` returns `null` both on failure and when the matched cell value is an empty string, directing consumers to `$this->last_error` to distinguish the two cases. * Tighten the `@return` in `get_results()` from `array|object|null` to `array|null`, since the method never returns a bare `stdClass`; the `object` was a copy/paste artifact from `get_row()`. * Fix a deprecated use of `null` as an array offset (PHP 8.5) in the `OBJECT_K` branch when a row's first column is SQL `NULL`. * Gather `get_col()` data as a true list. * Suggest `ext-mysqli` in `composer.json`, which `wpdb` requires at runtime. Developed in WordPress#11855. Props apermo, westonruter. See #30257, #64898. Fixes #65261. git-svn-id: https://develop.svn.wordpress.org/trunk@62529 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 58dc4e3 commit 4e804fb

2 files changed

Lines changed: 83 additions & 14 deletions

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"php": ">=7.4"
1717
},
1818
"suggest": {
19-
"ext-dom": "*"
19+
"ext-dom": "*",
20+
"ext-mysqli": "*"
2021
},
2122
"require-dev": {
2223
"composer/ca-bundle": "1.5.12",

src/wp-includes/class-wpdb.php

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3019,12 +3019,16 @@ protected function process_field_lengths( $data, $table ) {
30193019
* the value in the column and row specified is returned. If $query is null,
30203020
* the value in the specified column and row from the previous SQL result is returned.
30213021
*
3022+
* Returns null both on failure and when the matched cell value is an empty
3023+
* string. To distinguish the two cases, check {@see self::$last_error}.
3024+
*
30223025
* @since 0.71
30233026
*
30243027
* @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
30253028
* @param int $x Optional. Column of value to return. Indexed from 0. Default 0.
30263029
* @param int $y Optional. Row of value to return. Indexed from 0. Default 0.
3027-
* @return string|null Database query result (as string), or null on failure.
3030+
* @return string|null Database query result (as string), or null on failure or when the value is an empty string.
3031+
* @phpstan-return non-empty-string|null
30283032
*/
30293033
public function get_var( $query = null, $x = 0, $y = 0 ) {
30303034
$this->func_call = "\$db->get_var(\"$query\", $x, $y)";
@@ -3039,6 +3043,14 @@ public function get_var( $query = null, $x = 0, $y = 0 ) {
30393043

30403044
// Extract var out of cached results based on x,y vals.
30413045
if ( ! empty( $this->last_result[ $y ] ) ) {
3046+
/**
3047+
* Column values.
3048+
*
3049+
* These are returned from the database as strings, or null for SQL NULL, but get_object_vars() types the
3050+
* property values as mixed.
3051+
*
3052+
* @var list<string|null> $values
3053+
*/
30423054
$values = array_values( get_object_vars( $this->last_result[ $y ] ) );
30433055
}
30443056

@@ -3059,6 +3071,24 @@ public function get_var( $query = null, $x = 0, $y = 0 ) {
30593071
* respectively. Default OBJECT.
30603072
* @param int $y Optional. Row to return. Indexed from 0. Default 0.
30613073
* @return array|object|null Database query result in format specified by $output or null on failure.
3074+
* @phpstan-param 'OBJECT'|'ARRAY_A'|'ARRAY_N' $output
3075+
* @phpstan-return (
3076+
* $query is non-falsy-string
3077+
* ? (
3078+
* $output is 'OBJECT'
3079+
* ? stdClass|null
3080+
* : (
3081+
* $output is 'ARRAY_A'
3082+
* ? array<array-key, mixed>|null
3083+
* : (
3084+
* $output is 'ARRAY_N'
3085+
* ? list<mixed>|null
3086+
* : null
3087+
* )
3088+
* )
3089+
* )
3090+
* : null
3091+
* )
30623092
*/
30633093
public function get_row( $query = null, $output = OBJECT, $y = 0 ) {
30643094
$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
@@ -3104,6 +3134,7 @@ public function get_row( $query = null, $output = OBJECT, $y = 0 ) {
31043134
* @param string|null $query Optional. SQL query. Defaults to previous query.
31053135
* @param int $x Optional. Column to return. Indexed from 0. Default 0.
31063136
* @return array Database query result. Array indexed from 0 by SQL result row number.
3137+
* @phpstan-return list<non-empty-string|null>
31073138
*/
31083139
public function get_col( $query = null, $x = 0 ) {
31093140
if ( $query ) {
@@ -3118,7 +3149,7 @@ public function get_col( $query = null, $x = 0 ) {
31183149
// Extract the column values.
31193150
if ( $this->last_result ) {
31203151
for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
3121-
$new_array[ $i ] = $this->get_var( null, $x, $i );
3152+
$new_array[] = $this->get_var( null, $x, $i );
31223153
}
31233154
}
31243155
return $new_array;
@@ -3129,18 +3160,47 @@ public function get_col( $query = null, $x = 0 ) {
31293160
*
31303161
* Executes a SQL query and returns the entire SQL result.
31313162
*
3163+
* Returns an empty array when no rows match or when the database
3164+
* reports an error for the query. Returns null when $query is empty,
3165+
* when $output is not one of the recognized constants, or when the
3166+
* query cannot run because the connection is not ready.
3167+
*
31323168
* @since 0.71
31333169
*
3134-
* @param string $query SQL query.
3135-
* @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
3136-
* With one of the first three, return an array of rows indexed
3137-
* from 0 by SQL result row number. Each row is an associative array
3138-
* (column => value, ...), a numerically indexed array (0 => value, ...),
3139-
* or an object ( ->column = value ), respectively. With OBJECT_K,
3140-
* return an associative array of row objects keyed by the value
3141-
* of each row's first column's value. Duplicate keys are discarded.
3142-
* Default OBJECT.
3143-
* @return array|object|null Database query results.
3170+
* @param string|null $query SQL query.
3171+
* @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
3172+
* With one of the first three, return an array of rows indexed
3173+
* from 0 by SQL result row number. Each row is an associative array
3174+
* (column => value, ...), a numerically indexed array (0 => value, ...),
3175+
* or an object ( ->column = value ), respectively. With OBJECT_K,
3176+
* return an associative array of row objects keyed by the value
3177+
* of each row's first column's value. Duplicate keys are discarded.
3178+
* Default OBJECT.
3179+
* @return array|null Database query results. Empty array when no rows match
3180+
* or on database error. Null when $query is empty, when
3181+
* $output is invalid, or when the connection is not ready.
3182+
* @phpstan-param 'OBJECT'|'OBJECT_K'|'ARRAY_A'|'ARRAY_N' $output
3183+
* @phpstan-return (
3184+
* $query is non-falsy-string
3185+
* ? (
3186+
* $output is 'OBJECT'
3187+
* ? list<stdClass>|null
3188+
* : (
3189+
* $output is 'OBJECT_K'
3190+
* ? array<array-key, stdClass>
3191+
* : (
3192+
* $output is 'ARRAY_A'
3193+
* ? list<array<array-key, mixed>>
3194+
* : (
3195+
* $output is 'ARRAY_N'
3196+
* ? list<list<mixed>>
3197+
* : null
3198+
* )
3199+
* )
3200+
* )
3201+
* )
3202+
* : null
3203+
* )
31443204
*/
31453205
public function get_results( $query = null, $output = OBJECT ) {
31463206
$this->func_call = "\$db->get_results(\"$query\", $output)";
@@ -3167,7 +3227,15 @@ public function get_results( $query = null, $output = OBJECT ) {
31673227
if ( $this->last_result ) {
31683228
foreach ( $this->last_result as $row ) {
31693229
$var_by_ref = get_object_vars( $row );
3170-
$key = array_shift( $var_by_ref );
3230+
/**
3231+
* The first column's value is used as the key.
3232+
*
3233+
* A SQL NULL value surfaces as null here, so coerce it to an empty string to avoid the deprecated
3234+
* use of null as an array offset (PHP 8.5+).
3235+
*
3236+
* @var array-key $key
3237+
*/
3238+
$key = array_shift( $var_by_ref ) ?? '';
31713239
if ( ! isset( $new_array[ $key ] ) ) {
31723240
$new_array[ $key ] = $row;
31733241
}

0 commit comments

Comments
 (0)