使用$wpdb->query()执行两次DROP TABLE后,第三次调用无返回的问题咨询
Hey Mike, I’ve run into a similar issue before with older WordPress versions paired with MySQL 5.7 and PHP 7.0, so let’s break down what’s happening and how to fix it.
What’s Likely Causing This?
The root of the problem boils down to a combination of two factors:
- WordPress 5.0.x $wpdb Limitation: Older versions of WordPress’s database class didn’t handle repeated DDL (Data Definition Language) statements like
DROP TABLEvery gracefully. After two successful drops, the internal table cache or connection metadata in$wpdbcan get out of sync, causing the third query to hang waiting for a MySQL response that never comes. - MySQL 5.7 Metadata Locking: MySQL 5.7 has stricter metadata locking for DDL operations. If
$wpdbdoesn’t properly refresh its connection state after the first two drops, it might be holding onto stale metadata that conflicts with the third drop request.
Workarounds & Fixes
You’ve already found one solid workaround, but here are a few more options tailored to your scenario:
1. Combine Multiple DROP Statements into One
This is the most reliable fix you’ve already tested—since a single DROP TABLE call avoids the repeated connection/metadata issues entirely. Here’s a cleaned-up version of this approach:
function Drop_Tables() { global $wpdb; error_log("begin"); // List all tables to drop $tables = [ $wpdb->prefix . "Codes", $wpdb->prefix . "Phrases", $wpdb->prefix . "Exceptions" ]; // Prepare table names safely and build the query $table_list = implode(', ', array_map(function($table) use ($wpdb) { return $wpdb->prepare('%s', $table); }, $tables)); $SQL = "DROP TABLE IF EXISTS $table_list;"; $wpdb->query($SQL); if ($wpdb->last_error) { error_log($wpdb->last_error); } error_log("All tables dropped successfully"); }
(Added $wpdb->prepare here for extra safety, though DROP TABLE IF EXISTS is low-risk with properly prefixed table names.)
2. Flush $wpdb’s Internal Cache Before the Third Query
If you need to keep separate DROP calls for some reason, forcing $wpdb to refresh its table metadata can resolve the hang:
// Right before the third $wpdb->query() call error_log("Before query()"); $wpdb->flush(); // Resets internal table cache to avoid stale metadata $wpdb->query($SQL); error_log("After query()");
The flush() method clears $wpdb’s cached table information, ensuring it doesn’t rely on outdated data when executing the third drop.
3. Upgrade Your Entire Stack
This issue was addressed in WordPress 5.1 and later—the $wpdb class received updates to better handle repeated DDL operations and sync with MySQL’s metadata state. Additionally, your current stack (PHP 7.0.10, MySQL 5.7.14, WordPress 5.0.3) is quite outdated and has known security vulnerabilities. Upgrading to:
- WordPress 6.x (latest stable release)
- PHP 7.4+ (security-supported version)
- MySQL 8.0+ (improved performance and metadata handling)
will not only fix this specific issue but also make your site far more secure and stable.
Verification
From your debug log, it’s clear the script stops at Before query()—this confirms the $wpdb->query() call is hanging due to metadata/connection sync issues, not a syntax error (since the same table drops work perfectly in a single query).
内容的提问来源于stack exchange,提问作者Mike Meinz

