使用PDO查询,没有预处理语句,使用来自多个HTML输入字段的多个LIKE语句

时间:2013-04-09 18:49:45

标签: php pdo

我已成功获得在PDO中执行和打印的查询,但我在这里做错了。这个问题的代码的重要部分是在最后几个代码块中;为了清楚起见,我将第一部分包括在内。

此代码连接到具有多个输入字段的HTML表单。 PHP通过在WHERE语句中使用AND附加来自每个字段的数据来构造查询。

这就是抛出我的东西:我回显$ query变量,我可以看到查询是正确形成的,但是当我尝试打印查询结果时,没有打印结果。

我在这里使用预处理语句进行了挣扎,并且在未能构造具有不同数量参数的预准备语句之后,决定尝试使代码在没有它们的情况下首先工作。在这篇文章的帮助下,我确实尝试过:LIKE query using multiple keywords from search field using PDO prepared statement

所以,暂时搁置准备好的陈述,谁能告诉我这里我做错了什么?任何帮助将不胜感激。

<?php
if(isset($_POST['submit'])) {

// define the list of fields
$fields = array('titleSearch', 'keywordSearch', 'fullSearch', 'fromYear', 'toYear', 
    'fromSeconds', 'toSeconds', 'withSound', 'withColor');
$conditions = array();

// loop through the defined fields
foreach($fields as $field){
    // if the field is set and not empty
    if(isset($_POST[$field]) && $_POST[$field] != '') {
        // create a new condition, using a prepared statement
        $conditions[] = "$field LIKE CONCAT ('%', $_POST[$field], '%')";
    }
}

// build the query
$query = "SELECT keyframeurl, videoid, title, creationyear, sound, color, 
     duration, genre FROM openvideo ";

// if there are conditions defined, append them to the query
if(count($conditions) > 0) {
    $query .= "WHERE " . implode(' AND ', $conditions);
}

//confirm that query formed correctly
echo $query; 

//print query results
foreach ($dbh->query($query) as $row){
   print $row['videoid'].' - '.$row['title'].'<br />';
}
}
?>

4 个答案:

答案 0 :(得分:1)

您忘记了直接插入查询的$ _POST值的引号:

$conditions[] = "$field LIKE CONCAT ('%', '$_POST[$field]', '%')";
                                          ^--            ^--

所以虽然这将解决你的直接问题,但你仍然会对sql注入攻击持开放态度。

答案 1 :(得分:1)

您必须运行,而不是发布您的查询 这是解决问题的唯一方法

  • Stack Overflow passer-by头脑中没有数据库服务器来运行您的查询。
  • Stack Overflow passer-by没有特定的数据库服务器来运行您的查询。

因此,您是唯一一个可以针对您的数据库运行查询并询问它出了什么问题的人。

  1. Turn on error reporting.确保您可以看到发生的错误。尝试添加故意错误,看看它是否有效。
  2. 如果数据库数据确实包含所需的值,请仔细检查它。
  3. 如果输入数据与数据库值非常匹配,请仔细检查输入数据。
  4. 在控制台或phpadmin中对数据库运行已汇编的查询。
  5. 挖掘某些问题。不要只是坐着等待。问一个问题“我有一个代码它不起作用”没有多大意义。代码必须运行,而不是盯着。

答案 2 :(得分:0)

$conditions[] = "$field LIKE CONCAT ('%', $_POST[$field], '%')";

是罪魁祸首:为标题发送“东西”最终会像

那样
WHERE titleSearch LIKE CONCAT('%', something, '%')

但你想要

WHERE titleSearch LIKE CONCAT('%', 'something', '%')

有更多报价。

请注意不要将其推广到制作中,因为你最终可能会发布“xxx”或者1 = 1; - “只是为了获得乐趣,或者更糟糕的是,加快他们的心情。” / p>

答案 3 :(得分:-1)

您甚至不需要CONCAT内置函数,您可以将整个字符串建模为$conditions[] = "{$field} LIKE '%{$_POST[$field]}%'"。但是如果你不希望在短期内面临严重的SQL注入攻击,你应该使用准备好的语句。

你为什么不尝试这样的事情? (以PDO为例):

if ($pdo = new \PDO("mysql:host=localhost;dbname=testdb;charset=utf8", "user", "password")) {
    $fields = ["titleSearch","keywordSearch","fullSearch","fromYear","toYear","fromSeconds","toSeconds","withSound","withColor"];
    $parameters = array_map(function ($input) { return filter_var($input, FILTER_SANITIZE_STRING); }, $fields)
    $conditions = array_map(function ($input) { return (!empty($_POST[$input]) ? "{$input} LIKE ?" : null); }, $fields);
    $query = "SELECT `keyframeurl`,`videoid`,`title`,`creationyear`,`sound`,`color`,`duration`,`genre` FROM `openvideo`" . (sizeof($conditions) > 0 ? " " . implode(" AND ", $conditions) : null);

    if ($statement = $pdo->prepare($query, [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY])) {
        if ($statement->execute((!empty($parameters) ? $parameters : null))) {
            $result = $statement->fetchAll(\PDO::FETCH_ASSOC);
        }
    }
}

还没有测试过(我现在才想到),但它应该设置PDO,根据你想要查找的条件准备一个语句,在execute()方法中添加参数(预过滤,虽然有 FAR 更好的过滤技术)并返回与您的查询相关的所有结果。

即使您决定不使用它,至少要考虑一下......这是PDO的一个很好的起点,当然,还有一个很好的GET / POST变量过滤教程(或使用第三方)像HTML Purifier这样的工具。)

希望有所帮助;)