将“ curly”报价与数据库查询中的标准报价进行匹配

时间:2018-11-21 14:44:50

标签: php mysql sql wordpress

我在post_title列中存储了文本:

you’re

使用此查询:

function ma_post_title_filter($where, &$wp_query) {
    global $wpdb;
    if ( $search_term = $wp_query->get( 'ma_search_post_title' ) ) {
        $search_term = sanitize_text_field($search_term);
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . $wpdb->esc_like( $search_term ) . '%\'';
    }
    return $where;
}

如果$search_termyou’re,它将起作用并找到该列。但是当它为you're时,它将不起作用(因为它是一个不同的单引号)。

如何改进查询,以使you’reyou're都与you’re匹配?

到目前为止我已经尝试过的

  1. 使用str_replace()上的$search_term'替换为。示例:str_replace('\'','’',$wpdb->esc_like( $search_term )) ...这种方法的问题在于,如果存储的列为you're,我们将永远不会匹配。
  2. AND REPLACE上执行'.$wpdb->posts.'.post_title,将'替换为 ...但似乎不起作用。

我知道理想的解决方案是将单引号的所有数据库实例调整为标准引号,但是在我的情况下这是不可能的。

对此有什么合适的解决方案?

3 个答案:

答案 0 :(得分:2)

我想指出,%不是唯一可以在LIKE查询中使用的占位符。您也可以使用下划线_来指示单个字符。一种方法是用下划线替换某个类中的所有标点符号。这将使“您是”与“您是”匹配,反之亦然。 (当然,它也允许“ youvre”匹配!)

<?php
function ma_post_title_filter($where, &$wp_query) {
    global $wpdb;
    $punct = ["’", "‘", "”", "“"];
    if ( $search_term = $wp_query->get( 'ma_search_post_title' ) ) {
        // escape any % or _ characters
        $search_term = $wpdb->esc_like($search_term);
        // replace desired punctuation characters with _
        $search_term = str_replace($punct, "_", $search_term);
        // do final escaping for safe queries
        $search_term = $wpdb->_real_escape($search_term);
        // this looks much neater with string interpolation vs concatenation
        $where .= " AND $wpdb->posts.post_title LIKE '%$search_term%'";
    }
    return $where;
}

在将值传递到LIKE子句时,应使用wpdb::esc_like()来确保任何用户提供的百分号或下划线都不会妨碍您的操作。 sanitize_text_field()是在输出到HTML之前使用的,它不会使文本对于数据库查询安全。这就是wpdb::_real_escape()的目的。

答案 1 :(得分:1)

您可以使用MySQL RLIKE:

$where .= ' AND '. $wpdb->posts .'.post_title RLIKE \'.\*'. $wpdb->esc_like(str_replace(["’","'"],"['’]", $search_term) ) .'.\*\' ';

答案 2 :(得分:0)

我将两次使用LIKE语句,一个使用原始搜索词,第二个用'替换

您可以使用参数化查询。例如,使用wpdb::prepare()

$searchTerm = "You're"; //Don't sanitize using a function, this will by done with parameters.
// query
$where .= ' AND ('. $wpdb->posts .'.post_title LIKE %s OR '. $wpdb->posts .'.post_title LIKE %s)'; //Notice the double %s
//I suppose $where contains your whole query
$sth = $wpdb->prepare($where, '%' . $searchTerm . '%', '%' . str_replace('’', '\'', $search_term) . '%'); //This will associate the %s (a string) in the query by the value indicated in the function
$wpdb->query($sth);

%s是查询中的placeholder,用于向$wpdb->prepare()表示此位置将有一个字符串。