Twig PHP中筛选含子项条目触发致命错误的原因及修复咨询
问题分析与修复方案
问题根源
触发urlencode(): Argument #1 ($string) must be of type string, array given错误的核心原因有两点:
buildUrlWithQueryString方法逻辑缺陷- 遇到非数组类型的查询参数时直接提前返回,导致后续参数被忽略,若首个参数为非数组还会生成无效URL;
- 未严格检查参数类型,当
$queryArgs中存在嵌套数组(比如WordPress原生查询变量或处理异常的筛选参数)时,会将数组直接传入urlencode(),触发类型错误; - 方法缺少遍历完所有参数后的返回逻辑,若所有参数均为数组,方法会返回
null,导致$_SERVER['REQUEST_URI']被赋值为无效值。
查询参数处理不规范
- 直接修改
$wp_query->query_vars,混入了WordPress原生查询变量(如paged、post_type等),这些变量可能包含非预期的数组结构; - 手动拼接URL的方式容易出错,未利用WordPress原生函数处理数组类型参数的编码。
- 直接修改
修复建议
1. 重构URL构建方法(替换buildUrlWithQueryString)
放弃手动拼接URL,使用WordPress原生的add_query_arg()函数,它会自动处理数组类型参数的编码,避免类型错误:
private function buildUrlWithQueryString($baseUrl, $queryArgs) { // 仅保留筛选相关参数和分页参数,过滤WP原生无关参数 $allowedKeys = array_column($this->context['filters'], 'key'); $allowedKeys[] = 'paged'; $cleanArgs = array_filter($queryArgs, function($key) use ($allowedKeys) { return in_array($key, $allowedKeys); }, ARRAY_FILTER_USE_KEY); return add_query_arg($cleanArgs, $baseUrl); }
2. 修正查询参数处理逻辑
不要直接修改$wp_query->query_vars,构建独立的查询参数数组,避免混入原生变量:
// 初始化基础查询参数 $queryArgs = [ 'post_type' => 'offer', 'posts_per_page' => get_option('posts_per_page'), ]; // 添加选中的筛选参数 foreach ($selectedFilters as $key => $values) { if (!empty($values)) { $queryArgs[$key] = $values; } } // 保留分页参数 if (isset($wp_query->query_vars['paged']) && $wp_query->query_vars['paged'] > 1) { $queryArgs['paged'] = $wp_query->query_vars['paged']; } $context['query_vars'] = $queryArgs; $context['posts'] = new PostQuery($queryArgs);
3. 加强筛选参数的类型校验
在处理$_GET参数时,确保所有值都是有效字符串,避免意外数组混入:
$selectedFilters = []; foreach ($context['filters'] as $filter) { $key = $filter['key']; $values = isset($_GET[$key]) ? $_GET[$key] : []; // 强制转为数组,过滤空值和非字符串内容 $values = (array)$values; $values = array_filter($values, function($val) { return is_string($val) && !empty(trim($val)); }); $selectedFilters[$key] = array_map('sanitize_text_field', $values); }
4. 模板层优化
模板中判断选中状态时,使用selectedFilters而非query_vars,避免原生查询变量干扰:
{% set isSelected = term.slug in (selectedFilters[f.key] ?? []) %} {# 子项选中状态判断同理 #} {% set isSelectedChild = child.slug in (selectedFilters[f.key] ?? []) %}
关键说明
使用add_query_arg()是最稳妥的方案,它会自动处理数组参数的编码(生成key[]=value1&key[]=value2格式的URL),规避手动拼接带来的类型错误和编码问题;独立构建查询参数数组可避免与WordPress原生变量冲突,减少意外错误。
内容的提问来源于stack exchange,提问作者Gr28plus
相关产品推荐
相关产品推荐

