Przygotowane sprawozdania są bardzo przydatne przed SQL injection.
Przygotowane instrukcje i Związane Parametry
Przygotowane oświadczenie to funkcja używana do wykonywania tych samych (or similar) wielokrotnie SQL z wysoką wydajnością.
Przygotowane sprawozdania zasadzie działa tak:
- Przygotuj: AN SQL oświadczenie szablon jest tworzone i wysyłane do bazy danych. Pewne wartości pozostają nieokreślone, zwane parametry (labeled "?") . Przykład: INSERT NA MyGuests VALUES(?, ?, ?)
- Baza analizuje, kompiluje i wykonuje optymalizację zapytań na wyciągu SQL szablonu i zapisuje wynik bez wykonywania go
- Wykonanie: W późniejszym czasie, aplikacja łączy wartości parametrów, a baza danych wykonuje instrukcję. Aplikacja może wykonać instrukcję tyle razy, ile chce z różnymi wartościami
W porównaniu do wykonywania instrukcji SQL bezpośrednio Przygotowane sprawozdania mają dwie główne zalety:
- Przygotowane sprawozdania redukuje czas parsowania jako przygotowanie na zapytania odbywa się tylko raz (although the statement is executed multiple times)
- Związane parametry zminimalizować przepustowość do serwera, jak trzeba wysłać tylko te parametry za każdym razem, a nie cały zapytania
- Przygotowane sprawozdania są bardzo przydatne przed SQL injection, ponieważ wartości parametrów, które są przekazywane później użyć innego protokołu, nie muszą być prawidłowo uciekł. Jeśli oryginalny szablon oświadczenie nie pochodzi z zewnętrznego wejścia, SQL injection nie może wystąpić.
Przygotowane sprawozdania w MySQLi
W następującym przykładzie przygotowane instrukcje i parametry związane w MySQLi:
Przykład (MySQLi with Prepared Statements)
<?php
$servername = "localhost";
$username = "username";
$password =
"password";
$dbname =
"myDB";
// Create connection
$conn = new mysqli($servername,
$username, $password, $dbname);
// Check connection
if ($conn->connect_error)
{
die("Connection failed: " . $conn->connect_error);
}
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname,
$email);
// set parameters and execute
$firstname = "John";
$lastname
= "Doe";
$email = "[email protected]";
$stmt->execute();
$firstname
= "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$conn->close();
?>
linie kodu, aby wyjaśnić z powyższego przykładu:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
W naszym SQL, możemy wstawić znak zapytania (?) , Gdzie chcemy zastąpić w całkowitej wartości, łańcuch, podwójne lub kropelka.
Następnie spojrzeć na bind_param() funkcji:
$stmt->bind_param("sss", $firstname, $lastname, $email);
Funkcja ta wiąże parametry do kwerendy SQL i mówi do bazy danych, co parametry są. "sss" Argument zawiera listę typów danych, które parametry są. S postać mówi mysql, że parametr jest ciągiem.
Argumentem może być jednym z czterech rodzajów:
- I - liczba całkowita
- d - podwójne
- s - łańcuch
- B - BLOB
Musimy mieć jedną z nich dla każdego parametru.
Mówiąc mysql, jaki typ danych się spodziewać, możemy zminimalizować ryzyko SQL injection.
Uwaga: Jeśli chcemy wstawić żadnych danych ze źródeł zewnętrznych (like user input) , to jest bardzo ważne, że dane są odkażane i zatwierdzone.
Przygotowane sprawozdania w PDO
W następującym przykładzie przygotowane instrukcje i parametry związane w PDO:
Przykład (PDO with Prepared Statements)
<?php
$servername = "localhost";
$username = "username";
$password =
"password";
$dbname =
"myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname",
$username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
// prepare sql and bind
parameters
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (:firstname, :lastname, :email)");
$stmt->bindParam(':firstname', $firstname);
$stmt->bindParam(':lastname',
$lastname);
$stmt->bindParam(':email', $email);
// insert a row
$firstname =
"John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();
// insert another row
$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
// insert another row
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "New records created successfully";
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>