Php 에서 PDO 로 Mysql 을 조회 하여 SQL 이 위험 을 주입 하지 않도록 하 는 방법

6415 단어 phppdomysql
우리 가 전통 적 인 my sql 을 사용 할 때connect 、mysql_query 방법 으로 데이터 베 이 스 를 조회 할 때 여과 가 엄격 하지 않 으 면 SQL 이 위험 을 주입 하여 사이트 가 공격 당 하고 통 제 력 을 잃 게 됩 니 다.my sqlreal_escape_string()함수 가 사용자 가 제출 한 값 을 필터 하지만 결함 도 있 습 니 다.PHP 의 PDO 확장 prepare 방법 을 사용 하면 sql injection 위험 을 피 할 수 있 습 니 다.
PDO(PHP Data Object)는 PHP 5 에 새로 추 가 된 중대 한 기능 입 니 다.왜냐하면 PHP 5 이전의 php 4/php 3 는 데이터베이스 확장 으로 각 데이터베이스 와 의 연결 과 처리,예 를 들 어 phpmysql.dll。 PHP 6 에서 도 기본적으로 PDO 방식 으로 연결 되 며,my sql 확장 은 보조 가 됩 니 다.공식:http://php.net/manual/en/book.pdo.php
1.PDO 설정 은 PDO 확장 을 사용 하기 전에 이 확장 을 사용 해 야 합 니 다.PHP.ini 에서"extension=php"를 제거 합 니 다.pdo.dll"앞의";"번호,데이터 베 이 스 를 연결 하려 면 PDO 와 관련 된 데이터 베 이 스 를 제거 해 야 합 니 다."번호pdo_mysql.dll),그리고 아파 치 서버 를 다시 시작 하면 됩 니 다.

extension=php_pdo.dll
extension=php_pdo_mysql.dll
2.PDO 연결 my sql 데이터베이스

$dbh = new PDO("mysql:host=localhost;dbname=db_demo","root","password");
는 기본적으로 긴 연결 이 아 닙 니 다.데이터베이스 긴 연결 을 사용 하려 면 마지막 에 다음 과 같은 매개 변 수 를 추가 해 야 합 니 다.

$dbh = new PDO("mysql:host=localhost;dbname=db_demo","root","password","array(PDO::ATTR_PERSISTENT => true)");
$dbh = null; //( )
3.PDO 설정 속성
1)PDO 는 세 가지 오류 처리 방식 이 있 습 니 다.
• PDO::ERrmODE_SILENT 는 오류 메 시 지 를 표시 하지 않 고 오류 코드 만 설정 합 니 다•PDO::ERrmoDEWARNING 경고 오류 표시•PDO::ERrmoDEEXCEPTION 이상 던 지기
다음 문 구 를 통 해 오류 처리 방식 을 PDO 로 설정 할 수 있 습 니 다.:ERrmoDESILENT 는 error Code()나 error Info()를 호출 하여 오류 정 보 를 얻 을 수 있 습 니 다.물론 다른 경우 에 도 가능 합 니 다.
2)데이터베이스 에 따라 되 돌아 오 는 필드 이름 의 대소 문자 처리 가 다 르 기 때문에 PDO 는 PDO:ATTR 를 제공 합 니 다.CASE 설정 항목(PDO 포함:CASELOWER,PDO::CASE_NATURAL,PDO::CASE_UPPER)되 돌아 오 는 필드 이름 의 대소 문 자 를 확인 합 니 다.
3)설정 을 통한 PDO::ATTRORACLE_NULLS 형식(PDO 포함:NULLNATURAL,PDO::NULL_EmpTY_STRING,PDO::NULL_TO_STRING)데이터 베 이 스 를 되 돌려 주 는 NULL 값 이 php 에 대응 하 는 수 치 를 지정 합 니 다.
4.PDO 의 일반적인 방법 과 그 응용 PDO:query()는 주로 결 과 를 기록 하고 되 돌아 오 는 작업 에 사 용 됩 니 다.특히 SELECT 작업 PDO:exec()는 결과 가 없 는 집합 에 대한 작업 입 니 다.예 를 들 어 INSERT,UPDATE 등 작업 PDO:prepare()는 주로 예비 처리 작업 입 니 다.$rs->execute()를 통 해 예비 처리 안의 SQL 문 구 를 실행 해 야 합 니 다.이 방법 은 인 자 를 연결 할 수 있 습 니 다.기능 이 비교적 강력 합 니 다(sql 주입 을 방지 하려 면 이것 만 사용 합 니 다)PDO:lastInsertId()는 마지막 삽입 동작 을 되 돌려 줍 니 다.홈 키 열 형식 은 증가 한 마지막 증가 IDPDOStatement 입 니 다.:fetch()는 기록 PDOStatement 을 가 져 오 는 데 사 용 됩 니 다.:fetch All()은 모든 기록 을 집합 으로 가 져 오 는 것 입 니 다.PDOStatement::fetch Column()은 결 과 를 가 져 오 는 첫 번 째 기록 을 지정 하 는 필드 입 니 다.결 성 은 첫 번 째 필드 PDOStatement:rowCount():주로 PDO:query()와 PDO:prepare()에서 DELETE,INSERT,UPDATE 작업 에 영향 을 미 치 는 결과 집합 으로 PDO::exec()방법 과 SELECT 작업 에 잘못 되 었 습 니 다.
5.PDO 작업 MYSQL 데이터베이스 인 스 턴 스

$db->setAttribute(PDO::ATTR_ERrmODE, PDO::ERrmODE_EXCEPTION);

<?php
$pdo = new PDO("mysql:host=localhost;dbname=db_demo","root","");
if($pdo -> exec("insert into db_demo(name,content) values('title','content')")){
echo " !";
echo $pdo -> lastinsertid();
}
?>

<?php
$pdo = new PDO("mysql:host=localhost;dbname=db_demo","root","");
$rs = $pdo -> query("select * from test");
$rs->setFetchMode(PDO::FETCH_ASSOC); //
//$rs->setFetchMode(PDO::FETCH_NUM); //
while($row = $rs -> fetch()){
print_r($row);
}
?>
통계 몇 줄 데이터

<?php
foreach( $db->query( "SELECT * FROM feeds" ) as $row )
{
    print_r( $row );
}
?>
prepare 방식

$sql="select count(*) from test";
$num = $dbh->query($sql)->fetchColumn();
Prepare 파라미터 화 조회

$stmt = $dbh->prepare("select * from test");
if ($stmt->execute()) {
 while ($row = $stmt->fetch()) {
     print_r($row);
 }
}
[다음은 sql 주입 을 어떻게 방지 하 는 지 에 중심 을 두 었 습 니 다]
PDO 를 사용 하여 MySQL 데이터 베 이 스 를 방문 할 때 실제 real prepared statements 는 기본적으로 사용 하지 않 습 니 다.이 문 제 를 해결 하기 위해 서 는 prepared statements 의 시 뮬 레이 션 효 과 를 사용 하지 않 아야 합 니 다.다음은 PDO 를 사용 하여 링크 를 만 드 는 예 입 니 다.

$stmt = $dbh->prepare("select * from test where name = ?");
if ($stmt->execute(array("david"))) {
 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
     print_r($row);
 }
}
setAttribute()줄 은 강제 적 입 니 다.PDO 에 아 날로 그 예비 처리 문 구 를 사용 하지 않 고 real pared statements 를 사용 하 라 고 알려 줍 니 다.이것 은 SQL 구문 과 해당 하 는 값 이 my sql 서버 에 전달 되 기 전에 PHP 로 해석 되 지 않도록 확보 할 수 있 습 니 다(가능 한 모든 악성 SQL 주입 공격 을 금지 합 니 다).파일 에 문자 집합 속성(charset=utf 8)을 설정 할 수 있 지만,이전 버 전의 PHP(<5.3.6)는 DSN 에서 문자 인 자 를 무시 합 니 다.
우 리 는 완전한 코드 사용 실례 를 살 펴 보 자.

$dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
위의 이 코드 는 sql 주입 을 방지 할 수 있다.왜 일 까요?
prepare()를 호출 할 때 검색 어 는 데이터베이스 서버 에 보 냈 습 니 다.이 때 자리 표시 자 만 있 습 니까?사용자 가 제출 한 데 이 터 를 보 내지 않 았 습 니 다.execute()로 호출 될 때 사용자 가 제출 한 값 은 데이터베이스 에 전 송 됩 니 다.그들 은 따로 전 송 됩 니 다.둘 은 독립 적 이 고 SQL 공격 자 는 기회 가 없습니다.
그러나 우리 가 주의해 야 할 것 은 다음 과 같은 몇 가지 상황 이다.PDO 는 SQL 주입 을 예방 하 는 데 도움 이 되 지 않 는 다.
1,당신 은 자리 표시 자 를 양보 할 수 없 습 니까?한 그룹의 값 을 대체 합 니 다.예 를 들 어

$dbh = new PDO("mysql:host=localhost; dbname=demo", "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;
2.데이터 시트 이름 이나 열 이름 대신 자리 표시 자 를 사용 할 수 없습니다.예 를 들 어

SELECT * FROM blog WHERE userid IN ( ? );
3.자리 표시 자 를 사용 할 수 없습니다.다른 SQL 문법 대신:

SELECT * FROM blog ORDER BY ?;

좋은 웹페이지 즐겨찾기