我是否需要针对每个查询准备好声明?

时间:2013-01-09 19:33:06

标签: php pdo

$query = "SELECT 1 FROM users WHERE username = :username";
$query_params = array(':username' => $_POST['username']);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}

$row = $stmt->fetch();
if($row)
{
die("This username is already in use");
}

这一切都有效,但是:

  1. 如果查询只是SELECTSELECT COUNT,我真的需要准备好的声明吗? 因为,如果表上没有INSERT / UPDATE / DELETE操作 - 我认为没有SQL注入或垃圾邮件的危险吗?

  2. 每次去数据库时,我真的需要try/catch语句吗?

4 个答案:

答案 0 :(得分:2)

如果您在查询中放入了任何可以以任何方式更改的变量,您应该(必须)使用预准备语句。

答案 1 :(得分:2)

即使在SELECT语句上也始终存在SQL注入的危险,因为有人可以终止SELECT并在用户名中附加INSERT语句。但是,如果您使用的是mysql_real_escape_string(),或者您的DB类为您转义了值,那么您不必担心SELECT语句中的try / catch。如果你已经转义了你的值,这对你的SQL就足够了:

$username = mysql_real_escape_string($username); // escape the string first.
$query = "SELECT 1 FROM users WHERE username = '$username'";

答案 2 :(得分:2)

1)不,你不必使用准备好的陈述;你可以用例如PDO :: query和PDO :: quote使用字符串连接构建查询。但是 - 是的,只要您使用外部提供的字符串,即使您只是在执行SELECT操作,也存在SQL注入损坏的风险。例如,攻击者可以通过使用&#34 ;;"来尝试在一个语句中运行两个语句。在提供的字符串中。 PDO :: quote是另一种防范这种情况的方法。

2)你可以从你的调用代码中抛出错误,但在某些地方你必须考虑错误处理。

答案 3 :(得分:1)

就连接数据库而言,这是您需要的唯一方法。 Try and Catch :(如果您使用的是MySql数据库)

try {
    $conn = new PDO('mysql:host=localhost;dbname=DBNAME', 'USER', 'PASS', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

另外,还有一个内置计数查询计数:

$affected_rows = $stmt->rowCount();

这是一个很好的教程,如果你从来不知道

http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers