4

我想根据 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>";
}
?>

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

我还尝试将prepareandexecute行替换为:

$products = $productDB->query("SELECT * FROM products WHERE cat_id LIKE $cat");

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

最后,我尝试将 foreach 行替换为:

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

我尝试对固定查询执行相同操作都可以正常工作,但是我无法弄清楚如何在查询中放置变量元素,然后遍历结果。

4

2 回答 2

3

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

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

需要进入一个变量:

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

然后,而不是调用$products->fetchAll(),使用$results->fetchAll()

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

$query我发现使用变量(forprepare等)更容易,然后将结果转换为$resultor之类的东西$product。使代码更易于阅读。

于 2013-01-03T21:18:50.207 回答
2

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

$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,因为您不会在一个 var 中获取整个查询,从而减少了所需的内存量。

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

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

如果关联 PDOStatement 执行的最后一条 SQL 语句是 SELECT 语句,则某些数据库可能会返回该语句返回的行数。但是,不能保证所有数据库都具有此行为,并且不应依赖于可移植应用程序。

于 2013-01-03T21:18:29.247 回答