在WordPress中更新MySQL数据库出现500错误,独立代码运行正常
问题描述
我需要在WordPress WooCommerce页面的JS函数中通过Ajax更新MySQL数据库。这段代码在独立环境运行正常,但部署到本地WordPress环境时触发500错误。因无法通过Ajax的data参数传递数据,我将所需数据(最终会改为变量)附加在URL后(?test=14230)。
Ajax代码
function db() { $.ajax({ url: 'update_db.php?test=14230', type: 'post', data: 0, success: function(output) { alert('Success, server says '+output); }, error: function() { alert('Something went wrong.'); } }); }
update_db.php代码
<?php if(isset($_GET['test']) ){ $id = $_GET['test']; } include 'database-handler.php'; $sql = "UPDATE db_name SET column = 'Some Value' WHERE id = $id"; if(mysqli_query($conn, $sql)){ //echo ('<p>'."Success.".'</p>'); } else { //echo ('<p>'."Something went wrong. $sql. " . mysqli_error($conn).'</p>'); } mysqli_close($conn); ?>
错误日志
[Wed Nov 09 15:16:47.543162 2022] [php:error] [pid 4564:tid 1828] [client ::1:5888] PHP Fatal error: Uncaught TypeError: mysqli_query(): Argument #1 ($mysql) must be of type mysqli, null given in C:\xampp\htdocs\my-sites\wowcard\wp-content\themes\blocksy-child\woocommerce\single-product\save-card-size.php:17 Stack trace: #0 C:\xampp\htdocs\my-sites\wowcard\wp-content\themes\blocksy-child\woocommerce\single-product\save-card-size.php(17): mysqli_query(NULL, 'UPDATE new_card...') #1 {main} thrown in C:\xampp\htdocs\my-sites\wowcard\wp-content\themes\blocksy-child\woocommerce\single-product\save-card-size.php on line 17, referer: http://localhost/my-sites/wowcard/product/polka-dot-brush-strokes-two-photo-birthday-card-purple/?card=complete&id=14230
问题原因与解决办法
核心错误原因
错误日志明确显示mysqli_query()的第一个参数$conn为null,说明database-handler.php在WordPress环境中未成功创建数据库连接。
环境差异导致的问题
- 路径错误:WordPress运行目录与
update_db.php所在目录不一致,导致include 'database-handler.php';无法找到文件,连接创建失败。 - 数据库连接冲突:WordPress已通过内置的
wpdb类建立数据库连接,自定义mysqli连接会因配置加载、权限问题失败,甚至与WordPress的连接冲突。 - 安全机制限制:WordPress的文件权限、
wp-config.php配置等安全机制,可能阻止自定义数据库连接脚本正常运行。
符合WordPress规范的解决方案
WordPress不支持直接用自定义PHP文件做Ajax接口,必须遵循官方Ajax规范,同时利用内置wpdb类操作数据库,避免连接问题。
步骤1:注册Ajax动作(在主题functions.php中添加)
// 允许登录/未登录用户访问的Ajax动作 add_action('wp_ajax_update_db_action', 'update_db_callback'); add_action('wp_ajax_nopriv_update_db_action', 'update_db_callback'); function update_db_callback() { // 验证请求合法性(推荐添加) check_ajax_referer('update_db_nonce', 'nonce'); // 获取并校验ID参数 $id = isset($_GET['test']) ? intval($_GET['test']) : 0; if (!$id) { wp_send_json_error('无效的ID参数'); } global $wpdb; $table_name = $wpdb->prefix . 'db_name'; // 替换为实际表名,注意WordPress表前缀 // 安全执行更新(用prepare防止SQL注入) $result = $wpdb->update( $table_name, array('column' => 'Some Value'), // 要更新的字段与值 array('id' => $id), // WHERE条件 array('%s'), // 值的格式:%s=字符串,%d=整数 array('%d') // 条件的格式 ); if ($result !== false) { wp_send_json_success('更新成功'); } else { wp_send_json_error('更新失败:' . $wpdb->last_error); } }
步骤2:修改前端Ajax代码
function db() { // 需在PHP模板中预先传递WordPress Ajax地址和验证密钥: // <script>const ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>'; const update_nonce = '<?php echo wp_create_nonce('update_db_nonce'); ?>';</script> $.ajax({ url: ajax_url + '?action=update_db_action&test=14230', type: 'POST', data: { nonce: update_nonce }, success: function(response) { if (response.success) { alert('Success, server says ' + response.data); } else { alert('Error: ' + response.data); } }, error: function() { alert('Something went wrong.'); } }); }
为什么要替换自定义连接?
- WordPress的
wpdb类已处理数据库连接、字符集、安全防护等问题,无需重复写连接逻辑。 - 自定义PHP文件会绕过WordPress安全机制,引发权限、路径、连接冲突等问题。
wp_ajax_*是官方推荐的Ajax实现方式,兼容所有WordPress版本与主题插件。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

