【问题标题】:How do I create a PDO parameterized query with a LIKE statement?如何使用 LIKE 语句创建 PDO 参数化查询?
【发布时间】:2021-05-28 21:13:50
【问题描述】:

这是我的尝试:

$query = $database->prepare('SELECT * FROM table WHERE column LIKE "?%"');

$query->execute(array('value'));

while ($results = $query->fetch()) 
{
    echo $results['column'];
}

【问题讨论】:

    标签: php pdo


    【解决方案1】:

    我有类似的需求,但使用的是从表单中获取的变量。我这样做是为了使用 PHP 从我的 PostgreSQL 数据库中获取结果:

    <?php
         $player = $_POST['search'];  //variable from my search form
         $find = $sqlPDO->prepare("SELECT player FROM salaries WHERE player ILIKE ?;");
         $find->execute(['%'.$player.'%']);
    
         while ($row = $find->fetch()) {
             echo $row['player']."</br>";
         }
    ?>
    

    “ILIKE”使搜索不区分大小写,因此搜索购物车或购物车或购物车都将返回相同的结果。

    【讨论】:

    • 它与接受的答案中的代码完全相同。
    • 其实不是,是有区别的。如果您认为它们实际上是相同的答案,则可能需要检查一下。
    • @zdarma 我认为他的意思是代码几乎相同,它并没有真正添加那么多新的关键信息。如果有人看到接受的答案,他可以在一秒钟后想出这个。这太明显了。 StackOverflow 的理念是您提供易于理解的独特答案并增加一些价值。您可以参考其他答案并给予他们信任,然后将您自己的想法添加到其中(鉴于 X 的解决方案,我想更改/添加 x、y、z、原因)。一旦你有 50 多个代表。您可以在帖子下写 cmets 给评论家或添加您的想法。
    • 请突出显示与其他答案的差异,以便其他人可以从中学习
    【解决方案2】:

    对于那些使用命名参数的人,这里是如何使用LIKE% 部分匹配MySQL 数据库

    WHERE column_name LIKE CONCAT('%', :dangerousstring, '%')

    其中命名参数为:dangerousstring

    换句话说,在您自己的查询中使用明确未转义的% 符号,这些符号是分开的,绝对不是用户输入。

    编辑: Oracle 数据库 的连接语法使用连接运算符:||,因此它会变成:

    WHERE column_name LIKE '%' || :危险字符串 || '%'

    但是,@bobince 提到 here 时有一些注意事项:

    difficulty 当您希望在 搜索字符串,而不是作为通配符。

    因此,在组合 like 和参数化时,还有其他需要注意的地方。

    【讨论】:

    • +1 - 这对我来说似乎是一个好方法,因为所有连接都在占位符被替换后发生在数据库中,这意味着可以使用命名占位符。值得一提的是,上面的语法是针对 Oracle 的——在 MySQL 中,语法是LIKE CONCAT('%', :something, '%')。参考:stackoverflow.com/a/661207/201648
    • 这并不完全适合我,但让我走上了正轨。我必须做 LIKE '%' :something '%' 才能工作。
    • 我知道这是题外话,但即使使用这个语句我也能够执行 sql 注入,为什么?
    • 这对我不起作用,我还用 SQL 命令SELECT * FROM calculation WHERE ( email LIKE '%' || luza || '%' OR siteLocation LIKE '%'|| luza ||'%' OR company LIKE '%' ||luza ||'%' ) 测试了它,这会给我错误。
    • @AaronNewton and it means named placeholders can be used。当您在 PHP 中连接时,命名占位符甚至是一个问题?显然,PHP 中的连接支持命名和位置,并且更便携,因为您可以对任何数据库使用相同的查询。我真的不明白为什么这么多人认为命名占位符和位置占位符之间存在任何区别。
    【解决方案3】:

    我从php delusions得到这个

    $search = "%$search%";
    $stmt  = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?");
    $stmt->execute([$search]);
    $data = $stmt->fetchAll();
    

    它对我有用,非常简单。就像他说的那样,在将其发送到查询之前,您必须“先准备好我们的完整文字”

    【讨论】:

      【解决方案4】:

      这行得通:

      search `table` where `column` like concat('%', :column, '%')
      

      【讨论】:

        【解决方案5】:

        PDO 转义“%”(可能导致 sql 注入):使用前面的代码在寻找匹配部分字符串时会给出期望的结果 BUT 如果 a访问者键入字符“%”,即使数据库中没有存储任何内容,您仍然会得到结果(可能导致 sql 注入)

        我已经尝试了很多变体,所有结果都相同 PDO 正在转义“%”导致不想要/不兴奋的搜索结果。

        我虽然值得分享,如果有人在它周围找到了一个词,请分享它

        【讨论】:

        • 这来自手册:us3.php.net/manual/en/pdo.prepared-statements.php 这是另一篇关于该主题的帖子:stackoverflow.com/questions/22030451/… 我真的很想知道您对这个问题的看法。
        • 可能的解决方案(未测试)使用 CONCAT,例如:$sql = “SELECT item_title FROM item WHERE item_title LIKE CONCAT('%',?,'%')” ;参考:blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard
        • PDO 不会转义 %。是你的代码做错了。对于解决方案,您应该阅读此处已提供的答案
        • 感谢您的建议。无论如何,测试的代码是手册中的代码,使用占位符来避免 SQL 注入,我仍然得到相同的结果 Example #6 Invalid use of placeholder PDO 确实使用上面的代码转义 %,而不是我的代码。我是论坛的新手,我可能不明白评论、帖子和声誉的过程是如何在这里工作的,我会记住我的下一个评论,因为根据之前的评论,你需要声誉来帮助他人或制作 cmets。谢谢。
        【解决方案6】:

        你也可以试试这个。我遇到了类似的问题,但经过研究得到了结果。

        $query = $pdo_connection->prepare('SELECT * FROM table WHERE column LIKE :search');
        
        $stmt= $pdo_connection->prepare($query);
        
        $stmt->execute(array(':search' => '%'.$search_term.'%'));
        
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        print_r($result);
        

        【讨论】:

        • 我编辑了您的帖子以将代码放入代码块中——您可以在stackoverflow.com/help/formatting 阅读有关帖子格式的更多信息。其他一些用户选择在不发表评论的情况下对您的答案投反对票,所以我不确定投反对票的原因。
        【解决方案7】:
        $query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
        $query->bindValue(1, "%$value%", PDO::PARAM_STR);
        $query->execute();
        
        if (!$query->rowCount() == 0) 
        {
            while ($results = $query->fetch()) 
            {
                echo $results['column'] . "<br />\n";
            }       
        } 
        else 
        {
            echo 'Nothing found';
        }
        

        【讨论】:

        • 使用这个比接受的答案有什么好处吗?使用bindValue 是否可以防止注入攻击?接受的答案基本上否定了使用? 占位符的价值,方法是将搜索字符串连接到%,就像在过去的日子一样。
        • 在 $query->rowCount() == 0 之前使用否定有什么意义?这真的有意义吗?
        【解决方案8】:

        我发帖后马上想通了:

        $query = $database->prepare('SELECT * FROM table WHERE column LIKE ?');
        $query->execute(array('value%'));
        
        while ($results = $query->fetch())
        {
            echo $results['column'];
        }
        

        【讨论】:

        • @Andrew:如果使用多个like 会怎样? execute数组应该如何按顺序执行?
        • 谢谢。使用 csharp + Mysql + ODBC 有类似的问题,它不会使用“select * from table where column like '%?%';”返回任何行但是,如果我喜欢您所做的“从表中选择 * 列喜欢的列?;”并将参数字符串设置为: string frag = $"%{searchFragment}%";然后使用 frag 作为参数值。奇怪
        • PDO 应该在执行调用中转义该 %。 Kaqai的答案更好
        • 值得注意的是,PDOStatement::bindParam documentation page 上的顶部 user-contributed note 提供了一种不同的方法:在绑定之前将百分号添加到变量。
        • 查看 gavin 的解决方案,取自您的常识页面,靠近本主题的底部。简单的。逻辑。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 2010-12-19
        • 2015-06-03
        相关资源
        最近更新 更多