$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");
}
这一切都有效,但是:
如果查询只是SELECT
或SELECT COUNT
,我真的需要准备好的声明吗?
因为,如果表上没有INSERT / UPDATE / DELETE
操作 - 我认为没有SQL注入或垃圾邮件的危险吗?
每次去数据库时,我真的需要try/catch
语句吗?
答案 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();
这是一个很好的教程,如果你从来不知道