WordPress AJAX存数据库异常:部分内容无法保存,求调试方案
I see you're running into a frustrating issue where some articles save to your WordPress database but others don't, and the duplicate check isn't working consistently. Let's walk through fixing code flaws first, then dive into debugging steps to track down the root cause.
First: Fix Critical Code Issues
Your current PHP code has a couple of red flags that could cause inconsistent behavior or security risks:
Using
mysql_real_escape_stringwith WordPress
This function is deprecated and doesn't play nicely with WordPress's database abstraction layer. Instead, always use$wpdb->prepare()to safely escape values and avoid SQL injection—plus it ensures proper character encoding matching between your code and database.Unparameterized SQL Query
Your count query directly concatenates values, which can lead to mismatches if titles have special characters (like quotes, backslashes) or encoding differences.
Here's the revised PHP function with these fixes:
public static function wpnp_save_news(){ global $wpdb; $table_name = $wpdb->prefix.'wpnp'; if (is_user_logged_in()) { if (isset($_POST['delete'])) { $id = $_POST['id']; $wpdb->delete( $table_name, array( 'id' => $id ) ); echo "Article deleted"; } elseif (isset($_POST['savefav'])) { $user_id = $_POST['user_id']; $title = $_POST['title']; // Use prepare() for safe, consistent querying $count = $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $table_name WHERE user = %d AND title = %s", $user_id, $title ) ); if ($count <= 0 ) { // Insert with proper data handling $insert_data = array( 'user' => $user_id, 'title' => $title, 'summary' => $_POST['summary'], 'url' => $_POST['post_url'], 'img' => $_POST['img_url'], 'author' => $_POST['author'], 'source' => $_POST['source'] ); // Check if insert succeeded if ($wpdb->insert($table_name, $insert_data)) { echo "Article saved"; } else { // Log or output the error for debugging error_log("Insert failed: " . $wpdb->last_error); echo "Failed to save article"; } } else { echo "Article already saved"; } } else { echo "Please login to save articles"; } } else { // Fixed missing else clause for logged-out users echo "Please login to save articles"; } wp_die(); }
Note: I also added a check for insert success, logged errors, and fixed a missing else clause for logged-out users—small oversights that could cause unexpected behavior.
Debugging Steps to Track Down Remaining Issues
If you still see partial saves after fixing the code, work through these steps:
Check Database Field Constraints
- Verify your
wpnptable'stitlefield length: if some titles exceed theVARCHARlimit, they'll get truncated. This means your duplicate check looks for the full title, but only the truncated version is stored—leading to failed matches and potential save errors. - Ensure fields like
urlorsummaryaren't set toNOT NULLif some articles might have empty values for these.
- Verify your
Enable WordPress Debugging
Add these lines to yourwp-config.phpto log errors silently:define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false);Check
wp-content/debug.logfor database errors, insert failures, or PHP warnings that might explain why some saves fail.Inspect the SQL Being Executed
After running the count query or insert, adderror_log($wpdb->last_query);to log the exact SQL statement. Compare this to what you expect—are theuser_idandtitlevalues correct? Are special characters properly escaped?Validate Frontend Data
In your jQuery code, add aconsole.log()before the$.postto check if all data is being passed correctly. For the save action, do the same to ensure titles, URLs, and other fields aren't empty or corrupted:// Example for delete action (repeat for savefav) $('.wpnp-delete').on('click',(e)=>{ e.preventDefault(); const url = wpnpObj.au; const delete_data = { action: wpnpObj.ff, 'delete': true, 'id': e.currentTarget.dataset.id }; console.log('Delete data:', delete_data); // Log to check values const success = data =>{ alert(data) window.location.reload() }; const err = data =>{ console.log('Error:', data); } $.post(url,delete_data,success).fail(err); })Test the Duplicate Query Manually
Take a title that won't save, run this query directly in your database (via phpMyAdmin or WP CLI):SELECT count(*) FROM wp_wpnp WHERE user = YOUR_USER_ID AND title = 'EXACT_TITLE_FROM_FRONTEND';Does this return a count > 0? If not, check for hidden whitespace (like trailing spaces) or encoding differences (e.g., UTF-8 vs. Latin1) between the frontend data and what's stored in the database.
Check for Character Encoding Mismatches
Ensure your database table usesutf8mb4encoding (WordPress's default) and that your frontend sends data in UTF-8. Mismatches can cause characters to be stored incorrectly, leading to failed duplicate checks.
内容的提问来源于stack exchange,提问作者Thinkerman

