prepare()
seems a bit tedious and unnecessary for a majority of my code. If I send a string in a SQL command, why can't I just sanitize it with real_escape_string
? What's the difference? That's what I've been doing all the time and it worked well against SQL injections... Thanks.

- 1,687
- 2
- 12
- 18
-
1Well for one, `*_real_escape_string` methods are DB specific, whereas `PDO::prepare` is portable. – jszobody Jan 03 '14 at 17:42
-
3It works well against injections right up until _you forget to do it_ :) – Michael Berkowski Jan 03 '14 at 17:42
-
It's tedious but not unnecessary. But I don't really see how it is significantly more tedious than escaping each variable using the appropriate `escape_string` method? – Pekka Jan 03 '14 at 17:43
-
2@Shahar Trust me, you'll forget it – hek2mgl Jan 03 '14 at 17:43
-
2@Shahar What about the other guy who will be working on your code at some point? Sometimes "best practice" isn't just for you, but making sure your app is developed well for the next person who takes over. – jszobody Jan 03 '14 at 17:44
-
Why is typing a shorter function name more tedious? – vascowhite Jan 03 '14 at 17:45
-
2@JohnConde That doesn't address `real_escape_string`. – Shahar Jan 03 '14 at 17:45
-
1http://stackoverflow.com/a/20767765/46675 – Mike B Jan 03 '14 at 17:53
-
@vascowhite A short function name `prepare()` combined with all the other nonsense in MySQLi's prepared statement API (compared to PDO's easier one) is kinda tedious – Michael Berkowski Jan 03 '14 at 18:03
1 Answers
Escaping is just as effective at SQL injection defense as using query parameters.
Both methods are also less effective if you fail to do them consistently.
Both methods are useful only for protecting individual values in SQL expressions. They don't support other dynamic parts of the query. For example, if you want to ORDER BY a user-specified column. Neither query parameters nor escaping functions handle that.
So basically, it is a matter of style and personal preference.
I prefer query parameters because I think this:
$sql = "INSERT INTO mytable (columna, columnb, columnc) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$a, $b, $c]);
Is more clear than this:
$sql = "INSERT INTO mytable (columna, columnb, columnc) VALUES ('".mysqli_real_escape_string($conn, $a)."', '".mysqli_real_escape_string($conn, $b)."', '".mysqli_real_escape_string($conn, $c)."')";
mysqli_query($conn, $sql);
You can't seriously be saying that fiddling with all those open-quotes/close-quotes and .
string concatenation is easier than using prepare() with query parameters.
Re your comments about a hypothetical query()
function with parameters.
First of all, it's not necessary. Using prepare() and execute() together is a small price to pay for writing secure code, and by insisting on doing it with a single function, you just sound lazy. I suppose you don't check the return value of functions that return false
on error, either?
For what it's worth, it'd be easy to write a wrapper function to do both, because PHP supports varargs implicitly.
function myquery() {
global $pdo;
$params = func_get_args();
$sql = array_shift($params);
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return $stmt; // so we can fetch(), etc.
}

- 538,548
- 86
- 673
- 828
-
3
-
1@Shahar, that usage is not supported by PDO::query(). Where did you see that? – Bill Karwin Jan 03 '14 at 18:02
-
@Shahar, there is no pdo_query() function. PDO is used only in an object-oriented calling style. – Bill Karwin Jan 03 '14 at 18:05
-
@Shahar it is "foolproof" in that it is completely made-up syntax and will never run no matter how many times you ask about it. That is not valid syntax for either PDO or mySQLi. – Sammitch Jan 03 '14 at 18:05
-
1As for being foolproof, query parameters are *safe* when used consistently, just like escaping is. No API can protect against fools. – Bill Karwin Jan 03 '14 at 18:06