2017-05-18 6 views
2

:mysqli가 매개 변수화 된 쿼리를 사용할 때 명령문 당 2 줄의 로그를 만들고 ORM이 하나만 만드는 이유는 무엇입니까? 나는이 같은 문장을 참조 PHP로 매개 변수화 된 쿼리와 <code>mysqli</code>를 사용할 때 <code>general</code> MySQL의 로그를 보면

Prepare SELECT * FROM my_table WHERE id = ? 
Execute SELECT * FROM my_table WHERE id = 9 
Prepare INSERT INTO my_table SET name = ? 
Execute INSERT INTO my_table SET name = 'Alex' 

이 내가 분명히 첫 번째를보기 때문에 나를 따뜻하고 퍼지 느낌은, 내 쿼리가 전송되었습니다 , 그리고 그것들, 나의 매개 변수들, 두 개의 분리 된 진술에서. 내가 문 같은 시퀀스 파라미터 다음에 전송되는 것을 볼하지 않는 한이 날, 경고 느낌이있다

Query SELECT t0.id AS id_1, t0.name AS name_2 FROM my_table t0 WHERE t0.id = '9' 
Query START TRANSACTION 
Query INSERT INTO my_table (name) VALUES ('Alex') 
Query COMMIT 

: (이 경우에는 교리)는 ORM을 사용하는 경우

는하지만, 나는 다음을 참조하십시오. 하나의 문장 + 매개 변수입니다. 두 개의 패킷을 기록, mysqli처럼 기본적으로 수행 -

  • 교리가 실제로 매개 변수가있는 문을 사용하여, 그리고 왜 MySQL은 무엇을하지 않습니다 : 나는가 된 것으로 이것에 대해

    질문?

  • Doctrine은 지금하고있는 일이든간에 주입 공격으로부터 안전합니까?
  • Doctrine은 문과 매개 변수를 동일한 단일 쿼리로 쿼리별로 처리 할 때 공격으로부터 어떻게 안전합니까? 여기에 실제로 다른 것을합니까? 나는 특별히 교리 라이브러리를 모르는 동안

답변

1

Doctrine은 대부분의 경우 내부적으로 PDO를 사용합니다.

http://php.net/manual/en/pdo.prepare.php

부분적으로 말한다 :

PDO 준비된 문/기본적를 지원하지 않는 드라이버에 대한 바인딩 매개 변수를 에뮬레이트하고있는 경우도, 더 적절한 뭔가 이름 또는 물음표 스타일 매개 변수 마커를 재 작성 할 수 있습니다 드라이버는 한 스타일을 지원하지만 다른 스타일은 지원하지 않습니다.

준비된 문을 에뮬레이션 할 때 응용 프로그램이 실행되는 prepare()은 기본적으로 아무 작업도 수행하지 않습니다. PDO는 SQL 문자열을 저장하지만 그 시간에 데이터베이스 서버에 SQL 쿼리를 보내지 않습니다.

그런 다음 execute()을 호출하면 적절한 문자열 이스케이프를 사용하여 매개 변수 값을 쿼리의 적절한 위치에 복사합니다. 그런 다음 최종 문자열을 데이터베이스 서버로 최종 전송합니다. 준비는 데이터베이스 서버에서 수행되지 않고 그대로있는 그대로 쿼리를 실행합니다.

이것은 PDO가 대부분의 브랜드가 하나 또는 다른 스타일을 지원하지만 둘 다 지원하지 않더라도 RDBMS의 모든 브랜드에 대해 위치 (?) 및 명명 된 (:param) 매개 변수를 모두 지원하는 방법이기도합니다.

준비된 문을 에뮬레이션 할 수 없게되면 준비 로그와 실행 행이 모두 쿼리 로그에 나타납니다. !

$pdo = $entityManager->getConnection()->getWrappedConnection(); 
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
+0

우수한 ... 나는 그것을 준비하고 또한이 변경 – Dennis

+1

후 실행하고 시작 확인이 누군가에게 도움이 될 수 있습니다 :이 교리에이 방법을 수행 할 수 있습니다 믿고 http://stackoverflow.com/questions/31089893/doctrine-doesnt-persist-entity-boolean-values-and-pdoattr-emulate-prepar – Dennis

1

, 내가 MySQL의 로그를 말할 수 있고 무엇을 멀리 DB에 관한 한 일인지 :

첫 번째 예는 (준비/실행) 준비된 문을 사용하여 후자 (쿼리)는 그렇지 않습니다. 준비된 문은 기본적으로 성능 및 보안과 관련된 여러 가지 장점이 있습니다 (앞에서 언급 한 것처럼 SQL 주입을 피함). 준비된 문을 사용하지 않은 ORM을 개인적으로 피할 것입니다. 일반적으로 쿼리를 실행하는 최상의 방법으로 간주되기 때문입니다 응용 프로그램 내에서.

Doctrine이 SQL 주입으로부터 보호하기 위해 내부적으로 위생을하지 않는다고 말하는 것은 아닙니다. 동시에, 준비된 진술을 사용하는 것이 더 효과적 일 것이고, 나는 왜 그렇게하지 않았는지 알 수 없다.