404 状态 header 当重写 url 变量包含用于斜杠转义的 %2F

404 status header when rewrite url variable contains %2F for slash escape

我创建了一个 wordpress 网站,它通过将 2 个查询变量传递到具有我的自定义 php 模板的 WP 页面来动态显示大约 40 万种产品中的一种。我正在使用 WPML 翻译我的页面,并且启用了保留 url vars _brand 和 _sku 的选项。使用此设置一切正常(页面显示和状态 200 ok header)。语言切换器还保留我的查询变量。

URL 看起来像: 域名.com/en/products/?_brand=JCB&_sku=01%2F117903

但是因为我希望 url 像域一样显示。com/en/products/a-brand/a-sku 我已经将以下重写规则添加到我的 child的functions.php

function rewrite_products()
{
    //en
    add_rewrite_rule('^products/([^&]+)/([^&]+)', 'index.php?page_id=93837&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //nl
    add_rewrite_rule('^producten/([^&]+)/([^&]+)', 'index.php?page_id=93871&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //fr
    add_rewrite_rule('^produits/([^&]+)/([^&]+)', 'index.php?page_id=93875&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //de
    add_rewrite_rule('^produkte/([^&]+)/([^&]+)', 'index.php?page_id=93876&_brand=$matches[1]&_sku=$matches[2]', 'top');
    //es
    add_rewrite_rule('^productos/([^&]+)/([^&]+)', 'index.php?page_id=93877&_brand=$matches[1]&_sku=$matches[2]', 'top');
}

add_action('init', 'rewrite_products');

function rewrite_product_tags()
{
    add_rewrite_tag('%_brand%', '([^&]+)');
    add_rewrite_tag('%_sku%', '([^&]+)');
}
add_action('init', 'rewrite_product_tags', 10, 0);

我现在可以浏览到所需的 URL 并且我得到了包含正确产品的相同页面,但是 header 现在显示 404 作为状态。

WPML 的语言切换器也丢弃了我的查询变量,只是将 /products/a-brand/a-sku 重定向到,例如 /producten(/products 的翻译)。

但最重要的是,404 header 状态不允许我索引我在站点地图中转储的页面(大约 2M url,因为 google 认为url's 是 404's 并且不索引那些。这在对比中是一个巨大的问题。

我将其归结为以下问题:

在模板中设置 header 无效。我的正则表达式错了吗?感谢您的帮助!

我猜这个错误与核心 WordPress 相关或在我父主题的某个地方。无论如何,我从来没有找到解决方案,只有在字符串编码时用 !2F 替换 %2F 的解决方法

//Custom encoding en decoding to stop %2F 404 headers
function url_decode($encoded)
{
    $encoded = str_replace('!2F', '%2F', $encoded);
    $part_url = urldecode($encoded);

    return $part_url;
}

function url_encode($part_url)
{
    $encoded = rawurlencode($part_url);
    $encoded = str_replace('%2F', '!2F', $encoded);
    return $encoded;
}