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>";
}
?>

このコードを実行すると、クエリに応じて正しい行数が出力されますが、テーブルにはデータが入力されません。

prepareまた、execute行を次のように置き換えてみました。

$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 ..
}

クエリ全体を 1 つの変数にフェッチせず、必要なメモリ量を削減できるため、私は個人的に while を好みます。

FETCH_*パラメータを使用して、必要な種類の配列のみを取得することもお勧めします。

ところで、SELECT によって返される行をカウントするためにrowCountを使用しないことを知っておく必要があります。php.netが言ったように:

関連付けられた PDOStatement によって実行された最後の SQL ステートメントが SELECT ステートメントであった場合、一部のデータベースは、そのステートメントによって返された行数を返す場合があります。ただし、この動作はすべてのデータベースで保証されているわけではなく、移植可能なアプリケーションに依存するべきではありません。

于 2013-01-03T21:18:29.247 に答える