让我解释一下WordPress对请求的处理,以及相应地改变WordPress行为以实现目标的方法。
解析请求
当WordPress收到请求时,它会开始解析请求并将其转换为页面的过程。这个过程的核心开始于WordPress主查询方法
WP::main()
被调用。此函数在
parse_request()
(英寸
includes/class-wp.php
). 在那里,WordPress尝试将URL与
rewrite rules. 当URL匹配时,它会创建URL部分的查询字符串,并使用
urlencode()
, 防止特殊字符,如
&
避免弄乱查询字符串。这些编码字符可能会让您认为问题仍然存在,但在解析查询字符串时,它们实际上会变成相应的“真实”字符。
WordPress解析URL后,运行与请求关联的查询,它将设置主查询类,WP_Query
, 这是以相同的方式完成的main()
的方法WP
班的牛肉WP_Query
可在its中找到get_posts()
方法,在该方法中,所有查询参数都将被解析和清理,并构造(并最终运行)实际的SQL查询。
在此方法中,第2730行执行以下代码:
$q[\'name\'] = sanitize_title_for_query( $q[\'name\'] );
这将清理post,以便从posts表中获取它。在循环中输出调试信息表明这就是问题所在:您的帖子名,
my-permalink~
, 已转换为
my-permalink
, 然后用于从数据库中获取帖子。
职务消毒功能sanitize_title_for_query
呼叫sanitize_title
使用适当的参数,这将继续清理标题。现在,此函数的核心是应用sanitize_title
过滤器:
$title = apply_filters( \'sanitize_title\', $title, $raw_title, $context );
在本机WordPress中,此筛选器附带一个函数:
sanitize_title_with_dashes
. 我已经对这个函数的功能做了全面的概述,
which can be found here.
In this function, the line that\'s causing your problem is$title = preg_replace(\'/[^%a-z0-9 _-]/\', \'\', $title);
此行将除去字母数字字符、空格、连字符和下划线以外的所有字符。
解决您的问题
因此,基本上只有一种方法可以解决您的问题:删除
sanitize_title_with_dashes
函数,并用自己的函数替换它。这其实并不难做到,
but:
当WordPress更改标题清理的内部过程时,这将对您的网站产生重大影响其他挂接到此过滤器的插件可能无法正确处理新功能
Most importantly: WordPress使用sanitize_title
作用directly 在此行的SQL查询中:$where .= " AND $wpdb->posts.post_name = \'" . $q[\'name\'] . "\'";
如果您考虑更改过滤器,请确保在查询中使用标题之前正确转义标题!结论:就安全性而言,没有必要解决您的问题,但如果您想这样做,请更换
sanitize_title_with_dashes
使用您自己的功能,并注意SQL转义。
注意:所有文件名和行号都与WordPress 4.4.2文件相对应