WordPress查询与引号/撇号变量

4

这是一个有点复杂的问题。我有一个ajax请求,用于检查重复的文章标题,但它会因为不同的引号/撇号及其变体而出错,即使我知道有一个重复的标题也会返回负值。

我有一个名为“Ben's Big Fish”的文章标题,即带有撇号(’)

但是查询以下内容总是返回负值:

Ben's Big Fish (')
Ben’s Big Fish (’)
Bens Big Fish (no apos)

然而,查询Big Fish会返回所有包含这些单词的变体文章标题,包括带引号和撇号的文章标题。

以下是导致问题的主要字符:

Apostrophe          '   '
Open single quote   ‘   ‘ 
Close single quote  ’   ’
--- 
Quotation mark      "   "
Open double quotes  “   “ 
Close double quotes ”   ”

由于用户经常从MS Word等文档中提取文本,因此这些字符出现得很多。

在js端,我通过将文章标题通过此函数传递来进行编码,然后将其通过json发送到我的ajax处理程序:

function htmlEntities(str) {
    return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/‘/g, '&lsquo;').replace(/’/g, '&rsquo;').replace(/“/g, '&ldquo;').replace(/”/g, '&rdquo;');
} 

在我的php ajax钩子中,我将传入的POST查询处理如下:
global $wpdb;
// Grab details from inbound POST array & prepare for sql
$title = html_entity_decode($_POST['post_title']); //first un-encode
$post_id = $_POST['post_id'];

$sim_query = "SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_title LIKE '%%%s%%' AND ID != '%d'";
$sim_results = $wpdb->get_results( $wpdb->prepare( $sim_query, $wpdb->esc_like($title), $post_id ) );
if ($sim_results)
{ // Send the results back as json }

我的问题是: a)如何使查询返回预期的明显重复项; b)可能相关的是,有没有一种方法可以高效地搜索字符串,查找所有变体中撇号和引号字符的出现,而不需要多个查询?

我并不是正则表达式专家,但在搜索特殊字符时,你不应该加上 \ 吗?例如:.replace(/&/g, '&amp;') -> .replace(/\&/g, '&amp;') 等等? - dingo_d
@dingo_d 感谢您指出这一点,尽管我不认为在这种情况下需要转义。至少 Webkit 似乎可以处理这个问题,但是旧的 js 引擎可能会有异议。此示例源自 https://css-tricks.com/snippets/javascript/htmlentities-for-javascript/。无论如何,它都没有影响 sql 查询的结果。 - orionrush
1个回答

2
问题的关键实际上回溯到 JS 中的原始编码。其中一个让我们困扰的关键字符:&apos;,即使设置了ENT_QUOTES标志,也不会被html_entity_decode解码。相反,它需要&#039;
因此,最终我们的 JavaScript 代码如下:
function htmlEntities(str) {
    return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;').replace(/‘/g, '&lsquo;').replace(/’/g, '&rsquo;').replace(/“/g, '&ldquo;').replace(/”/g, '&rdquo;');
} 

我们用PHP解码:
 $title = html_entity_decode($_POST['post_title'], ENT_QUOTES,  'UTF-8' ); //first un-encode

重要的是要注意,SQL 对单引号和撇号会产生错误。它要求将它们通过将它们加倍进行转义''。当我们使用 Wordpress 的 SQL 转义类$wpdb->prepare时,Wordpress 会为我们处理转义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接