如何为PDO预处理语句设置查询

时间:2012-01-06 08:00:45

标签: php sql pdo prepared-statement

我已经构建了一个PDO连接和查询,现在我需要它从SQL注入安全

这是我的代码

用户输入

<?php $search=$_GET["Search"];?>

查询数据库的SQL

<?php
// Issue the query
$Recordset1 = $dbh->query("SELECT * FROM catelogue 
WHERE catelogue.TITLE LIKE '$search'");
$Recordset1->setFetchMode(PDO::FETCH_ASSOC);
?>

获取行

<?php $row_Recordset1 = $Recordset1-> fetch(); ?>

在此之后,有一个带有do-while循环的表来显示返回的所有内容

如何为我的查询制作准备好的声明?

由于

编辑:

好的,DavdRew发布的最后一段代码有助于我的搜索再次运行。现在我有两个新问题。

问题1:在做了几个查询后,我收到了这条消息

mysql_pconnect()[function.mysql-pconnect]:MySQL服务器已经消失

它仍会显示我搜索的内容的其余部分。这是如何解决的?

然后问题2:

每次搜索时,返回的第一条记录为空,为空白记录。以前从未这样做过,为什么现在这样做呢?

非常感谢DavdRew

编辑:添加更多代码

这是整个PDO代码

<?php 

$hostname_EchosPDO = "localhost";
$username_EchosPDO = "echos";
$password_EchosPDO = "echos";
$database_EchosPDO = "full catelogue";
$connStr = 'mysql:host=localhost;dbname=full catelogue';

try {
    $dbh = new PDO($connStr, $username_EchosPDO, $password_EchosPDO);
    /*** echo a message saying we have connected ***/
    echo 'Connected to database';
    }
catch(PDOException $e)
    {
    echo $e->getMessage();
    } 
?>


<?php


$q = $dbh->prepare("SELECT * FROM catelogue WHERE catelogue.TITLE LIKE ?"); // prepare statement
if ($q->execute(array('sharpay%'))) // execute wirh passed params array($search)
{
    $row_Recordset1 = $q->fetchAll(PDO::FETCH_ASSOC); // store fetched result into $rows;

}
else
{
    $error = $dbh->errorInfo();
    throw new Exception("SQLSTATE: {$error[0]}. {$error[1]} {$error[2]}");
}


?>
<?php /* $row_Recordset1 = $Recordset1-> fetch(); */ ?>


<?php do { ?>
<table width="800" border="0">
          <tr>
          <form action="/Echos Online/Detail.php" method="get"><input value='<?php echo $row_Recordset1['CAT NO.']; ?>' name="detail" type="hidden"/><td width='100' rowspan='4'><input type="image" img src="<?php echo $row_Recordset1['IMAGE PATH']; ?>" width="<?php if ($row_Recordset1['FORMAT']=='DVD') {echo "70";} else if ($row_Recordset1['FORMAT']=='DVD+CD') {echo "70";} else if($row_Recordset1['FORMAT']=='BLURAY+CD') {echo "81";}else if($row_Recordset1['FORMAT']=='BLURAY+DVD') {echo "81";} else if($row_Recordset1['FORMAT']=='BLURAY') {echo "81";} else {echo "100";} ?>" height="100"></td></form>
            <td width="100">Artist:</td>
            <td><?php echo $row_Recordset1['ARTIST']; ?></td>
          </tr>
          <tr>
            <td width="100">Title</td>
            <td><?php echo $row_Recordset1['TITLE']; ?></td>
          </tr>
          <tr>
            <td width="100">Format</td>
            <td><?php echo $row_Recordset1['FORMAT']; ?></td>
          </tr>
          <tr>
            <td width="100">Cat. No.</td>
            <td><?php echo $row_Recordset1['CAT NO.']; ?></td>
          </tr>
          <hr background-color="#e4a566" color="#e4a566"; width="100%"/>
  <?php }  while ($row_Recordset1 = $q-> fetch());  ?>
</table>

老实说,现在我正在回到preg_replace和mysql_real_escape_string

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

像这样:

$q = $this->pdo->prepare($query);

$data = array();
if ($q->execute($params)) // params is the array of values for each '?' in your prepared statement.
    $data = $q->fetchAll($fetch);
else
{
    $error = $this->pdo->errorInfo();
    throw new \Exception("SQLSTATE: {$error[0]}. {$error[1]} {$error[2]}");
}

return $data;

请注意WHERE IN 效果不佳,您需要将尽可能多的?放入由,内爆并被IN (包裹的内容中从左边开始,)右边。 例如:

$statement = $pdo->prepare('SELECT * FROM my_table AS m WHERE m.id = ?');
if ($statement->execute(array(24))) // here you can pass values too.
     $data = $q->fetchAll(\PDO::FETCH_ASSOC);
else
     exit('Shit happens');

使用id = 24;

搜索记录

对于您的代码,那将是:

$q = $dbh->prepare("SELECT * FROM catelogue WHERE catelogue.TITLE LIKE ?"); // prepare statement
if ($q->execute(array($search))) // execute wirh passed params array($search)
{
    $rows = $q->fetchAll(PDO::FETCH_ASSOC); // store fetched result into $rows;
}
else
{
    $error = $dbh->errorInfo();
    throw new Exception("SQLSTATE: {$error[0]}. {$error[1]} {$error[2]}");
}

输出:

<table width="800" border="0">
    <?php foreach ($rows as $row): ?>
        <tr>
            <form action="/Echos Online/Detail.php" method="get"><input value='<?php echo $row['CAT NO.']; ?>' name="detail" type="hidden"/><td width='100' rowspan='4'><input type="image" img src="<?php echo $row['IMAGE PATH']; ?>" width="<?php if ($row['FORMAT']=='DVD') {echo "70";} else if ($row['FORMAT']=='DVD+CD') {echo "70";} else if($row['FORMAT']=='BLURAY+CD') {echo "81";}else if($row['FORMAT']=='BLURAY+DVD') {echo "81";} else if($row['FORMAT']=='BLURAY') {echo "81";} else {echo "100";} ?>" height="100"></td></form>
            <td width="100">Artist:</td>
            <td><?php echo $row['ARTIST']; ?></td>
        </tr>
        <tr>
            <td width="100">Title</td>
            <td><?php echo $row['TITLE']; ?></td>
        </tr>
        <tr>
            <td width="100">Format</td>
            <td><?php echo $row['FORMAT']; ?></td>
        </tr>
        <tr>
            <td width="100">Cat. No.</td>
            <td><?php echo $row['CAT NO.']; ?></td>
        </tr>
        <hr background-color="#e4a566" color="#e4a566"; width="100%"/>
    <?php endforeach; ?>
</table>

答案 1 :(得分:0)

$pdo = new PDO('mysql:host=localhost;dbname=mydb', $username, $password);

$stmt = $pdo->prepare('SELECT * FROM catelogue WHERE catelogue.TITLE LIKE :search');
$stmt->bindValue('search', $search);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

OR 

$stmt = $pdo->prepare('SELECT * FROM catelogue WHERE catelogue.TITLE LIKE :search');
$stmt->execute(array('search' => $search);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

请注意,您可能希望将$ search字符串包含通配符,例如

$stmt->bindValue('search', '%'.$search.'%');

另请注意,如果您在类似标准的左侧有通配符,则使用不会使用索引

$stmt->bindValue('search', '%'.$search.'%'); //will not use index
$stmt->bindValue('search', $search.'%'); //will use index