You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress PHP插件被JS调用时显示成功但未更新数据库

问题:AJAX调用WordPress插件脚本无法更新数据库,直接访问却正常

我搭建了WordPress站点,开发了一个插件用来更新自定义数据库,目的是限制用户使用工具的次数。数据库包含用户ID和使用次数列,检查次数阈值的功能正常,但遇到了奇怪的问题:

  • 直接在浏览器访问插件的PHP链接时,能成功获取用户ID并更新数据库;
  • 用HTML/JS的fetch调用这个脚本时,控制台显示调用成功,但数据库根本没更新。

插件PHP代码

<?php
/*
Plugin Name: Track User Usage
Plugin URL: REDACTED
Description: 
Version: 1.0
Author: REDACTED
*/

define('DB_SERVER2', 'REDACTED');
define('DB_USERNAME2', 'REDACTED');
define('DB_PASSWORD2', 'REDACTED');
define('DB_NAME2', 'REDACTED');

// Establish a persistent database connection
$conn = new mysqli(DB_SERVER2, DB_USERNAME2, DB_PASSWORD2, DB_NAME2);
$conn->autocommit(TRUE);
$conn->real_query("SET NAMES 'utf8'");

// Checking connection
if ($conn->connect_error) {
    die('Database connection failed: ' . $conn->connect_error);
}

function process_request() {

    global $conn;

    if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', '/home/REDACTED/REDACTED.com/' );
    }

     if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
     
        return;
    }

    include_once ABSPATH . '/wp-load.php';
    $userid = get_current_user_id();

    if ($userid == 0) {
        return;
    }

    $user_id = $userid; 
    $created_at = date('Y-m-d H:i:s'); 

    // Check if the user already exists in the table
    $sql_check_user = "SELECT * FROM tool_usage WHERE user_id = ?";
    $stmt_check_user = $conn->prepare($sql_check_user);
    $stmt_check_user->bind_param("i", $user_id);
    $stmt_check_user->execute();
    $result = $stmt_check_user->get_result();

    if ($result->num_rows > 0) {
        // User exists, update the usage count
        $sql_update_usage = "UPDATE tool_usage SET usage_count = usage_count + 1 WHERE user_id = ?";
        $stmt_update_usage = $conn->prepare($sql_update_usage);
        $stmt_update_usage->bind_param("i", $user_id);
        if ($stmt_update_usage->execute()) {
            
        } else {
            
        }
    } else {
        // User doesn't exist, insert a new record
        $usage_count = 1; // Initial usage count
        $sql_insert = "INSERT INTO tool_usage (user_id, usage_count, created_at) VALUES (?, ?, ?)";
        $stmt_insert = $conn->prepare($sql_insert);
        $stmt_insert->bind_param("iis", $user_id, $usage_count, $created_at);
        if ($stmt_insert->execute()) {
            
        } else {
            
        }
    }

    $stmt_check_user->close();
}

process_request();

$conn->close();
?>

注:部分else语句为空,是因为原来的echo语句引发问题,我删掉了,原本用来输出成功信息。

测试HTML/JS代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Track User Usage</title>
    <script>
        function trackUserUsage() {
            fetch('https://www.REDACTED.com/wp-content/plugins/track_user_usage/track_user_usage.php')
                .then(data => {
                    if (data.success) {
                        console.log('PHP script called successfully:', data);
                    } else {
                        console.error('PHP script error:', data);
                    }
                })
                .catch(error => {
                    console.error('Error calling PHP script:', error);
                });
        }
    </script>
</head>
<body>
    <button onclick="trackUserUsage()">Track User Usage</button>
</body>
</html>

问题排查与修复方案

核心原因

直接访问PHP脚本时,浏览器自动携带了WordPress的会话Cookie,所以get_current_user_id()能拿到正确的用户ID;但fetch请求默认不发送Cookie,导致get_current_user_id()返回0,脚本直接执行return,跳过了数据库更新逻辑。

具体修复步骤

1. 修改JS的fetch请求,强制携带Cookie

在fetch的配置里加上credentials: 'include',确保请求发送当前域名的会话Cookie:

function trackUserUsage() {
    fetch('https://www.REDACTED.com/wp-content/plugins/track_user_usage/track_user_usage.php', {
        credentials: 'include' // 关键:带上Cookie以保持用户登录状态
    })
    .then(response => response.text()) // 先解析响应内容(如果PHP返回JSON就用response.json())
    .then(result => {
        console.log('请求响应:', result);
    })
    .catch(error => {
        console.error('请求失败:', error);
    });
}

注意:原来的data.success是错误写法,fetch返回的是Response对象,必须先解析成文本或JSON才能读取内容。

2. 优化PHP脚本的调试与安全性

  • 添加错误日志:在$userid == 0时记录日志,方便确认是否是用户身份问题:
    if ($userid == 0) {
        error_log('Track Usage Plugin: 未检测到已登录用户');
        return;
    }
    
  • 输出响应结果:在数据库操作后返回明确的状态,方便前端判断:
    // 更新成功后添加
    echo json_encode(['success' => true, 'message' => '使用次数更新成功', 'user_id' => $user_id]);
    // 失败时添加
    echo json_encode(['success' => false, 'message' => '更新失败', 'error' => $stmt_update_usage->error]);
    
    对应的前端可以改成解析JSON:
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log('跟踪成功:', data);
        } else {
            console.error('跟踪失败:', data.error);
        }
    })
    
  • 改用WordPress原生数据库连接:插件里没必要自己新建mysqli连接,可以直接用WordPress的$wpdb类,避免硬编码数据库信息和路径问题:
    // 替换原有的数据库连接代码,直接使用$wpdb
    global $wpdb;
    // 查询示例:
    $result = $wpdb->get_row($wpdb->prepare("SELECT * FROM tool_usage WHERE user_id = %d", $user_id));
    

3. 处理跨域问题(如果测试页面不在同一域名)

如果测试HTML是在其他域名下打开的,需要在PHP脚本开头添加CORS响应头:

// 允许指定域名的跨域请求,替换成你的测试域名
header("Access-Control-Allow-Origin: https://your-test-domain.com");
header("Access-Control-Allow-Credentials: true");

注意:不能用*作为Access-Control-Allow-Origin,否则无法携带Cookie。

内容的提问来源于stack exchange,提问作者user25236328

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 15:30:53