php - 条件where子句和mysql参数

标签 php mysql conditional-statements

我的应用程序中有一个包含多个不同字段的表单,用于搜索功能。搜索参数可以是任意组合,可以全部填充或仅填充 1 个(或任何其他参数)。

到目前为止,PHP 代码的相关部分如下所示(实际上有效 - 但我担心并认为这是一个非常糟糕的设计/实现):

       $whereClause =  "";
        if (!empty($_POST['searchAlias'])) {
            $searchAlias = "%{$_POST['searchAlias']}%";
            $whereClause .= " AND (users.alias LIKE ? OR users.alias LIKE ?)";
        } else {
            $searchAlias = "";
            $whereClause .= " AND (users.alias LIKE ? OR users.alias LIKE ?)";
        }
        if (!empty($_POST['searchLink'])) {
            $searchLink = "%{$_POST['searchLink']}%";
            $whereClause .= " AND (posts.homepage LIKE ? OR posts.homepage LIKE ?)";
        } else {
            $searchLink = "";
            $whereClause .= " AND (posts.homepage LIKE ? OR ? = '')";
        }
        if (!empty($_POST['searchComment'])) {
            $searchComment = "%{$_POST['searchComment']}%";
            $whereClause .= " AND (posts.comment LIKE ? OR posts.comment LIKE ?)";
        } else {
            $searchComment = "";
            $whereClause .= " AND (posts.comment LIKE ? OR ? = '')";
        }
        if (!empty($_POST['searchCategory'])) {
            $searchCategory = $_POST['searchCategory'];
            $whereClause .= " AND (posts.category LIKE ? OR posts.category LIKE ?)";
        } else {
            $searchCategory = "";
            $whereClause .= " AND (posts.category LIKE ? OR ? = '')";
        }

        $stmt = $connection->prepare("SELECT users.alias, posts.postId, 
        categories.category, posts.homepage, posts.comment, posts.timestamp, 
        posts.upvotes FROM ((posts INNER JOIN categories ON posts.category = 
        categories.id) INNER JOIN users ON posts.userId = users.userId) 
        WHERE 1=1 $whereClause ORDER BY postId DESC LIMIT 300");


        $stmt->bind_param("ssssssss", $searchAlias,$searchAlias, 
        $searchLink,$searchLink, $searchComment,$searchComment, 
        $searchCategory,$searchCategory);

我应该补充一点,我还有 2 个日期输入字段(起始日期和截止日期),它们也可以包含在搜索中,它们没有添加到当前的 php 代码中,因为我还没有修复它们。

如您所见,我确保从表单数据设置的参数附加到 whereClause - 始终带有两个 ?确保bind_param类型和变量始终保持不变。

那么,这是一个“可接受的”解决方案,还是有什么方法可以使其变得更加干净和简单?我尝试过寻找不同的解决方案,但我要么搜索得不够好,要么不够聪明地理解解决方案。

任何帮助或想法表示赞赏!

亲切的问候, 埃肯

最佳答案

如果/当添加其他搜索参数时,使用具有命名参数的 PDO 将使此任务更容易维护。它还可以容纳将值与多个列进行比较的搜索参数,或者需要对搜索值进行类型转换。您可能需要考虑在 LIKE 条件的值之前和之后添加“%”。这可以通过将 $_POST 值添加到数组并绑定(bind)数组值而不是 $_POST 值来完成。

编辑

我修改了我的第一篇文章,以搜索匹配的日期,并允许添加通配符来进行比较。还可以轻松修改代码以允许进行两个值检查,例如日期之间的检查。

$postVals = array();
foreach($_POST as $varname => $varval) {
    $postVals[$varname] = $varval;
}
$wherePieces = array();
$tests = array(
    "searchAlias" => array("where" => "user.alias LIKE :searchAlias","addWildCard" => false),
    "searchLink" => array("where" => "posts.homepage LIKE :searchLink","addWildCard" => true),
    "searchComment" => array("where" => "posts.comment LIKE :searchComment","addWildCard" => true),
    "searchCategory" => array("where" => "posts.category LIKE :searchCategory","addWildCard" => false),
    "searchTimestamp" => array("where" => "CAST(posts.timestamp AS DATE) = CAST(:searchTimestamp AS DATE)","addWildCard" => false)
);

foreach($tests as $postname => $wherePart) {
    if(isset($_POST[$postname]) && $_POST[$postname] != '') {
        $wherePieces[] = $wherePart['where'];
    }
}
$whereClause = "WHERE " . implode(" AND ",$wherePieces);
$qstr = "SELECT 
            users.alias, 
            posts.postId, 
            categories.category, 
            posts.homepage, 
            posts.comment, 
            posts.timestamp, 
            posts.upvotes 
        FROM posts 
        INNER JOIN categories 
            ON posts.category = categories.id
        INNER JOIN users 
            ON posts.userId = users.userId) 
        $whereClause 
        ORDER BY postId DESC 
        LIMIT 300";
$stmt = $connection->prepare($qstr);
foreach($tests as $postname => $wherePart) {
    if(isset($_POST[$postname]) && $_POST[$postname] != '') {
        if($wherePart["addWildCard"]) {
            $postVals[$postname] = '%'.$postVals[$postname].'%';
        }
        $stmt->bindParam(':'.$postname,$postVals[$postname]);
    }
}
$stmt->execute();

注意:未经测试,可能有拼写错误。

关于php - 条件where子句和mysql参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49677583/

相关文章:

php - 访问控制允许来源 angularjs 到 php

php - MySQL不会更新

在取消引用指针之前对 NULL 检查的条件移动指令

ruby-on-rails - validates_uniqueness_of 的条件验证消息

Postgresql创建表条件排除tsrange中的一列

javascript - 将图像上传为数组

php - PHP 中如何引用数组中的数组

php - 接受两个不同的模型实例作为函数参数 php

java - 如何防止重复。 Java、SQL

php - 如何使用内连接获取值