diff --git a/features/db-check.feature b/features/db-check.feature index 523ddd99..53c73d1a 100644 --- a/features/db-check.feature +++ b/features/db-check.feature @@ -162,6 +162,38 @@ Feature: Check the database When I try `wp db check --no-defaults --debug` Then STDERR should match #Debug \(db\): Running shell command: /usr/bin/env (mysqlcheck|mariadb-check) --no-defaults %s# + @require-mysql-or-mariadb + Scenario: Empty DB credentials should not cause empty parameter errors + Given an empty directory + And WP files + + When I run `wp config create {CORE_CONFIG_SETTINGS} --dbcharset="" --skip-check` + Then STDOUT should not be empty + + When I run `cat wp-config.php` + Then STDOUT should contain: + """ + define( 'DB_CHARSET', '' ); + """ + + When I run `wp db create` + Then STDOUT should not be empty + + When I try `wp db check --debug` + Then the return code should be 0 + And STDOUT should contain: + """ + Success: Database checked. + """ + And STDERR should not contain: + """ + --default-character-set='' + """ + And STDERR should not contain: + """ + --default-character-set= + """ + @require-sqlite Scenario: SQLite commands that show warnings Given a WP install diff --git a/src/DB_Command.php b/src/DB_Command.php index 984a1d60..13de3c55 100644 --- a/src/DB_Command.php +++ b/src/DB_Command.php @@ -1990,6 +1990,29 @@ private static function run( $cmd, $assoc_args = [], $send_to_shell = true, $int $final_args = array_merge( $required, $assoc_args ); + // Filter out empty string values to avoid passing empty parameters to MySQL commands + // which can cause errors like "Character set '' is not a compiled character set". + // However, keep empty strings for credential options like 'user' and 'pass' so that + // an explicitly empty value is not silently converted into an omitted parameter. + $final_args = array_filter( + $final_args, + static function ( $value, $key ) { + // Always drop null values. + if ( null === $value ) { + return false; + } + + // Preserve explicitly empty credential arguments. + if ( '' === $value && in_array( $key, [ 'user', 'pass' ], true ) ) { + return true; + } + + // For all other options, filter out empty strings. + return '' !== $value; + }, + ARRAY_FILTER_USE_BOTH + ); + // Adapt ordering of arguments. uksort( $final_args,