迭代PDO查询的结果


Iterating over results of PDO query

我想基于URL参数中的数据使用PDO运行查询(是的,我知道这很容易受到攻击,但这是一个实用程序的内部代码)。

$user = 'USER';
$pass = 'PASSWORD';
$dsn = 'mysql:dbname=PRODUCTS;host=HOST'; 
try {
    $productDB = new PDO($dsn, $user, $pass); 
    $productDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
    $msg = 'PDO ERROR' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
    die($msg);
}
if(isset($_GET['cat'])) 
{
    $cat = $_GET['cat'];
    print "cat = $cat <br>";
    $products = $productDB->prepare('SELECT * FROM products WHERE cat_id LIKE ?');
    $products->execute(array($cat));
    $rows = $products->rowCount();
    print "$rows rows returned";
?>
<table border="1">
<tr>
    <td>product_id</td>
    <td>product_name</td>
</tr>
<?php
foreach ($products->fetchAll() as $row) {
    $id = $row['product_id'];
    $product_name = $row['product_name'];
    print "<tr>";
    print "<th scope='"row'"><b>$id</b></th>";
    print "<td> $product_name </td>";
    print "<tr>";
    }
print "</table>";
}
?>

当我运行这段代码时,它根据查询打印正确的行数,但不填充表。

我还尝试用:

替换prepareexecute行:
$products = $productDB->query("SELECT * FROM products WHERE cat_id LIKE $cat");

返回正确的行数,但没有其他帮助。

最后,我试着用这样的东西替换前一行:

$rows = $products->fetchAll();
foreach ($rows as $row) {

我尝试用固定的查询做同样的工作都很好,但我有麻烦,弄清楚如何在查询中放置一个变量元素,然后迭代结果。

您没有做任何事情来存储结果:

$products->execute(array($cat));

需要放在变量中:

$result = $products->execute(array($cat));

则不调用$products->fetchAll(),而使用$results->fetchAll():

foreach ($result->fetchAll() as $row)

我发现使用$query变量(prepare等)更容易,然后将结果转换为$result$product。使代码更容易阅读。

试试这个(如果我理解正确的话):

$products = $productDB->prepare("SELECT * FROM products WHERE cat_id LIKE :cat");
// Now, you can either do this :
$products->bindParam('cat', '%'.$cat.'%');
$products->execute();
// or you can call execute with an associative array of your parameterized query.
$products->execute(array('cat' => '%'.$cat.'%'));
// Then, get all the results like this :
$rows = $products->fetchAll();
foreach ($rows as $row) {
    // Do work here ..
}
// Or, like this :
while ($row = $products->fetch(PDO::FETCH_ASSOC)) {
    // Do work here ..
}

我个人更喜欢while,因为你不需要在一个变量中获取整个查询,减少了所需的内存量。

我还建议您使用FETCH_*参数,只获取您想要的数组类型。

顺便说一下,您需要知道rowCount不应该用于计算SELECT返回的行。正如php.net所说:

如果关联的PDOStatement执行的最后一条SQL语句是SELECT语句,一些数据库可能会返回该语句返回的行数。然而,这种行为并不能保证适用于所有数据库,也不应该依赖于可移植应用程序。