$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
<span style="font-size:14px;" data-filtered="filtered"></span>
이 경우 PHP는 단순히 sql 문을 mysql 서버로 보냅니다. 이것은 문자열을 이스케이프 처리한 다음 이를 SQL 문으로 연결하기 위해 mysql_real_escape_string을 일반적으로 사용하는 것과 다르지 않습니다. PDO 로컬 드라이버에 의해 이스케이프됨), 이 경우 분명히 SQL 주입이 발생할 수 있습니다. 즉, pdo 준비의 mysql_real_escape_string은 PHP에서 로컬로 호출되어 로컬 단일 바이트 문자 세트를 사용하여 쿼리를 작동합니다. 멀티바이트로 인코딩된 변수를 전달하더라도 여전히 SQL 주입 취약점이 발생할 수 있습니다(PDO를 사용할 때 PHP 5.3.6+로 업그레이드하는 것이 권장되는 이유를 설명하는 PHP 5.3.6 이전 버전의 문제 중 하나입니다. 그리고 그 이유는 다음과 같습니다). DSN 문자열에 문자 집합을 지정하는 방법은 mysql 서버에 대한 문자 집합을 지정하고 해당 변수를 MySQL 서버로 보내 문자 이스케이프를 완료하는 것입니다. 그렇다면 PHP 로컬 이스케이프를 비활성화하고 MySQL 서버를 이스케이프하도록 하는 방법은 무엇일까요?
PDO에는 PHP를 사용하여 로컬에서 준비를 시뮬레이션할지 여부를 나타내는 PDO::ATTR_EMULATE_PREPARES라는 매개변수가 있습니다. 그리고 방금 본 패킷 캡처 및 분석 결과에 따르면 PHP 5.3.6입니다. + 여전히 기본적으로 로컬 변수를 사용하며 이를 SQL로 연결하여 MySQL 서버로 보냅니다. 이 값을 false로 설정했습니다.$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$stmt = $pdo->prepare('select * from user where id=?');
$id = 1;
$stmt->bindParam(1,$id);
$stmt - >execute();
$pdo = new PDO('mysql:host=localhost;dbname=test
;charset=utf8', 'root');
다음 질문이 있습니다. charset이 DSN에 지정되어 있으면, 여전히 세트 이름 8dfab5cd353228de2a245e6f3e44b919을 실행해야 합니까?
예, 생략할 수 없습니다.
세트 이름 8dfab5cd353228de2a245e6f3e44b919에는 실제로 두 가지 기능이 있습니다:
A. 클라이언트(PHP 프로그램)가 제출한 인코딩
B. 클라이언트가 결과에 필요한 인코딩을 mysql 서버에 알려줍니다. 즉, 데이터 테이블이 gbk 문자 세트를 사용하고 PHP 프로그램이 UTF-8 인코딩을 사용하는 경우 쿼리를 실행하기 전에 세트 이름 utf8을 실행하여 mysql 서버에 이를 올바르게 인코딩하도록 지시할 수 없습니다. 프로그램에서 인코딩을 변환해야 합니다. 이러한 방식으로 우리는 utf-8 인코딩으로 mysql 서버에 쿼리를 제출하고, 얻은 결과도 utf-8 인코딩으로 표시됩니다. 이렇게 하면 프로그램에서 변환 인코딩 문제가 해결됩니다. 이렇게 하면 잘못된 코드가 생성되지 않습니다. 그렇다면 DSN에서 문자 세트를 지정하는 역할은 무엇입니까? 로컬 드라이버가 이스케이프할 때 지정된 문자 세트를 사용한다고 PDO에 알리고(mysql 서버 통신 문자 세트를 설정하지 않음) mysql 서버를 설정합니다. 통신 문자 세트의 경우에는 set names 8dfab5cd353228de2a245e6f3e44b919 명령도 사용해야 합니다. 관련 추천 :
위 내용은 mysql에 대한 PDO 연결이 주입을 방지할 수 있는 이유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!