준비된 문은 SQL 주입에 대한 매우 유용합니다.
문 준비 및 바인드 매개 변수
준비된 문은 같은 실행하는 데 사용하는 기능입니다 (or similar) 높은 효율로 반복적으로 SQL 문을.
준비된 문은 기본적으로 다음과 같이 작동합니다 :
- 준비 : SQL 문 템플릿을 생성하고 데이터베이스로 전송됩니다. 특정 값은 매개 변수라고 지정되지 않은 남아 있습니다 (labeled "?") . 예 : MyGuests의 삽입 반 VALUES(?, ?, ?)
- 데이터베이스는, 구문 분석 컴파일하고, SQL 문 템플릿에 질의 최적화를 수행하고, 그것을 실행하지 않고 결과를 저장
- 실행 : 나중에 응용 프로그램은 매개 변수에 값을 결합하고, 데이터베이스는 문을 실행합니다. 그것은 서로 다른 값을 원하는대로 응용 프로그램은 문장을 여러 번 실행할 수 있습니다
직접 SQL 문을 실행에 비해 준비된 문은 두 가지 장점이 있습니다 :
- 준비된 문은 쿼리에 대한 준비가 한 번만 이루어집니다로서 구문 분석 시간을 단축 (although the statement is executed multiple times)
- 바인딩 매개 변수는 매개 변수 만 각 시간을 보낼 필요로하는 서버에 대역폭을 최소화, 그리고 전체 쿼리
- 나중에 다른 프로토콜을 사용하여 전송하는 매개 변수 값이 올바르게 이스케이프 할 필요가 있기 때문에 준비된 문은 SQL 주입에 대한 매우 유용합니다. 일본어 문장 템플릿 외부 입력으로부터 유래하지 않은 경우, SQL 인젝션 발생할 수 없다.
MySQLi에서 문 준비
다음의 예는 준비된 문 및 MySQLi 바운드 매개 변수를 사용합니다 :
실시 예 (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();
?>
코드 라인은 위의 예에서 설명합니다 :
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
우리의 SQL에서, 우리는 물음표 삽입 (?) 우리는 정수, 문자열, 더블 또는 BLOB 값을 대체 할.
그런 다음, 한 번 봐 가지고 bind_param() 함수를 :
$stmt->bind_param("sss", $firstname, $lastname, $email);
이 기능은 SQL 쿼리에 매개 변수를 결합하여 매개 변수가 무엇인지 데이터베이스를 알려줍니다. "sss" 인수는 매개 변수는 데이터의 유형을 나열합니다. 의 S 문자 매개 변수가 문자열이라고 mysql을 알려줍니다.
인수는 네 가지 유형 중 하나가 될 수 있습니다 :
- I - 정수
- D - 더블
- 의 - 문자열
- B - BLOB
우리는 각 매개 변수에 대해 다음 중 하나가 있어야합니다.
기대하는 데이터의 유형 MySQL의 이야기, 우리는 SQL 인젝션의 위험을 최소화 할 수 있습니다.
참고 : 우리가 외부 소스에서 데이터 삽입하려면 (like user input) , 데이터가 소독 및 검증하는 것이 매우 중요합니다.
PDO에서 문 준비
다음의 예는 준비된 명령문과 PDO 바운드 매개 변수를 사용합니다 :
실시 예 (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;
?>