@@ -1959,6 +1959,56 @@ private static function get_create_query() {
19591959 return $ create_query ;
19601960 }
19611961
1962+ /**
1963+ * Run a single DDL query (e.g. DROP/CREATE DATABASE) using PHP's mysqli extension.
1964+ *
1965+ * Used as a fallback when the mysql/mariadb CLI binary is not available.
1966+ * Creates a fresh connection per call so that DDL operations like
1967+ * DROP DATABASE followed by CREATE DATABASE work correctly.
1968+ *
1969+ * @param string $query SQL query to execute.
1970+ */
1971+ protected function run_query_via_mysqli ( $ query ) {
1972+ $ db_host = DB_HOST ;
1973+ $ port = null ;
1974+ $ socket = null ;
1975+
1976+ if ( ': ' === substr ( $ db_host , 0 , 1 ) ) {
1977+ $ socket = substr ( $ db_host , 1 );
1978+ $ db_host = 'localhost ' ;
1979+ } else {
1980+ $ parts = explode ( ': ' , $ db_host , 2 );
1981+ $ db_host = $ parts [0 ];
1982+ if ( isset ( $ parts [1 ] ) ) {
1983+ $ port_or_socket = trim ( $ parts [1 ] );
1984+ if ( '' !== $ port_or_socket && '/ ' === $ port_or_socket [0 ] ) {
1985+ $ socket = $ port_or_socket ;
1986+ } elseif ( '' !== $ port_or_socket ) {
1987+ $ port = (int ) $ port_or_socket ;
1988+ }
1989+ }
1990+ }
1991+
1992+ // When using a socket, pass 0 for port. When a port is explicitly set, use it; otherwise use the default.
1993+ $ port_value = null !== $ port ? $ port : 0 ;
1994+ $ socket_value = null !== $ socket ? $ socket : '' ;
1995+
1996+ // No database is selected intentionally — DDL operations like DROP/CREATE DATABASE work at the server level.
1997+ // phpcs:ignore WordPress.DB.RestrictedClasses.mysql__mysqli -- direct mysqli required as wpdb fallback when mysql binary is unavailable.
1998+ $ conn = new mysqli ( $ db_host , DB_USER , DB_PASSWORD , '' , $ port_value , $ socket_value );
1999+
2000+ if ( $ conn ->connect_errno ) {
2001+ WP_CLI ::error ( sprintf ( 'Failed to connect to the database: %s ' , $ conn ->connect_error ) );
2002+ }
2003+
2004+ if ( ! $ conn ->query ( $ query ) ) {
2005+ $ error = $ conn ->error ;
2006+ $ conn ->close ();
2007+ WP_CLI ::error ( sprintf ( 'Query failed: %s ' , $ error ) );
2008+ }
2009+ $ conn ->close ();
2010+ }
2011+
19622012 /**
19632013 * Run a single query via the 'mysql' binary.
19642014 *
@@ -1970,20 +2020,8 @@ private static function get_create_query() {
19702020 */
19712021 protected function run_query ( $ query , $ assoc_args = [] ) {
19722022 if ( ! $ this ->is_mysql_binary_available () ) {
1973- WP_CLI ::debug ( "Query via wpdb: {$ query }" , 'db ' );
1974- $ this ->maybe_load_wpdb ();
1975- global $ wpdb ;
1976-
1977- if ( ! isset ( $ wpdb ) ) {
1978- WP_CLI ::error ( 'WordPress database (wpdb) could not be initialized. Please ensure WordPress core files are properly installed. ' );
1979- }
1980-
1981- // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1982- $ result = $ wpdb ->query ( $ query );
1983- if ( false === $ result ) {
1984- // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
1985- WP_CLI ::error ( 'Query failed: ' . strip_tags ( $ wpdb ->last_error ) );
1986- }
2023+ WP_CLI ::debug ( "Query via mysqli: {$ query }" , 'db ' );
2024+ $ this ->run_query_via_mysqli ( $ query );
19872025 return ;
19882026 }
19892027
0 commit comments