【问题标题】:prepared statement in the loop循环中的准备好的语句
【发布时间】:2022-01-23 04:54:11
【问题描述】:

我有一个问题,我无法弄清楚太久。基本上我有一个带有用户名的表(表中的1个唯一用户名)和1个相应的图像文件。有些用户有图像文件,有些没有。用户名存储在数组 $Users[] 中。我正在尝试使用以下方法为每个用户获取图像的文件名:

$stmt = $db->prepare("SELECT file_name FROM images WHERE BINARY username=?"); 
    for($temp1=0; $temp1<count($Users); $temp1++){
        $stmt->bind_param("s", $Users[$temp1]);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($ImgFileName);
        $stmt->fetch();
        $imageURL[$temp1]=$ImgFileName;
    }

但是这有烦人的行为。假设代码循环通过,如果用户 User[0] 具有与之相关的 $ImgFileName,但 User[1]、User[2] 等没有,则 $ImgFileName 用于最后一个具有可用图像的用户,而不是 null。这种情况会发生,直到循环中的某个用户再次在表中具有图像文件名。因此,如果我在循环通过后打印 $imageURL[] 数组,它看起来像:

$Users[]=[user1,user2,user3,user4,user5]
$imageURL[]=[img001.png,img001.png,img001.png,img231.png,img124.png,img124.png]

而不是

$Users[]=[user1,user2,user3,user4,user5]
$imageURL[]=[img001.png,,,img231.png,img124.png,]

有人知道为什么吗?

【问题讨论】:

  • 我很确定使用 PDO 会容易 10 倍。你为什么要使用 mysqli 这样做?
  • 其实我只是通过做一些项目来学习 php、javascript 并没有真正使用过 pdo 。但会看看。谢谢
  • 如果你刚刚开始学习 PHP,那么你应该学习 PDO 而不是 mysqli。 PDO 更容易,更适合初学者。从这里开始phpdelusions.net/pdo & websitebeaver.com/…
  • 谢谢。从sql注入的角度来看,另一种方法更好吗?或者可能有任何其他安全功能?
  • 不,在安全方面它们是相同的。两者都提供准备好的语句,PDO 具有更多功能,使编码更加容易。

标签: php arrays loops mysqli


【解决方案1】:

原因是因为您从未在循环内重置$ImgFileName

$ImgFileName = null; 放入循环中。

您也可以取消设置变量,这将导致相同的结果。

for($temp1=0; $temp1<count($Users); $temp1++){
    $stmt->bind_param("s", $Users[$temp1]);
    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result($ImgFileName);
    $stmt->fetch();
    $imageURL[$temp1]=$ImgFileName;

    unset($ImgFileName);
}

【讨论】:

  • 嗯,很奇怪,我试过了,确实有效。我希望每当 sql 语句给出 null 时,如果我只是为一个没有文件名的用户运行它,它会自动绑定 $ImgFileName = null;。很高兴我问了,因为我没想到会这样。非常感谢,爵士。
  • @lucaamarelli 当准备好的语句没有找到任何行时,它不会返回任何值,甚至不会返回 null。
  • 是的,现在我可以看到了。学过的知识。再次感谢您。
【解决方案2】:

另一种方法是将文件名存储在一个数组中,并以名称作为索引(同时确保图像名称每次都被空白)...

for($temp1=0; $temp1<count($Users); $temp1++){
    $ImgFileName = '';
    $userName = $Users[$temp1];
    $stmt->bind_param("s", $userName);
    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result($ImgFileName);
    $stmt->fetch();
    $imageURL[$userName] = $ImgFileName;
}

如果您还结合使用 in(来自 How do you use IN clauses with mysqli prepared statements),您可以在一次执行中获取已知用户和文件名的列表...

$stmt = $db->prepare("SELECT username, file_name
                       FROM images 
                       WHERE username in...

只需循环遍历结果并将它们添加到数组中。

【讨论】:

    猜你喜欢
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 2012-04-04
    • 2018-08-29
    • 2011-07-01
    相关资源
    最近更新 更多