2013-04-09 82 views
1

我已经成功地得到了查询的执行和PDO打印,但我在这里做得不对。这个问题的代码的重要部分在最后几代码块中;为了清晰起见,我将第一部分包括在内。使用PDO查询,没有准备好的语句,多得像来自多种HTML输入字段声明

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

这是抛出:我回声$查询变量,我可以看到,查询是否已正确形成,但是当我尝试打印查询结果,没有结果被打印出来。

我按倒在这里使用准备好的声明,并决定尝试让未能建立一个预处理语句具有不同的参数号码后,代码先工作,没有他们。我曾尝试,这个职位的帮助: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 />'; 
} 
} 
?> 
+0

尼斯[SQL注入孔](http://bobby-tables.com)。享受你的服务器pwn3d。 – 2013-04-09 18:51:40

+0

您的格式良好的查询是怎样的? – bestprogrammerintheworld 2013-04-09 19:08:18

+0

http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php – jycr753 2013-04-09 19:15:44

回答

1

你忘了周围的$ _ POST值的报价,你直接插入到你的查询:

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

因此,虽然这将解决您的眼前问题,您仍然是敞开的到SQL注入攻击。

+0

谢谢!这绝对是一个需要修复的问题,尽管我的代码在添加单引号后仍然没有执行查询。并澄清,我打算最终使用准备好的陈述,我只是遇到了麻烦,想试图让一个更简单的版本工作。这是将单引号添加到'$ _POST [$ field]'后打印的查询的示例:SELECT keyframeurl,videoid,title,creationyear,sound,color,duration,genre FROM openvideo WHERE titleSearch LIKE CONCAT(' ','future','%')并且带有声音LIKE CONCAT('%','withSound','%') – 2013-04-09 19:36:07

+0

然后进行一些适当的错误处理。例如'$ res = $ db-> query($ sql)或die($ db-> errorInfo());'。 – 2013-04-09 19:54:32

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

是罪魁祸首:送 “东西” 为标题在像

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

结束了,但你要

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

与更多的报价。

请务必不要把它推广到生产中,因为你最终可能会发布“xxx”)或1 = 1; - “只是为了表演的乐趣,或者更糟糕的是,在他们的情绪上有所不同。

+0

谢谢!我添加了单引号,但代码仍然没有执行查询,所以必须有一些额外的问题。别担心,我确实打算最终使用预先准备好的语句,我只想得到一个更简单的代码版本。下面是一个由此代码打印的查询示例:SELECT keyframeurl,videoid,title,creationyear,sound,color,duration,genre FROM openvideo WHERE titleSearch LIKE CONCAT('%','future','%')AND withSound LIKE CONCAT ('%','withSound','%') – 2013-04-09 19:39:05

1

而不是发布您的查询,你必须运行它。
这就是来解决这个问题

  • 堆栈溢出路人没有在他们的头一个数据库服务器来运行查询的唯一途径。
  • Stack Overflow passer-by没有特定的数据库服务器来运行您的查询。

那么,你是谁,可以对数据库运行查询,并要求它什么错唯一的一个。

  1. Turn on error reporting.确保您确定可以看到发生的错误。尝试添加故意错误并查看它是否有效。
  2. 仔细检查您的数据库数据,如果它确实包含所需的值。
  3. 仔细检查您的输入数据是否与数据库值匹配。
  4. 在控制台或phpadmin中针对数据库运行您的汇编查询。

挖一些问题。不要只是坐着等。提出一个问题“我有一个代码,它不起作用”是没有意义的。代码必须运行,而不是盯着。

+0

感谢您检查错误的建议。我是一个初学者,并没有开发一个好的调试工具包,所以这非常有帮助。 – 2013-04-10 00:20:30

-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,准备根据你似乎寻找条件的声明,在​​方法中添加参数(预过滤,虽然有FAR更好的过滤技术),并返回与您的查询相关的所有结果。如果你决定不使用这个,至少应该考虑一下......这是PDO的一个很好的起点,当然,你可以在GET/POST变量过滤器上获得一个很好的教程(或者使用3rd-就像这个问题一样,使用HTML Purifier等第三方工具)。

希望帮助;)