wpdb::get_results( string|null $query = null, string $output = OBJECT ): array|null

Retrieves an entire SQL result set from the database (i.e., many rows).

Description

Executes a SQL query and returns the entire SQL result.

Returns an empty array when no rows match or when the database reports an error for the query. Returns null when $query is empty, when $output is not one of the recognized constants, or when the query cannot run because the connection is not ready.

Parameters

$querystring|nulloptional
SQL query.

Default:null

$outputstringoptional
Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
With one of the first three, return an array of rows indexed from 0 by SQL result row number. Each row is an associative array (column => value, …), a numerically indexed array (0 => value, …), or an object ( ->column = value ), respectively. With OBJECT_K, return an associative array of row objects keyed by the value of each row’s first column’s value. Duplicate keys are discarded.

Default:OBJECT

Return

array|null Database query results. Empty array when no rows match or on database error. Null when $query is empty, when $output is invalid, or when the connection is not ready.

Source

public function get_results( $query = null, $output = OBJECT ) {
	$this->func_call = "\$db->get_results(\"$query\", $output)";

	if ( $query ) {
		if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
			$this->check_current_query = false;
		}

		$this->query( $query );
	} else {
		return null;
	}

	$new_array = array();
	if ( OBJECT === $output ) {
		// Return an integer-keyed array of row objects.
		return $this->last_result;
	} elseif ( OBJECT_K === $output ) {
		/*
		 * Return an array of row objects with keys from column 1.
		 * (Duplicates are discarded.)
		 */
		if ( $this->last_result ) {
			foreach ( $this->last_result as $row ) {
				$var_by_ref = get_object_vars( $row );
				/**
				 * The first column's value is used as the key.
				 *
				 * A SQL NULL value surfaces as null here, so coerce it to an empty string to avoid the deprecated
				 * use of null as an array offset (PHP 8.5+).
				 *
				 * @var array-key $key
				 */
				$key = array_shift( $var_by_ref ) ?? '';
				if ( ! isset( $new_array[ $key ] ) ) {
					$new_array[ $key ] = $row;
				}
			}
		}
		return $new_array;
	} elseif ( ARRAY_A === $output || ARRAY_N === $output ) {
		// Return an integer-keyed array of...
		if ( $this->last_result ) {
			if ( ARRAY_N === $output ) {
				foreach ( (array) $this->last_result as $row ) {
					// ...integer-keyed row arrays.
					$new_array[] = array_values( get_object_vars( $row ) );
				}
			} else {
				foreach ( (array) $this->last_result as $row ) {
					// ...column name-keyed row arrays.
					$new_array[] = get_object_vars( $row );
				}
			}
		}
		return $new_array;
	} elseif ( strtoupper( $output ) === OBJECT ) {
		// Back compat for OBJECT being previously case-insensitive.
		return $this->last_result;
	}
	return null;
}

Changelog

VersionDescription
0.71Introduced.

User Contributed Notes

  1. Skip to note 5 content

    Example about how can you retrieve data from a table using get_results function:

    public function wpdocs_some_function( $some_parameter ) {
            global $wpdb;
            $results = $wpdb->get_results( 
                    $wpdb->prepare( "SELECT count( ID ) as total FROM {$wpdb->prefix}your_table_without_prefix WHERE some_field_in_your_table=%d", $some_parameter ) 
            );
    }

    Please, note that I have used %d assuming that $some_parameter is a int value.

  2. Skip to note 7 content

    When using OBJECT_K, the docs say “Duplicate keys are discarded” but don’t say WHICH row survives. Looking at the source:

    foreach ( $this->last_result as $row ) {
    $var_by_ref = get_object_vars( $row );
    $key = array_shift( $var_by_ref );
    if ( ! isset( $new_array[ $key ] ) ) {
    $new_array[ $key ] = $row;
    }
    }

    The FIRST row for each key wins, and every later row with the same key is discarded. This is the opposite of how a normal PHP loop assignment behaves ($array[$key] = $value repeated in a loop normally means “last write wins”), so it’s an easy assumption to get backwards.

    In practice, this means: if you query something like “the latest meta value per post” or “the newest row per user_id” and rely on OBJECT_K to collapse duplicates, the row you actually get back depends entirely on the order MySQL returns rows in — which is NOT guaranteed unless you explicitly ORDER BY.

    // WRONG: assumes the “latest” row wins, but SQL row order isn’t
    // guaranteed without ORDER BY, so this can silently return stale data.
    $latest_by_post = $wpdb->get_results(
    “SELECT post_id, meta_value FROM $wpdb->postmeta
    WHERE meta_key = ‘my_key’”,
    OBJECT_K
    );

    // RIGHT: since OBJECT_K keeps the FIRST row per key, order by the
    // field that determines “latest” in DESCENDING order, so the row you
    // want to keep is the first one MySQL returns for each post_id.
    $latest_by_post = $wpdb->get_results(
    “SELECT post_id, meta_value FROM $wpdb->postmeta
    WHERE meta_key = ‘my_key’
    ORDER BY meta_id DESC”,
    OBJECT_K
    );

    If your key column isn’t guaranteed unique in the result set and you don’t care which duplicate wins, this doesn’t matter — but if you do care (e.g. “most recent per group”), always pair OBJECT_K with an explicit ORDER BY, otherwise which row you get is essentially undefined behavior.

  3. Skip to note 8 content

    The example below is using heredoc to write the query and then getting the result through $wpdb->get_result(). The second parameter ARRAY_A used on the function will tell to the function that we need the result to be an Array.

    $query = <<<SQL
    SELECT
           p.ID, m.meta_key, m.meta_value
    FROM
         $wpdb->posts p
         LEFT JOIN
         $wpdb->postmeta m ON p.ID = m.post_id
         WHERE
               p.post_type IN ( 'post', 'page' )
               AND p.post_status = 'publish'
               AND ( m.meta_key IN ( '_yoast_wpseo_title', '_yoast_wpseo_metadesc', '_yoast_wpseo_meta-robots-noindex', 
               '_yoast_wpseo_meta-robots-nofollow' )
               OR 1 = 1 )
    SQL;
            
    /** @var array $result this will give us the ID and the other meta_field if any of all post types selected */
    $result = $wpdb->get_results( $query, ARRAY_A );

You must log in before being able to contribute a note or feedback.