Uso de preparedStatements
Prepared Statements e Bound Parameters
Os prepared statements son útiles para protexer fronte as inyeccións SQL. Son unha característica usada para executar o mesmo (ou similar) SQL statement (sentenza) repetidamente con alta eficiencia e seguridade.
Funcionan do seguinte xeito:
- Prepare: Unha plantilla da sentenza SQL (statement) é creada e enviada á base de datos. Algúns elementos chamados parámetros (etiquetados cun ?) son deixados sen completar. Por exemplo: INSERT INTO ExemploDeTaboa VALUES(?, ?, ?)
- A base de datos pasea, compila e realiza optimización da query coa plantilla da SQL e almacena o resultado sen executalo
- Execute: Nun momento posterior a aplicación conecta (binds) os valores aos parámetros (bound parameters), e a base de datos executa a sentenza. A aplicación pode executar a sentenza tantas veces como precise con diferentes valores.
Comparado coa execución de sentenzas SQL de xeito directo, as sentenzas SQL teñen as seguintes vantaxes:
- Prepared statements reduce o tempo de parseo xa que a preparación da query e feita só unha vez (ainda que é executado múltiples veces)
- Bound parameters minimizan o uso de ancho de bando do servidor xa que só precisa enviar os parámetros cada vez e non a query completa
- Prepared statements son útiles fronte a SQL injections xa os valores dos parametros, que son transmitidos despois usando un protocolo diferente, non poden ser escapados
Exemplo
O seguinte exemplo usa prepared statements e parametros conectados con MySQLi:
1 <?php
2 $servername = "localhost";
3 $username = "username";
4 $password = "password";
5 $dbname = "myDB";
6
7 // Create connection
8 $conn = new mysqli($servername, $username, $password, $dbname);
9
10 // Check connection
11 if ($conn->connect_error) {
12 die("Conexión fallou: " . $conn->connect_error);
13 }
14
15 // prepare and bind
16 $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
17 $stmt->bind_param("sss", $firstname, $lastname, $email);
18
19 // set parameters and execute
20 $firstname = "Shakira";
21 $lastname = "Mebarak";
22 $email = "shakira@example.com";
23 $stmt->execute();
24
25 $firstname = "Gerard";
26 $lastname = "Piqué";
27 $email = "gerard@example.com";
28 $stmt->execute();
29
30 $firstname = "Clara";
31 $lastname = "Chia";
32 $email = "clara@example.com";
33 $stmt->execute();
34
35 echo "Novos rexistros creados correctamente!";
36
37 $stmt->close();
38 $conn->close();
39 ?>
O código explicado:
Primeiro preparamos a query cos parámetros etiquetados con ?:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
Marcamos con interrogante onde queremos substituír un integer, string, double ou valor blob.
Entón usamos a función bind_param():
$stmt->bind_param("sss", $firstname, $lastname, $email);
Esta función conecta (binds) coa query sql e dille a base de datos qué parametros son. O argumento "sss" indica os tipos de datos dos parámetros, neste caso string. O argumento podería ser de catro tipos:
- i - integer
- d - double
- s - string
- b - BLOB
É preciso ter un para cada un dos parámetros. O indicarlle a MySQL que tipo de datos espera, minimizamos o risco de SQL injections.
IMPORTANTE. Se queremos insertar calquera data de fontes externas (coma un usuario introducindo datos nun formulario), e importante que o datos estén sanitized e validados.