Opened 6 months ago
Last modified 5 months ago
#63751 new defect (bug)
wpdb->set_prefix() throws deprecation notice for preg_match() when setup-config.php is loaded
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | minor | Version: | 6.8.2 |
| Component: | Database | Keywords: | |
| Focuses: | coding-standards, php-compatibility | Cc: |
Description
A bit esoteric, but this is throwing a reliable deprecation notice in my logs when bots visit /wp-admin/setup-config.php:
[25-Jul-2025 18:59:23] PHP deprecated: "preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated" file: /[...]/wp-includes/class-wpdb.php:1007 url: [...]/wp-admin/setup-config.php
The code throwing the error:
public function set_prefix( $prefix, $set_table_names = true ) {
if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
}
The immediate cause is obvious: preg_match() is run without checking that $prefix has any content, and in PHP 8.x you're not allowed to pass empty strings to it.
The "real" cause, I don't know. Why is there no $prefix available when normally there would be? Should there be?
These WP_INSTALLING files like setup-config.php are a mystery to me, and seem relatively untested especially with these PHP 8.x edge-cases.
My goal with this ticket is just to clean up the deprecation warning.
It seems to me all that needs to be done is to check that !empty( $prefix) before doing the preg_replace(), so:
public function set_prefix( $prefix, $set_table_names = true ) {
if ($prefix && preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
}
Seems to me that would resolve the notice and have the exact same effect as the old code.
Thank you for helping fix this 🙏🏻
Change History (2)
#2
@
5 months ago
Fair enough, I'm not clear on whether the prefix can be empty or not. The current behavior implies an empty one is acceptable, so I would default to preserving the behavior and just silencing the notice.
If anyone wants to confirm that this would be accepted either way, it would probably be fine.
The cause is highly important to understanding how to fix it. I think the real solution would be found outside the
wpdbclass.However, if its
set_prefixmethod should require a$prefix(#16229), then returning theinvalid_db_prefixerror could stop the operations:if ( ! $prefix || preg_match( '|[^a-z0-9_]|i', $prefix ) ) { return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' ); }