问题
Since all SQL queries should be prepared to prevent SQL injections, why are we allowed to write and execute non-prepared queries? Doesn't this seem counterintuitive?
回答1:
In cases where the query is a fixed string and does not need any program variables, it's safe to use query()
to run it.
Here's the example from https://www.php.net/manual/en/pdo.query.php:
<?php
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
print $row['name'] . "\t";
print $row['color'] . "\t";
print $row['calories'] . "\n";
}
The query has no PHP variables in it. The query()
is sufficient, and accomplishes the same as prepare()
and execute()
.
If you need to substitute PHP variables for values in SQL expressions, then you would use parameters:
$sql = 'SELECT name, colour, calories FROM fruit
WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql);
$sth->execute(array('calories' => 150, 'colour' => 'red'));
You might find that this is more common in your application than running a fixed query.
回答2:
Even if you require using prepared statements, there's no way to prevent the prepared statement from being created from variable substitution. E.g.
$sql = "SELECT * FROM someTable WHERE id = $id";
$stmt = $conn->prepare($sql);
回答3:
Bound parameters and query preparation are two different things. You can do one or the other or both.
You need to bind parameters to prevent SQL injection. However, there are things that cannot be passed as parameters (e.g. ORDER BY list), in which case you can concatenate the desired SQL syntax directly into the SQL string. This is called "dynamic SQL" and should generally use only whitelisted strings to prevent SQL injection.
So to answer (what I think was) you question: dynamic SQL is allowed because there are cases not covered by the bound parameters.
来源:https://stackoverflow.com/questions/61616604/if-all-sql-queries-should-be-prepared-to-prevent-sql-injections-why-does-the-sy