Search code examples
phpmysqlmysqliprepared-statementsql-injection

Prepared queries vs constructed queries


I see the oft-repeated comment "always use prepared queries to protect against SQL injection attacks".

What is the practical difference between using a prepared query and a constructed query where user input is always sanitized?

Constructed

function quote($value) {
  global $db; 
  return "'" . mysqli_real_escape_string($db, $value) . "'";
}

$sql = "INSERT INTO foo (a, b) VALUES (" . quote($a) . "," . quote($b) . ")";

Prepared

$stmt = mysqli_prepare($db, "INSERT INTO foo (a, b) VALUES (?, ?)");
mysqli_stmt_bind_param($stmt, "ss", $a, $b);

Aside from verbosity and style, what reasons would I want to use one over the other?


Solution

  • Prepared queries are sent to the SQL server separate from the parameters, meaning that they only need to be compiled/optimized once if executed multiple times (e.g. with varying parameters). This can be quite significant with large datasets.

    Other than that, they are functionally identical provided the input is actually properly escaped in all cases when using non-prepared queries.

    That said, prepared queries are a lot less prone to oversights, usually resulting in better maintainability.

    Edit: Also check out @eggyal's comment as to why prepared statements are always injection-safe as opposed to escaped query parameters.