0
$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. 如果查询只是SELECTor ,我真的需要准备好的语句SELECT COUNT吗?
    因为,如果INSERT / UPDATE / DELETE表上没有任何操作 - 我想没有 sql 注入或垃圾邮件的危险?

  2. try/catch每次去数据库时我真的需要声明吗?

4

4 回答 4

2

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

于 2013-01-09T19:36:17.680 回答
2

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

$username = mysql_real_escape_string($username); // escape the string first.
$query = "SELECT 1 FROM users WHERE username = '$username'";
于 2013-01-09T19:36:40.707 回答
2

1)不,您不必使用准备好的语句;您可以使用例如 PDO::query 和 PDO::quote 来构建使用字符串连接的查询。但是——是的,任何时候你使用外部提供的字符串,都存在 SQL 注入造成损坏的风险,即使你只是在做一个 SELECT。例如,攻击者可以尝试使用“;”在一个语句中运行两个语句。在提供的字符串中。PDO::quote 是防止这种情况的另一种方法。

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

于 2013-01-09T19:37:16.870 回答
1

就与数据库的连接而言,这是您需要的唯一方法。尝试并抓住:(如果您使用的是 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

于 2013-01-09T19:38:37.900 回答