【问题标题】:PHP PDO: SELECT array within IN()PHP PDO:在 IN() 中选择数组
【发布时间】:2012-08-23 21:43:50
【问题描述】:

我玩游戏有点晚了,正在尝试从 mysql_* 过渡到 PDO,同时尝试应对当前的挑战。我有一个接口,我在其中捕获数组中的框编号值,并且该数组按行项存储在另一个数组中(为了清楚起见,这些是嵌套数组)。

我的主要目的是获取特定行项目的箱号并运行 mysql 选择查询以返回给定的一组箱中的单元数。如果框中的数量不是用户认为的数量,我希望它抛出错误。

目前我的挑战是我得到一个空的结果集。我相信这是由于我的框号数组没有正确传递给 PDO 选择语句。任何想法或指导将不胜感激。

这是我目前所拥有的:

$Boxes = $_POST['Boxes']; //this includes box numbers within an array for each line item of a form

$e = 0;

while($e<$num1){
$units = 0;
$r = 0;
$SO_Line_Item=mysql_result($result1,$e,"SO_Line_Item");

    foreach ($Boxes[$e] as $a => $b)  // the purpose of this loop is to take the values from Boxes and store it in $zzz which I hope to use in my Select statement below.
    {
    $zzz[] = $Boxes[$e][$r];
    $r++; 
    }
   //end inner foreach

$BNs= implode(',', $zzz);

$db = new PDO('mysql:host=XXXXXX ;dbname=XXXXXX', $dbuser,$dbpass);
$stmt = $db->prepare("SELECT Box_Num,Timestamp,SN,Assy_Status FROM Current_Box WHERE Box_Num IN(' . $BNs . ')");
$stmt->execute($zzz);   

$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($results); // this shows up as an empty array

}  
$e++;
}

【问题讨论】:

  • 在查询中直接使用 $_POST 数据很容易受到 SQL 注入攻击。您必须在将您从 $_POST 获取的各个项目插入查询字符串之前对其进行转义。
  • 这不是使用 PDO 的好处吗?
  • 只使用 pdo 并不能使您安全,就像驾驶带安全带的汽车不会使您安全一样,除非您确实系好安全带。 PDO 允许使用准备好的语句/占位符,但您实际上并没有使用它们,因此您的 PDO 实际上与旧的 mysql_*() 函数一样“不安全”。话虽这么说,当使用任意的IN(...) 子句时,占位符会落到他们的脸上,而实际上您确实需要做一些动态的事情来说服 PDO 使用它。
  • 我明白你在说什么...除了转义如果我将 $BNs 更改为 $BNs= implode(',', array_fill(0,count($zzz), '?') );这不会在我的 SELECT IN(...) 语句中创建占位符吗?那么我可以遍历 $zzz 的每个实例以获得所需的结果吗?试一试,似乎缺少了什么。我认为这应该更多地朝着准备好的声明方向发展,在提供预期结果的同时创造一些安全性。
  • count() - 1,实际上,如果你是从 0 开始的话。但是,是的,这是基本的想法。占位符必须与其关联值进行 1:1 匹配,因此您生成 ?,?,?,... 系列并独立绑定每个值。它仍然是一个“自制”查询,但您插入的只是?,,因此注入潜力为0。

标签: php mysql loops pdo


【解决方案1】:

这样就搞定了。感谢 Marc B 的想法:

$e = 0;

while($e<$num1){
$units = 0;
$r = 0;
$SO_Line_Item=mysql_result($result1,$e,"SO_Line_Item");

    foreach ($Boxes[$e] as $a => $b)  
    {

        $zzz[] = $Boxes[$e][$r];

$ce = count($Boxes[$e]);        

    $r++; 
    }
//end inner foreach

$products = implode(',', array_fill(0,$ce, '?'));

$db = new PDO('mysql:host=192.168.1.197 ;dbname=Tracking', $dbuser,$dbpass);
$stmt = $db->prepare("SELECT Box_Num,Timestamp,E3_SN,Assy_Status FROM Current_Box WHERE Box_Num IN( $products )");
$stmt->execute($zzz);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
unset($zzz);
$e++;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 2011-02-18
    • 2012-05-20
    • 2017-03-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    相关资源
    最近更新 更多