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

在WordPress插件中使用rewrite_rules_array后如何获取$_POST?

获取WordPress重写规则后的POST数据

我太懂你深夜折腾插件的那种疲惫了——当你用上rewrite_rules_array自定义路由后,突然发现$_POST数据拿不到了,确实挺闹心的。结合你贴的那些钩子代码,我来帮你梳理下问题和解决办法:

为什么POST数据会“消失”?

WordPress的重写规则默认是为GET请求设计的,当你自定义路由后,如果没有正确处理请求类型,或者钩子的执行顺序/逻辑干扰了请求体的解析,就会出现$_POST为空的情况。尤其是你同时用了do_parse_request和parse_request,很容易在拦截过程中跳过了POST数据的解析步骤。

具体解决步骤

1. 确保重写规则不限制POST请求

在你的rewrite_rules函数里,不要给规则加上只匹配GET的限制,确保自定义路由能接收POST请求:

public function rewrite_rules($rules) {
    // 示例:添加支持POST的API路由
    $custom_rules = [
        'api/v1/([a-z-]+)/?$' => 'index.php?api_endpoint=$matches[1]'
    ];
    // 把自定义规则放在最前面,优先匹配
    return array_merge($custom_rules, $rules);
}

2. 手动读取POST数据(最可靠的方法)

如果$_POST还是为空,直接从PHP的原始请求体读取数据,这是绕过WordPress路由干扰的终极办法:

public function v1_api($wp) {
    // 先判断是不是我们的API请求
    if (!isset($wp->query_vars['api_endpoint'])) {
        return;
    }

    // 读取原始POST数据
    $raw_post = file_get_contents('php://input');
    
    // 处理JSON格式的请求
    $post_data = json_decode($raw_post, true);
    // 如果是表单提交的x-www-form-urlencoded格式,用parse_str解析
    if (!$post_data) {
        parse_str($raw_post, $post_data);
    }

    // 现在$post_data就包含了所有POST参数,比如:
    // $username = $post_data['username'] ?? '';
    
    // 你的API逻辑代码...
}

3. 检查do_parse_request的拦截逻辑

你的intercept_wp_router函数如果提前终止了请求,会导致WordPress没有机会解析POST数据。确保这个钩子只是做拦截判断,不要提前exit:

public function intercept_wp_router($continue, $wp, $extra_query_vars) {
    // 只拦截我们的API请求
    if (isset($wp->query_vars['api_endpoint'])) {
        // 这里可以做预处理,但一定要return true,让请求继续到parse_request
        return true;
    }
    // 非API请求,按WordPress默认流程走
    return $continue;
}

4. 优化重写规则刷新逻辑

你现在在wp_loaded里每次都刷新重写规则,不仅影响性能,还可能导致规则不稳定。建议只在插件激活时刷新:

// 插件激活钩子(放在类外面或者类的构造函数里)
register_activation_hook(__FILE__, [$this, 'activate_plugin']);

public function activate_plugin() {
    // 先调用一次rewrite_rules确保规则被注册
    $this->rewrite_rules([]);
    // 刷新重写规则
    flush_rewrite_rules();
}

// 把wp_loaded里的flush_rewrites改成只在开发环境用
public function flush_rewrites() {
    if (defined('WP_ENV') && WP_ENV === 'development') {
        flush_rewrite_rules();
    }
}

总结

大多数情况下,直接读取php://input就能解决POST数据获取的问题,因为它绕过了WordPress的路由解析层,直接拿到原始请求体。另外记得检查各个钩子的执行顺序和逻辑,不要在拦截过程中打断正常的请求流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:56:57