可以让PHP MYSQL查询忽略WHERE子句中的空变量吗?

use*_*170 4 php mysql clause where

不知道我怎么做到这一点.基本上我有变量用组合框填充,然后传递以通过where子句形成MQSQL查询的过滤器.我需要做的是允许用户将组合框留空,然后在where子句中忽略该变量.这可能吗?

即,从这个代码.假设填充$ value1的组合框保留为空,是否有任何方法可以忽略它并仅应用第二个过滤器.

$query = "SELECT * FROM moth_sightings WHERE user_id = '$username' AND location = '$value1' AND english_name = $value2 ";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.C

sha*_*ail 12

使用

$where = "WHERE user_id = '$username'";

if(!empty($value1)){
$where .= "and location = '$value1'";
}

if(!empty($value2 )){
$where .= "and english_name= '$value2 '";
}


$query = "SELECT * FROM moth_sightings $where";
$result = mysql_query($query) or die(mysql_error());
$r = mysql_numrows($result);
Run Code Online (Sandbox Code Playgroud)


小智 6

其他几个答案提到了 SQL 注入的风险,还有几个明确提到使用准备好的语句,但没有一个答案明确显示如何做到这一点,这对于初学者来说可能是一个很大的要求。

我目前解决此问题的首选方法是使用 MySQL“IF”语句来检查有问题的参数是否为 null/empty/0(取决于类型)。如果为空,则它将字段值与其自身进行比较(WHERE field1=field1始终返回true)。如果参数不为空/null/零,则将字段值与参数进行比较。

下面是一个使用 MySQLi 准备好的语句的示例(假设 $mysqli 是一个已经实例化的 mysqli 对象):

$sql = "SELECT * 
        FROM moth_sightings 
        WHERE user_id = ? 
            AND location = IF(? = '', location, ?)
            AND english_name = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ssss', $username, $value1, $value1, $value2);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)

(我假设这$value2是一个基于字段名称的字符串,尽管 OP 的示例 SQL 中缺少引号。)

MySQLi 中无法将同一参数绑定到语句中的多个占位符,因此我们必须显式绑定$value1两次。MySQLi 在这种情况下的优点是参数的显式类型 - 如果我们$value1作为字符串传入,我们知道我们需要将它与空字符串进行比较''。如果$value1是整数值,我们可以像这样显式声明:

$stmt->bind_param('siis', $username, $value1, $value1, $value2);
Run Code Online (Sandbox Code Playgroud)

并将其与它进行比较0

下面是一个使用命名参数的 PDO 示例,因为我认为它们会产生可读性更高、计数更少的代码:

$sql = "SELECT * 
    FROM moth_sightings 
    WHERE user_id = :user_id 
        AND location = IF(:location_id = '', location, :location_id)
        AND english_name = :name";
$stmt = $pdo->prepare($sql);
$params = [
    ':user_id' => $username,
    ':location_id' => $value1,
    ':name' => $value2
];
$stmt->execute($params);
Run Code Online (Sandbox Code Playgroud)

请注意,使用 PDO 命名参数,我们可以在查询中多次引用:location_id,而只需绑定一次。