174
175
protected $col_info;
177
* Saved queries that were executed
178
* Log of queries that were executed, for debugging purposes.
181
* @since 2.5.0 The third element in each query log was added to record the calling functions.
182
* @since 5.1.0 The fourth element in each query log was added to record the start time.
185
* Array of queries that were executed.
187
* @type array ...$0 {
188
* Data for each query.
190
* @type string $0 The query's SQL.
191
* @type float $1 Total time spent on the query, in seconds.
192
* @type string $2 Comma separated list of the calling functions.
193
* @type float $3 Unix timestamp of the time at the start of the query.
241
256
* @see wpdb::tables()
244
var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
245
'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' );
267
'term_relationships',
248
273
* List of deprecated WordPress tables
271
296
* @see wpdb::tables()
274
var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
275
'sitecategories', 'registration_log', 'blog_versions' );
299
var $ms_global_tables = array(
278
311
* WordPress Comments table
531
protected $incompatible_modes = array( 'NO_ZERO_DATE', 'ONLY_FULL_GROUP_BY',
532
'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'TRADITIONAL' );
572
protected $incompatible_modes = array(
574
'ONLY_FULL_GROUP_BY',
575
'STRICT_TRANS_TABLES',
535
581
* Whether to use mysqli over mysql.
567
613
public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
568
614
register_shutdown_function( array( $this, '__destruct' ) );
570
if ( WP_DEBUG && WP_DEBUG_DISPLAY )
616
if ( WP_DEBUG && WP_DEBUG_DISPLAY ) {
571
617
$this->show_errors();
573
620
// Use ext/mysqli if it exists unless WP_USE_EXT_MYSQL is defined as true
574
621
if ( function_exists( 'mysqli_connect' ) ) {
744
792
* @param string $collate Optional. The collation. Default null.
746
794
public function set_charset( $dbh, $charset = null, $collate = null ) {
747
if ( ! isset( $charset ) )
795
if ( ! isset( $charset ) ) {
748
796
$charset = $this->charset;
749
if ( ! isset( $collate ) )
798
if ( ! isset( $collate ) ) {
750
799
$collate = $this->collate;
751
801
if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
752
802
$set_charset_succeeded = true;
759
809
if ( $set_charset_succeeded ) {
760
810
$query = $this->prepare( 'SET NAMES %s', $charset );
761
if ( ! empty( $collate ) )
811
if ( ! empty( $collate ) ) {
762
812
$query .= $this->prepare( ' COLLATE %s', $collate );
763
814
mysqli_query( $dbh, $query );
769
820
if ( $set_charset_succeeded ) {
770
821
$query = $this->prepare( 'SET NAMES %s', $charset );
771
if ( ! empty( $collate ) )
822
if ( ! empty( $collate ) ) {
772
823
$query .= $this->prepare( ' COLLATE %s', $collate );
773
825
mysql_query( $query, $dbh );
853
905
public function set_prefix( $prefix, $set_table_names = true ) {
855
if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
856
return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
907
if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
908
return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
858
911
$old_prefix = is_multisite() ? '' : $prefix;
860
if ( isset( $this->base_prefix ) )
913
if ( isset( $this->base_prefix ) ) {
861
914
$old_prefix = $this->base_prefix;
863
917
$this->base_prefix = $prefix;
865
919
if ( $set_table_names ) {
866
foreach ( $this->tables( 'global' ) as $table => $prefixed_table )
920
foreach ( $this->tables( 'global' ) as $table => $prefixed_table ) {
867
921
$this->$table = $prefixed_table;
869
if ( is_multisite() && empty( $this->blogid ) )
924
if ( is_multisite() && empty( $this->blogid ) ) {
870
925
return $old_prefix;
872
928
$this->prefix = $this->get_blog_prefix();
874
foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
930
foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) {
875
931
$this->$table = $prefixed_table;
877
foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
934
foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) {
878
935
$this->$table = $prefixed_table;
880
938
return $old_prefix;
900
958
$this->prefix = $this->get_blog_prefix();
902
foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
960
foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) {
903
961
$this->$table = $prefixed_table;
905
foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
964
foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) {
906
965
$this->$table = $prefixed_table;
908
968
return $old_blog_id;
918
978
public function get_blog_prefix( $blog_id = null ) {
919
979
if ( is_multisite() ) {
920
if ( null === $blog_id )
980
if ( null === $blog_id ) {
921
981
$blog_id = $this->blogid;
922
983
$blog_id = (int) $blog_id;
923
if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
984
if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) ) {
924
985
return $this->base_prefix;
926
987
return $this->base_prefix . $blog_id . '_';
928
990
return $this->base_prefix;
959
1021
public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
960
1022
switch ( $scope ) {
962
1024
$tables = array_merge( $this->global_tables, $this->tables );
963
if ( is_multisite() )
1025
if ( is_multisite() ) {
964
1026
$tables = array_merge( $tables, $this->ms_global_tables );
967
1030
$tables = $this->tables;
970
1033
$tables = $this->global_tables;
971
if ( is_multisite() )
1034
if ( is_multisite() ) {
972
1035
$tables = array_merge( $tables, $this->ms_global_tables );
975
1039
$tables = $this->ms_global_tables;
978
1042
$tables = $this->old_tables;
984
1048
if ( $prefix ) {
986
1050
$blog_id = $this->blogid;
987
$blog_prefix = $this->get_blog_prefix( $blog_id );
988
$base_prefix = $this->base_prefix;
1052
$blog_prefix = $this->get_blog_prefix( $blog_id );
1053
$base_prefix = $this->base_prefix;
989
1054
$global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
990
1055
foreach ( $tables as $k => $table ) {
991
if ( in_array( $table, $global_tables ) )
1056
if ( in_array( $table, $global_tables ) ) {
992
1057
$tables[ $table ] = $base_prefix . $table;
994
1059
$tables[ $table ] = $blog_prefix . $table;
995
1061
unset( $tables[ $k ] );
998
if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) )
1064
if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) ) {
999
1065
$tables['users'] = CUSTOM_USER_TABLE;
1001
if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) )
1068
if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) ) {
1002
1069
$tables['usermeta'] = CUSTOM_USER_META_TABLE;
1005
1073
return $tables;
1017
1085
* @param resource|null $dbh Optional link identifier.
1019
1087
public function select( $db, $dbh = null ) {
1020
if ( is_null($dbh) )
1088
if ( is_null( $dbh ) ) {
1021
1089
$dbh = $this->dbh;
1023
1092
if ( $this->use_mysqli ) {
1024
1093
$success = mysqli_select_db( $dbh, $db );
1044
1113
$message .= '<li>' . sprintf(
1045
1114
/* translators: 1: database user, 2: database name */
1046
1115
__( 'Does the user %1$s have permission to use the %2$s database?' ),
1047
'<code>' . htmlspecialchars( $this->dbuser, ENT_QUOTES ) . '</code>',
1116
'<code>' . htmlspecialchars( $this->dbuser, ENT_QUOTES ) . '</code>',
1048
1117
'<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>'
1052
1121
/* translators: %s: database name */
1053
1122
__( 'On some systems the name of your database is prefixed with your username, so it would be like <code>username_%1$s</code>. Could that be the problem?' ),
1054
1123
htmlspecialchars( $db, ENT_QUOTES )
1057
1126
$message .= "</ul>\n";
1081
1150
* @return string
1083
1152
function _weak_escape( $string ) {
1084
if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
1153
if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) {
1085
1154
_deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' );
1086
1156
return addslashes( $string );
1130
1200
if ( is_array( $data ) ) {
1131
1201
foreach ( $data as $k => $v ) {
1132
1202
if ( is_array( $v ) ) {
1133
$data[$k] = $this->_escape( $v );
1203
$data[ $k ] = $this->_escape( $v );
1135
$data[$k] = $this->_real_escape( $v );
1205
$data[ $k ] = $this->_real_escape( $v );
1156
1226
* @return mixed
1158
1228
public function escape( $data ) {
1159
if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
1229
if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) {
1160
1230
_deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' );
1161
1232
if ( is_array( $data ) ) {
1162
1233
foreach ( $data as $k => $v ) {
1163
if ( is_array( $v ) )
1164
$data[$k] = $this->escape( $v, 'recursive' );
1166
$data[$k] = $this->_weak_escape( $v, 'internal' );
1234
if ( is_array( $v ) ) {
1235
$data[ $k ] = $this->escape( $v, 'recursive' );
1237
$data[ $k ] = $this->_weak_escape( $v, 'internal' );
1169
1241
$data = $this->_weak_escape( $data, 'internal' );
1182
1254
* @param string $string to escape
1184
1256
public function escape_by_ref( &$string ) {
1185
if ( ! is_float( $string ) )
1257
if ( ! is_float( $string ) ) {
1186
1258
$string = $this->_real_escape( $string );
1202
1275
* Literal percentage signs (%) in the query string must be written as %%. Percentage wildcards (for example,
1203
1276
* to use in LIKE syntax) must be passed via a substitution argument containing the complete LIKE string, these
1204
* cannot be inserted directly in the query string. Also see {@see esc_like()}.
1277
* cannot be inserted directly in the query string. Also see {@see wpdb::esc_like()}.
1206
1279
* Arguments may be passed as individual arguments to the method, or as a single array containing all arguments. A combination
1207
1280
* of the two is not supported.
1269
1342
$query = str_replace( '"%s"', '%s', $query ); // Strip any existing double quotes.
1270
1343
$query = preg_replace( '/(?<!%)%s/', "'%s'", $query ); // Quote the strings, avoiding escaped strings like %%s.
1272
$query = preg_replace( "/(?<!%)(%($allowed_format)?f)/" , '%\\2F', $query ); // Force floats to be locale unaware.
1345
$query = preg_replace( "/(?<!%)(%($allowed_format)?f)/", '%\\2F', $query ); // Force floats to be locale unaware.
1274
1347
$query = preg_replace( "/%(?:%|$|(?!($allowed_format)?[sdF]))/", '%%\\1', $query ); // Escape any unescaped percents.
1289
1362
* or we were expecting multiple arguments in an array, throw a warning.
1291
1364
wp_load_translations_early();
1292
_doing_it_wrong( 'wpdb::prepare',
1293
1367
/* translators: 1: number of placeholders, 2: number of arguments passed */
1294
sprintf( __( 'The query does not contain the correct number of placeholders (%1$d) for the number of arguments passed (%2$d).' ),
1369
__( 'The query does not contain the correct number of placeholders (%1$d) for the number of arguments passed (%2$d).' ),
1344
1420
public function print_error( $str = '' ) {
1345
1421
global $EZSQL_ERROR;
1348
1424
if ( $this->use_mysqli ) {
1349
1425
$str = mysqli_error( $this->dbh );
1351
1427
$str = mysql_error( $this->dbh );
1354
$EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
1430
$EZSQL_ERROR[] = array(
1431
'query' => $this->last_query,
1432
'error_str' => $str,
1356
if ( $this->suppress_errors )
1435
if ( $this->suppress_errors ) {
1359
1439
wp_load_translations_early();
1415
1496
* @return bool Old value for showing errors.
1417
1498
public function show_errors( $show = true ) {
1418
$errors = $this->show_errors;
1499
$errors = $this->show_errors;
1419
1500
$this->show_errors = $show;
1420
1501
return $errors;
1431
1512
* @return bool Whether showing of errors was active
1433
1514
public function hide_errors() {
1434
$show = $this->show_errors;
1515
$show = $this->show_errors;
1435
1516
$this->show_errors = false;
1461
1542
public function flush() {
1462
$this->last_result = array();
1463
$this->col_info = null;
1464
$this->last_query = null;
1543
$this->last_result = array();
1544
$this->col_info = null;
1545
$this->last_query = null;
1465
1546
$this->rows_affected = $this->num_rows = 0;
1466
$this->last_error = '';
1547
$this->last_error = '';
1468
1549
if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
1469
1550
mysqli_free_result( $this->result );
1470
1551
$this->result = null;
1472
1553
// Sanity check before using the handle
1473
if ( empty( $this->dbh ) || !( $this->dbh instanceof mysqli ) ) {
1554
if ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) {
1502
1583
* Deprecated in 3.9+ when using MySQLi. No equivalent
1503
1584
* $new_link parameter exists for mysqli_* functions.
1505
$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
1586
$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
1506
1587
$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
1508
1589
if ( $this->use_mysqli ) {
1540
1621
* It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
1541
* - We haven't previously connected, and
1542
* - WP_USE_EXT_MYSQL isn't set to false, and
1543
* - ext/mysql is loaded.
1622
* - We haven't previously connected, and
1623
* - WP_USE_EXT_MYSQL isn't set to false, and
1624
* - ext/mysql is loaded.
1545
1626
$attempt_fallback = true;
1547
1628
if ( $this->has_connected ) {
1577
1658
$message = '<h1>' . __( 'Error establishing a database connection' ) . "</h1>\n";
1579
1660
$message .= '<p>' . sprintf(
1580
/* translators: 1: wp-config.php. 2: database host */
1661
/* translators: 1: wp-config.php, 2: database host */
1581
1662
__( 'This either means that the username and password information in your %1$s file is incorrect or we can’t contact the database server at %2$s. This could mean your host’s database server is down.' ),
1582
1663
'<code>wp-config.php</code>',
1583
1664
'<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'
1640
1721
$socket_pos = strpos( $host, ':/' );
1641
1722
if ( $socket_pos !== false ) {
1642
1723
$socket = substr( $host, $socket_pos + 1 );
1643
$host = substr( $host, 0, $socket_pos );
1724
$host = substr( $host, 0, $socket_pos );
1646
1727
// We need to check for an IPv6 address first.
1656
1737
$matches = array();
1657
$result = preg_match( $pattern, $host, $matches );
1738
$result = preg_match( $pattern, $host, $matches );
1659
1740
if ( 1 !== $result ) {
1660
1741
// Couldn't parse the address, bail.
1770
1851
* @param string $query Database query
1771
* @return int|false Number of rows affected/selected or false on error
1852
* @return int|bool Boolean true for CREATE, ALTER, TRUNCATE and DROP queries. Number of rows
1853
* affected/selected for all other queries. Boolean false on error.
1773
1855
public function query( $query ) {
1774
1856
if ( ! $this->ready ) {
1859
1941
if ( $this->last_error ) {
1860
1942
// Clear insert_id on a subsequent failed insert.
1861
if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
1943
if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
1862
1944
$this->insert_id = 0;
1864
1947
$this->print_error();
1888
1971
if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
1889
1972
while ( $row = mysqli_fetch_object( $this->result ) ) {
1890
$this->last_result[$num_rows] = $row;
1973
$this->last_result[ $num_rows ] = $row;
1893
1976
} elseif ( is_resource( $this->result ) ) {
1894
1977
while ( $row = mysql_fetch_object( $this->result ) ) {
1895
$this->last_result[$num_rows] = $row;
1978
$this->last_result[ $num_rows ] = $row;
2156
2244
$conditions[] = "`$field` = " . $value['format'];
2157
$values[] = $value['value'];
2245
$values[] = $value['value'];
2160
$fields = implode( ', ', $fields );
2248
$fields = implode( ', ', $fields );
2161
2249
$conditions = implode( ' AND ', $conditions );
2163
2251
$sql = "UPDATE `$table` SET $fields WHERE $conditions";
2208
2296
$conditions[] = "`$field` = " . $value['format'];
2209
$values[] = $value['value'];
2297
$values[] = $value['value'];
2212
2300
$conditions = implode( ' AND ', $conditions );
2383
2471
// Extract var out of cached results based x,y vals
2384
if ( !empty( $this->last_result[$y] ) ) {
2385
$values = array_values( get_object_vars( $this->last_result[$y] ) );
2472
if ( ! empty( $this->last_result[ $y ] ) ) {
2473
$values = array_values( get_object_vars( $this->last_result[ $y ] ) );
2388
2476
// If there is a value return it else return null
2389
return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null;
2477
return ( isset( $values[ $x ] ) && $values[ $x ] !== '' ) ? $values[ $x ] : null;
2418
if ( !isset( $this->last_result[$y] ) )
2506
if ( ! isset( $this->last_result[ $y ] ) ) {
2421
2510
if ( $output == OBJECT ) {
2422
return $this->last_result[$y] ? $this->last_result[$y] : null;
2511
return $this->last_result[ $y ] ? $this->last_result[ $y ] : null;
2423
2512
} elseif ( $output == ARRAY_A ) {
2424
return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
2513
return $this->last_result[ $y ] ? get_object_vars( $this->last_result[ $y ] ) : null;
2425
2514
} elseif ( $output == ARRAY_N ) {
2426
return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
2515
return $this->last_result[ $y ] ? array_values( get_object_vars( $this->last_result[ $y ] ) ) : null;
2427
2516
} elseif ( strtoupper( $output ) === OBJECT ) {
2428
2517
// Back compat for OBJECT being previously case insensitive.
2429
return $this->last_result[$y] ? $this->last_result[$y] : null;
2518
return $this->last_result[ $y ] ? $this->last_result[ $y ] : null;
2431
$this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
2520
$this->print_error( ' $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N' );
2445
2534
* @param int $x Optional. Column to return. Indexed from 0.
2446
2535
* @return array Database query result. Array indexed from 0 by SQL result row number.
2448
public function get_col( $query = null , $x = 0 ) {
2537
public function get_col( $query = null, $x = 0 ) {
2449
2538
if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
2450
2539
$this->check_current_query = false;
2502
2591
if ( $this->last_result ) {
2503
2592
foreach ( $this->last_result as $row ) {
2504
2593
$var_by_ref = get_object_vars( $row );
2505
$key = array_shift( $var_by_ref );
2594
$key = array_shift( $var_by_ref );
2506
2595
if ( ! isset( $new_array[ $key ] ) ) {
2507
2596
$new_array[ $key ] = $row;
2564
2653
$charsets = $columns = array();
2566
2655
$table_parts = explode( '.', $table );
2567
$table = '`' . implode( '`.`', $table_parts ) . '`';
2568
$results = $this->get_results( "SHOW FULL COLUMNS FROM $table" );
2656
$table = '`' . implode( '`.`', $table_parts ) . '`';
2657
$results = $this->get_results( "SHOW FULL COLUMNS FROM $table" );
2569
2658
if ( ! $results ) {
2570
2659
return new WP_Error( 'wpdb_get_table_charset_failure' );
2641
2730
* character set. WP_Error object if there was an error.
2643
2732
public function get_col_charset( $table, $column ) {
2644
$tablekey = strtolower( $table );
2733
$tablekey = strtolower( $table );
2645
2734
$columnkey = strtolower( $column );
2706
2795
* WP_Error object if there was an error.
2708
2797
public function get_col_length( $table, $column ) {
2709
$tablekey = strtolower( $table );
2798
$tablekey = strtolower( $table );
2710
2799
$columnkey = strtolower( $column );
2712
2801
// Skip this entirely if this isn't a MySQL database.
2838
2927
$this->checking_collation = true;
2839
$collation = $this->get_table_charset( $table );
2928
$collation = $this->get_table_charset( $table );
2840
2929
$this->checking_collation = false;
2842
2931
// Tables with no collation, or latin1 only, don't need extra checking.
2883
2972
$charset = $value['charset'];
2885
2974
if ( is_array( $value['length'] ) ) {
2886
$length = $value['length']['length'];
2975
$length = $value['length']['length'];
2887
2976
$truncate_by_byte_length = 'byte' === $value['length']['type'];
2889
2978
$length = false;
2912
3001
( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) )
2914
3003
$truncate_by_byte_length = true;
2915
$needs_validation = false;
3004
$needs_validation = false;
2918
3007
if ( $truncate_by_byte_length ) {
2949
$regex .= '){1,40} # ...one or more times
3038
$regex .= '){1,40} # ...one or more times
2951
3040
| . # anything else
2953
3042
$value['value'] = preg_replace( $regex, '$1', $value['value'] );
2956
3044
if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) {
2957
3045
$value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' );
2989
3077
if ( is_array( $value['length'] ) ) {
2990
$length = sprintf( '%.0f', $value['length']['length'] );
3078
$length = sprintf( '%.0f', $value['length']['length'] );
2991
3079
$queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), $length ) USING $connection_charset )", $value['value'] );
2992
} else if ( 'binary' !== $charset ) {
3080
} elseif ( 'binary' !== $charset ) {
2993
3081
// If we don't have a length, there's no need to convert binary - it will always return the same result.
2994
3082
$queries[ $col ] = $this->prepare( "CONVERT( CONVERT( %s USING $charset ) USING $connection_charset )", $value['value'] );
3010
3098
$this->check_current_query = false;
3011
$row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A );
3099
$row = $this->get_row( 'SELECT ' . implode( ', ', $sql ), ARRAY_A );
3012
3100
if ( ! $row ) {
3013
3101
return new WP_Error( 'wpdb_strip_invalid_text_failure' );
3016
3104
foreach ( array_keys( $data ) as $column ) {
3017
if ( isset( $row["x_$column"] ) ) {
3018
$data[ $column ]['value'] = $row["x_$column"];
3105
if ( isset( $row[ "x_$column" ] ) ) {
3106
$data[ $column ]['value'] = $row[ "x_$column" ];
3127
3215
$query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', $query );
3129
3217
// Quickly match most common queries.
3130
if ( preg_match( '/^\s*(?:'
3131
3220
. 'SELECT.*?\s+FROM'
3132
3221
. '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?'
3133
3222
. '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?'
3134
3223
. '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?'
3135
3224
. '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:.+?FROM)?'
3136
. ')\s+((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) {
3225
. ')\s+((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is',
3137
3229
return str_replace( '`', '', $maybe[1] );
3154
3246
// Big pattern for the rest of the table-related queries.
3155
if ( preg_match( '/^\s*(?:'
3156
3249
. '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
3157
3250
. '|DESCRIBE|DESC|EXPLAIN|HANDLER'
3158
3251
. '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?'
3166
3259
. '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE'
3167
3260
. '|(?:GRANT|REVOKE).*ON\s+TABLE'
3168
3261
. '|SHOW\s+(?:.*FROM|.*TABLE)'
3169
. ')\s+\(*\s*((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) {
3262
. ')\s+\(*\s*((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is',
3170
3266
return str_replace( '`', '', $maybe[1] );
3211
3307
if ( $this->col_info ) {
3212
3308
if ( $col_offset == -1 ) {
3214
3310
$new_array = array();
3215
3311
foreach ( (array) $this->col_info as $col ) {
3216
$new_array[$i] = $col->{$info_type};
3312
$new_array[ $i ] = $col->{$info_type};
3219
3315
return $new_array;
3221
return $this->col_info[$col_offset]->{$info_type};
3317
return $this->col_info[ $col_offset ]->{$info_type};
3258
3354
* @return false|void
3260
3356
public function bail( $message, $error_code = '500' ) {
3261
if ( !$this->show_errors ) {
3357
if ( $this->show_errors ) {
3360
if ( $this->use_mysqli ) {
3361
if ( $this->dbh instanceof mysqli ) {
3362
$error = mysqli_error( $this->dbh );
3363
} elseif ( mysqli_connect_errno() ) {
3364
$error = mysqli_connect_error();
3367
if ( is_resource( $this->dbh ) ) {
3368
$error = mysql_error( $this->dbh );
3370
$error = mysql_error();
3375
$message = '<p><code>' . $error . "</code></p>\n" . $message;
3262
3380
if ( class_exists( 'WP_Error', false ) ) {
3263
$this->error = new WP_Error($error_code, $message);
3381
$this->error = new WP_Error( $error_code, $message );
3265
3383
$this->error = $message;
3311
3429
public function check_database_version() {
3312
3430
global $wp_version, $required_mysql_version;
3313
3431
// Make sure the server has the required MySQL version
3314
if ( version_compare($this->db_version(), $required_mysql_version, '<') ) {
3432
if ( version_compare( $this->db_version(), $required_mysql_version, '<' ) ) {
3315
3433
/* translators: 1: WordPress version number, 2: Minimum required MySQL version number */
3316
return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
3434
return new WP_Error( 'database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ) );
3344
3462
public function get_charset_collate() {
3345
3463
$charset_collate = '';
3347
if ( ! empty( $this->charset ) )
3465
if ( ! empty( $this->charset ) ) {
3348
3466
$charset_collate = "DEFAULT CHARACTER SET $this->charset";
3349
if ( ! empty( $this->collate ) )
3468
if ( ! empty( $this->collate ) ) {
3350
3469
$charset_collate .= " COLLATE $this->collate";
3352
3472
return $charset_collate;
3370
3490
$version = $this->db_version();
3372
3492
switch ( strtolower( $db_cap ) ) {
3373
case 'collation' : // @since 2.5.0
3374
case 'group_concat' : // @since 2.7.0
3375
case 'subqueries' : // @since 2.7.0
3493
case 'collation': // @since 2.5.0
3494
case 'group_concat': // @since 2.7.0
3495
case 'subqueries': // @since 2.7.0
3376
3496
return version_compare( $version, '4.1', '>=' );
3377
case 'set_charset' :
3378
3498
return version_compare( $version, '5.0.7', '>=' );
3379
case 'utf8mb4' : // @since 4.1.0
3499
case 'utf8mb4': // @since 4.1.0
3380
3500
if ( version_compare( $version, '5.5.3', '<' ) ) {
3397
3517
return version_compare( $client_version, '5.5.3', '>=' );
3399
case 'utf8mb4_520' : // @since 4.6.0
3519
case 'utf8mb4_520': // @since 4.6.0
3400
3520
return version_compare( $version, '5.6', '>=' );