PDO를 사용하여 MySQL 데이터베이스에 액세스할 때 실제 준비된 명령문은 기본적으로 사용되지 않습니다. 이 문제를 해결하려면 준비된 문의 에뮬레이션 효과를 비활성화해야 합니다. 다음은 PDO를 사용하여 링크를 생성하는 예입니다.
코드는 다음과 같습니다.
$dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass'); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setAttribute() 이 줄은 필수이며 PDO를 알려줍니다. 가장을 비활성화하려면 명령문을 준비하고 실제 준비된 명령문을 사용하십시오. 이렇게 하면 SQL 문과 해당 값이 mysql 서버로 전달되기 전에 PHP에 의해 구문 분석되지 않습니다(가능한 모든 악성 SQL 주입 공격이 비활성화됨). 구성 파일에서 문자 세트 속성(charset=utf8)을 설정할 수 있지만 이전 버전의 PHP(< 5.3.6)는 DSN의 문자 매개변수를 무시한다는 점에 유의하는 것이 중요합니다.
전체 코드 사용 예를 살펴보겠습니다.
코드는 다음과 같습니다.
$dbh = new PDO("mysql:host=localhost; dbname=dbtest", "user", "pass"); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果 $dbh->exec("set names 'utf8'"); $sql="select * from test where name = ? and password = ?"; $stmt = $dbh->prepare($sql); $exeres = $stmt->execute(array($testname, $pass)); if ($exeres) { while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print_r($row); } } $dbh = null;
위 문단은 SQL 인젝션을 방지할 수 있는 코드입니다. 왜?
prepare()가 호출되면 쿼리 문이 데이터베이스 서버로 전송됩니다. 이때 자리 표시자만 전송되고 사용자는 없습니다. - 제출된 데이터가 전송됩니다.execute()가 호출되면 사용자가 제출한 값이 데이터베이스로 전송됩니다. 둘은 독립적이며 SQL 공격자는 기회가 없습니다.
그러나 우리가 주의해야 할 것은 다음과 같은 상황입니다. PDO는 SQL 삽입을 방지하는 데 도움이 되지 않습니다
1. 자리 표시자를 대체할 수는 없나요? , 예:
코드는 다음과 같습니다.
SELECT * FROM blog WHERE userid IN ( ? );
2. 자리 표시자로 데이터 테이블 이름이나 열 이름을 대체할 수 없습니다.
코드는 다음과 같습니다.
SELECT * FROM blog ORDER BY ?;
3. 다음과 같은 다른 SQL 구문을 자리 표시자로 대체할 수 없습니다.
코드는 다음과 같습니다.
SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;
위는 PDO의 SQL 인젝션 방지 메커니즘 내용입니다. 자세한 내용은 PHP 중국어 홈페이지(m.sbmmt.com)를 참고해주세요. !