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

use*_*468 4 php mysql wordpress

我目前正在使用自定义 wordpress 表来存储外部 xml 提要,并且此信息需要可通过具有多个选项的基本 html 表单进行过滤。

解决此问题并使用构建字符串的最佳方法是什么wpdb->prepare?我正在使用以下内容进行分页,并且 $user_query 当前设置为 $user_query .= "ANDquery1LIKE $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)
  );
Run Code Online (Sandbox Code Playgroud)

我希望以上是有道理的。我只是想从$_GET没有 SQL 注入问题的表单值中构建 SQL 查询。

非常感谢

Mat*_*ley 8

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

$user_query = $wpdb->prepare('AND query1 LIKE %s', $query1);
Run Code Online (Sandbox Code Playgroud)

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

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

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

$wpdb->esc_like转义特定于 like 表达式(%、\、_)的字符,但不进行任何额外的转义。您仍然需要在转义 like 表达式后调用prepareor esc_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') );   
Run Code Online (Sandbox Code Playgroud)

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

$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) ); 
Run Code Online (Sandbox Code Playgroud)

为了举例,我假设用户查询是可选的。如果是这种情况,那么仅当提供了参数时,您才需要单独准备 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 );
Run Code Online (Sandbox Code Playgroud)

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