: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Retrieves one value from the database.
* Executes a SQL query and returns the value from the SQL result.
* If the SQL result contains more than one column and/or more than one row,
* the value in the column and row specified is returned. If $query is null,
* the value in the specified column and row from the previous SQL result is returned.
* @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
* @param int $x Optional. Column of value to return. Indexed from 0. Default 0.
* @param int $y Optional. Row of value to return. Indexed from 0. Default 0.
* @return string|null Database query result (as string), or null on failure.
public function get_var( $query = null, $x = 0, $y = 0 ) {
$this->func_call = "\$db->get_var(\"$query\", $x, $y)";
if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
$this->check_current_query = false;
// Extract var out of cached results based on x,y vals.
if ( ! empty( $this->last_result[ $y ] ) ) {
$values = array_values( get_object_vars( $this->last_result[ $y ] ) );
// If there is a value return it, else return null.
return ( isset( $values[ $x ] ) && '' !== $values[ $x ] ) ? $values[ $x ] : null;
* Retrieves one row from the database.
* Executes a SQL query and returns the row from the SQL result.
* @param string|null $query SQL query.
* @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
* 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.
public function get_row( $query = null, $output = OBJECT, $y = 0 ) {
$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
$this->check_current_query = false;
if ( ! isset( $this->last_result[ $y ] ) ) {
if ( OBJECT === $output ) {
return $this->last_result[ $y ] ? $this->last_result[ $y ] : null;
} elseif ( ARRAY_A === $output ) {
return $this->last_result[ $y ] ? get_object_vars( $this->last_result[ $y ] ) : null;
} elseif ( ARRAY_N === $output ) {
return $this->last_result[ $y ] ? array_values( get_object_vars( $this->last_result[ $y ] ) ) : null;
} elseif ( OBJECT === strtoupper( $output ) ) {
// Back compat for OBJECT being previously case-insensitive.
return $this->last_result[ $y ] ? $this->last_result[ $y ] : null;
$this->print_error( ' $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N' );
* Retrieves one column from the database.
* Executes a SQL query and returns the column from the SQL result.
* If the SQL result contains more than one column, the column specified is returned.
* If $query is null, the specified column from the previous SQL result is returned.
* @param string|null $query Optional. SQL query. Defaults to previous query.
* @param int $x Optional. Column to return. Indexed from 0. Default 0.
* @return array Database query result. Array indexed from 0 by SQL result row number.
public function get_col( $query = null, $x = 0 ) {
if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
$this->check_current_query = false;
// Extract the column values.
if ( $this->last_result ) {
for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
$new_array[ $i ] = $this->get_var( null, $x, $i );
* Retrieves an entire SQL result set from the database (i.e., many rows).
* Executes a SQL query and returns the entire SQL result.
* @param string $query SQL query.
* @param string $output Optional. 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.
* @return array|object|null Database query results.
public function get_results( $query = null, $output = OBJECT ) {
$this->func_call = "\$db->get_results(\"$query\", $output)";
if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
$this->check_current_query = false;
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 );
$key = array_shift( $var_by_ref );
if ( ! isset( $new_array[ $key ] ) ) {
$new_array[ $key ] = $row;
} 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 ) );
foreach ( (array) $this->last_result as $row ) {
// ...column name-keyed row arrays.
$new_array[] = get_object_vars( $row );
} elseif ( strtoupper( $output ) === OBJECT ) {
// Back compat for OBJECT being previously case-insensitive.
return $this->last_result;
* Retrieves the character set for the given table.
* @param string $table Table name.
* @return string|WP_Error Table character set, WP_Error object if it couldn't be found.
protected function get_table_charset( $table ) {
$tablekey = strtolower( $table );
* Filters the table charset value before the DB is checked.
* Returning a non-null value from the filter will effectively short-circuit
* checking the DB for the charset, returning that value instead.
* @param string|WP_Error|null $charset The character set to use, WP_Error object
* if it couldn't be found. Default null.
* @param string $table The name of the table being checked.
$charset = apply_filters( 'pre_get_table_charset', null, $table );
if ( null !== $charset ) {
if ( isset( $this->table_charset[ $tablekey ] ) ) {
return $this->table_charset[ $tablekey ];
$table_parts = explode( '.', $table );
$table = '`' . implode( '`.`', $table_parts ) . '`';
$results = $this->get_results( "SHOW FULL COLUMNS FROM $table" );
return new WP_Error( 'wpdb_get_table_charset_failure', __( 'Could not retrieve table charset.' ) );
foreach ( $results as $column ) {
$columns[ strtolower( $column->Field ) ] = $column;
$this->col_meta[ $tablekey ] = $columns;
foreach ( $columns as $column ) {
if ( ! empty( $column->Collation ) ) {
list( $charset ) = explode( '_', $column->Collation );
$charsets[ strtolower( $charset ) ] = true;
list( $type ) = explode( '(', $column->Type );
// A binary/blob means the whole query gets treated like this.
if ( in_array( strtoupper( $type ), array( 'BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB' ), true ) ) {
$this->table_charset[ $tablekey ] = 'binary';
// utf8mb3 is an alias for utf8.
if ( isset( $charsets['utf8mb3'] ) ) {
$charsets['utf8'] = true;
unset( $charsets['utf8mb3'] );
// Check if we have more than one charset in play.
$count = count( $charsets );
$charset = key( $charsets );
} elseif ( 0 === $count ) {
// No charsets, assume this table can store whatever.
// More than one charset. Remove latin1 if present and recalculate.
unset( $charsets['latin1'] );
$count = count( $charsets );
// Only one charset (besides latin1).
$charset = key( $charsets );
} elseif ( 2 === $count && isset( $charsets['utf8'], $charsets['utf8mb4'] ) ) {
// Two charsets, but they're utf8 and utf8mb4, use utf8.
// Two mixed character sets. ascii.
$this->table_charset[ $tablekey ] = $charset;
* Retrieves the character set for the given column.
* @param string $table Table name.
* @param string $column Column name.
* @return string|false|WP_Error Column character set as a string. False if the column has
* no character set. WP_Error object if there was an error.
public function get_col_charset( $table, $column ) {
$tablekey = strtolower( $table );
$columnkey = strtolower( $column );
* Filters the column charset value before the DB is checked.
* Passing a non-null value to the filter will short-circuit
* checking the DB for the charset, returning that value instead.
* @param string|null|false|WP_Error $charset The character set to use. Default null.
* @param string $table The name of the table being checked.
* @param string $column The name of the column being checked.
$charset = apply_filters( 'pre_get_col_charset', null, $table, $column );
if ( null !== $charset ) {
// Skip this entirely if this isn't a MySQL database.
if ( empty( $this->is_mysql ) ) {
if ( empty( $this->table_charset[ $tablekey ] ) ) {
// This primes column information for us.
$table_charset = $this->get_table_charset( $table );
if ( is_wp_error( $table_charset ) ) {
// If still no column information, return the table charset.
if ( empty( $this->col_meta[ $tablekey ] ) ) {
return $this->table_charset[ $tablekey ];
// If this column doesn't exist, return the table charset.
if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
return $this->table_charset[ $tablekey ];
// Return false when it's not a string column.
if ( empty( $this->col_meta[ $tablekey ][ $columnkey ]->Collation ) ) {
list( $charset ) = explode( '_', $this->col_meta[ $tablekey ][ $columnkey ]->Collation );
* Retrieves the maximum string length allowed in a given column.
* The length may either be specified as a byte length or a character length.
* @param string $table Table name.
* @param string $column Column name.
* @return array|false|WP_Error {
* Array of column length information, false if the column has no length (for
* example, numeric column), WP_Error object if there was an error.
* @type string $type One of 'byte' or 'char'.
* @type int $length The column length.
public function get_col_length( $table, $column ) {
$tablekey = strtolower( $table );
$columnkey = strtolower( $column );
// Skip this entirely if this isn't a MySQL database.
if ( empty( $this->is_mysql ) ) {
if ( empty( $this->col_meta[ $tablekey ] ) ) {
// This primes column information for us.
$table_charset = $this->get_table_charset( $table );
if ( is_wp_error( $table_charset ) ) {
if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
$typeinfo = explode( '(', $this->col_meta[ $tablekey ][ $columnkey ]->Type );
$type = strtolower( $typeinfo[0] );
if ( ! empty( $typeinfo[1] ) ) {
$length = trim( $typeinfo[1], ')' );
'length' => (int) $length,
'length' => (int) $length,
'length' => 255, // 2^8 - 1
'length' => 65535, // 2^16 - 1
'length' => 16777215, // 2^24 - 1
'length' => 4294967295, // 2^32 - 1
* Checks if a string is ASCII.
* The negative regex is faster for non-ASCII strings, as it allows
* the search to finish as soon as it encounters a non-ASCII character.
* @param string $input_string String to check.
* @return bool True if ASCII, false if not.
protected function check_ascii( $input_string ) {
if ( function_exists( 'mb_check_encoding' ) ) {
if ( mb_check_encoding( $input_string, 'ASCII' ) ) {
} elseif ( ! preg_match( '/[^\x00-\x7F]/', $input_string ) ) {
* Checks if the query is accessing a collation considered safe on the current version of MySQL.
* @param string $query The query to check.
* @return bool True if the collation is safe, false if it isn't.
protected function check_safe_collation( $query ) {
if ( $this->checking_collation ) {
// We don't need to check the collation for queries that don't read data.
$query = ltrim( $query, "\r\n\t (" );
if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $query ) ) {
// All-ASCII queries don't need extra checking.
if ( $this->check_ascii( $query ) ) {
$table = $this->get_table_from_query( $query );
$this->checking_collation = true;
$collation = $this->get_table_charset( $table );
$this->checking_collation = false;
// Tables with no collation, or latin1 only, don't need extra checking.
if ( false === $collation || 'latin1' === $collation ) {