Wordpress wpdb->从表单中准备sql字符串

时间:2015-04-07 17:14:48

标签: php mysql wordpress wpdb

我目前正在使用自定义wordpress表来存储外部xml Feed,而这些信息需要通过带有多个选项的基本html表单进行过滤。

使用wpdb->prepare构建字符串的最佳方法是什么?我使用以下内容进行分页,$ user_query目前设置为$user_query .= "AND query1 LIKE $query1 ";等。

但是我觉得这可能会导致问题,因为我没有通过%d$variable等第二个参数执行此操作。

//Get Results
$results = $wpdb->get_results(
    $wpdb->prepare("SELECT * FROM `feed` WHERE `price` != 0 $user_query  LIMIT %d,
       %d", $offset, $items_per_page, OBJECT)
  );

我希望上述内容有道理。我只是尝试从$_GET形式的值构建SQL查询而没有SQL注入问题。

非常感谢

1 个答案:

答案 0 :(得分:4)

您可以对部分查询调用$wpdb->prepare

$user_query = $wpdb->prepare('AND query1 LIKE %s', $query1);

您也可以直接在用户输入上调用esc_sql来清理它。

此外,LIKE表达式需要单独转义:

https://codex.wordpress.org/Class_Reference/wpdb/esc_like

$wpdb->esc_like转义特定于类似表达式(%,\,_)的字符,但不执行任何其他转义。在转义类似表达式后,您仍需要致电prepareesc_sql

更新:在评论中使用此示例:

$user_query = $_GET['query1']; 
$user_query2 = $_GET['query2']; 

$user = $wpdb->prepare('AND query1 = %s ', $user_query); 
$user2 = $wpdb->prepare('AND query2 = %s ', $user_query2); 

$results = $wpdb->get_results( $wpdb->prepare('SELECT * FROM test WHERE price != 0' . $user . $user2 . 'LIMIT 20') );   

这里没有任何关于部分构建查询的意义,您可以像这样构建查询:

$query = 'SELECT * FROM test 
            WHERE price != 0 
                AND query1 = %s 
                AND query1 = %s 
            LIMIT 20';
$results = $wpdb->get_results( $wpdb->prepare($query, $user_query, $user_query2) ); 

为了举例,我假设用户查询是可选的。如果是这种情况,那么只有在提供参数时才需要单独准备WHERE条件:

$query = 'SELECT * FROM test 
            WHERE price != 0';

if($user_query) {
    $cond = $wpdb->prepare(' AND query1 = %s', $user_query);
    $query .= $cond;
}

if($user_query2) {
    $cond = $wpdb->prepare(' AND query2 = %s', $user_query2); 
    $query .= $cond;
}

$query .= ' LIMIT 20';
$results = $wpdb->get_results( $query );

请注意,在将查询传递给get_results时,无需为查询调用prepare,因为所有用户输入都已经过清理。