programing

준비된 설명문을 사용할 *아니오* 때는?

css3 2023. 10. 17. 20:29

준비된 설명문을 사용할 *아니오* 때는?

최소한의 데이터베이스를 사용하는 PHP 기반 웹사이트를 재설계하고 있습니다.원래 버전은 인젝션 공격을 방지하고 데이터베이스 로직과 페이지 로직을 분리하기 위해 "pseudo-preaded-statement"(인용 및 매개 변수 교체를 수행한 PHP 함수)를 사용했습니다.

이러한 임시 기능을 PDO와 실제 준비된 문장을 사용하는 객체로 대체하는 것은 당연한 것처럼 보였지만, 이에 대한 제 판독을 해본 결과, 저는 확신할 수 없습니다.PDO는 여전히 좋은 아이디어인 것 같지만, 준비된 명세서의 주요 판매 포인트 중 하나는 재사용이 가능하다는 것입니다. 저는 결코 그렇게 하지 않을 것입니다.제 설정은 이렇습니다.

  • 그 진술들은 모두 아주 간단합니다.대부분은 형태를 갖추고 있습니다.SELECT foo,bar FROM baz WHERE quux = ? ORDER BY bar LIMIT 1. 로트에서 가장 복잡한 문장은 단지 3개의 그러한 선택들이 함께 결합되는 것입니다.UNION ALLs.
  • 각 페이지 히트는 최대 한 개의 문을 실행하고 한 번만 실행합니다.
  • 저는 호스트 환경에 있기 때문에 개인적으로 "스트레스 테스트"를 수행하여 서버를 강타할 가능성이 적습니다.

준비된 진술서를 사용하면 최소한 데이터베이스 왕복 횟수를 두 배로 늘릴 수 있기 때문에 이를 피하는 것이 좋을까요?사용해도 됩니까?PDO::MYSQL_ATTR_DIRECT_QUERY매개 변수화 및 주입 방어의 이점을 유지하면서 여러 번의 데이터베이스 이동에 따른 오버헤드를 방지할 수 있습니까?아니면 준비된 스테이트먼트 API에서 사용하는 바이너리 콜은 준비되지 않은 쿼리를 실행하는 것에 비해 충분히 성능이 좋습니까?

편집:

좋은 조언 감사합니다, 여러분.이것은 제가 한 가지 이상의 대답을 "받아들인" 것으로 표시할 수 있기를 바라는 것입니다. 즉, 많은 다양한 관점들 말입니다.하지만 궁극적으로 릭에게 응분의 응분의 답이 없었다면, 저는 모든 사람들의 충고를 따랐음에도 불구하고 행복하게 떠나 완전히 잘못된 일을 했을 것입니다. :-)

준비된 문장을 에뮬레이트 한 것입니다.

오늘날의 소프트웨어 엔지니어링 규칙: 만약 그것이 당신에게 아무런 도움이 되지 않는다면, 그것을 사용하지 마세요.

PDO를 원하는 것 같습니다:ATTR_EMULATE_PREAPARES입니다.이렇게 하면 기본 데이터베이스 준비 문이 해제되지만 쿼리 바인딩을 사용하여 sql 주입을 방지하고 sql을 정리할 수 있습니다.PDO::MYSQL_ATTR_DIRECT_QUERY는 쿼리 바인딩을 완전히 끕니다.

준비된 명세서를 사용하지 않을 때는?db 연결이 해제되기 전에 문을 한 번만 실행할 경우.

바운드 쿼리 매개변수를 사용하지 않을 때(대부분의 사람들이 준비된 문장을 사용하여 실제로 얻는 것)?저는 "절대로"라고 말하고 싶고, 정말로 "절대로"라고 말하고 싶지만, 현실은 대부분의 데이터베이스와 일부 DB 추상화 계층이 매개 변수를 바인딩할 수 없는 특정한 상황을 가지고 있기 때문에 그러한 경우에는 사용하지 않을 수밖에 없습니다.하지만 다른 시간에는, 그것은 당신의 삶을 더 단순하게 해줄 것이고 당신의 코드가 그것들을 사용하는 것을 더 안전하게 해줄 것입니다.

PDO는 잘 모르지만, 준비하지 않으려면 동일한 함수 호출에 주어진 값으로 매개 변수화된 쿼리를 실행하는 메커니즘을 제공하고, 별도의 단계로 실행할 것입니다.(예: 다음과 같은 것)run_query("SELECT * FROM users WHERE id = ?", 1)또는 유사합니다.)

또한 후드 아래를 보면 대부분의 db 추상화 계층에서 쿼리를 준비한 다음 정적 SQL 문을 실행하라고 해도 실행합니다.따라서 명시적인 준비를 피함으로써 DB로의 이동을 절약할 수는 없을 것입니다.

준비된 진술은 수천 명의 사람들에 의해 사용되고 있으며 따라서 테스트가 잘 되어 있습니다(따라서 상당히 안전하다고 추론할 수 있습니다).사용자 지정 솔루션은 사용자만 사용합니다.

맞춤형 솔루션이 안전하지 않을 가능성이 매우 높습니다.준비된 문을 사용합니다.그런 식으로 코드를 적게 유지해야 합니다.

작성된 명세서의 이점은 다음과 같습니다.

  • 각 쿼리는 한 번만 컴파일됩니다.
  • mysql은 서버로 데이터를 보내기 위해 더 효율적인 전송 형식을 사용할 것입니다.

그러나 준비된 문은 연결마다만 유지됩니다.연결 풀링을 사용하지 않는 한 페이지당 하나의 문장만 수행하면 아무런 이점이 없습니다.사소하게 간단한 질의는 보다 효율적인 전송 형식의 혜택도 받지 못합니다.

개인적으로는 신경쓰지 않겠습니다.의사가 작성한 문장은 추정적으로 제공하는 안전 변수 인용에 유용할 수 있습니다.

솔직히 걱정하지 않으셔도 될 것 같아요.그러나 많은 PHP 데이터 액세스 프레임워크가 준비문 모드와 준비문 모드를 지원했던 것으로 기억합니다.내 기억이 맞다면 PEAR:예전에 DB가 그랬습니다.

저는 당신과 같은 문제에 부딪혔고 저만의 예약이 있었기 때문에 PDO를 사용하는 대신 준비문과 표준문을 지원하고 두 경우 모두에서 올바른 탈출(sql-injection prevention)을 수행하는 경량 데이터베이스 계층을 작성하게 되었습니다.준비와 관련된 제 다른 불만 중 하나는 때때로 탈출할 수 없는 입력을 ...와 같은 문장에 추가하는 것이 더 효율적이라는 것입니다.WHERE ID IN (1, 2, 3...)

저는 PDO에 대해 아는 것이 부족하여 PDO를 사용하는 다른 옵션이 무엇인지 알려드릴 수 없습니다.그러나 PHP는 지원하는 모든 데이터베이스 공급업체에서 사용할 수 있는 이스케이핑 기능을 가지고 있으며, 사용자가 사용하고 있는 모든 데이터 액세스 계층 위에 자신의 작은 계층을 굴릴 수 있다는 것을 알고 있습니다.

언급URL : https://stackoverflow.com/questions/535464/when-not-to-use-prepared-statements