매개 변수가있는 SELECT 쿼리에 PDO 개체를 올바르게 사용하는 방법


85

SELECT쿼리 를 수행하기 위해 PHP.net 지침을 따르려고 시도했지만이 작업을 수행 하는 가장 좋은 방법이 확실하지 않습니다.

SELECT가능한 경우 매개 변수가있는 쿼리 를 사용 ID하여 name필드가 매개 변수와 일치 하는 테이블에서을 반환하고 싶습니다 . ID고유하므로 하나를 반환해야합니다 .

그런 다음 IDINSERT를 다른 테이블에 사용하고 싶으므로 성공했는지 여부를 결정해야합니다.

또한 재사용을 위해 쿼리를 준비 할 수 있다는 것도 읽었지만 이것이 어떻게 도움이되는지 잘 모르겠습니다.

답변:


158

다음과 같은 데이터를 선택합니다.

$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch(); // Use fetchAll() if you want all results, or just iterate over the statement, since it implements Iterator

동일한 방식으로 삽입합니다.

$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));

오류 발생시 예외를 발생 시키도록 PDO를 구성하는 것이 좋습니다. 그런 다음 PDOException쿼리 중 하나라도 실패하면-명시 적으로 확인할 필요가 없습니다. 예외를 설정하려면 $db개체를 만든 직후에 다음을 호출하십시오 .

$db = new PDO("...");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

새로운 PDO (...)가있는 PDOStatement를 의미한다고 가정합니다.
Joe Phillips

1
아니. PDO는 연결 클래스입니다 (대신 PdoConnection으로 이름이 지정되었을 것임). 연결은 PdoStatements를 만들 수 있습니다. 개별 문이 아니라 연결 개체에서 setAttribute ()를 호출합니다. (또는 생성자에게 전달할 수 있습니다.)
troelskn

1
이 유용 할 수 있습니다 :$db = new PDO('mysql:dbname=your_database;host=localhost', 'junior', '444');
주니어 Mayhé

2
라인 $statement->execute(array(':name' => "Jimbo"));에 대해 짐보 부분을 설명해 주시겠습니까?
muttley91 dec.

1
@rar 이전 줄에서 쿼리는 자리 표시 자로 시작됩니다 :name. execute여기서 호출 은 자리 표시 자-> 값 쌍의 연관 배열로 수행됩니다. 따라서이 경우 :name자리 표시자는 Jimbo 문자열로 대체됩니다. 값이 실제 쿼리와 다른 채널을 통해 이스케이프되거나 전송되어 모든 종류의 인젝션 공격을 방지하기 때문에 단순히 문자열 교체를 수행하는 것이 아닙니다.
troelskn

16

나는 최근에 PDO로 작업하고 있으며 위의 대답은 완전히 옳았지만 다음도 작동한다는 것을 문서화하고 싶었습니다.

$nametosearch = "Tobias";
$conn = new PDO("server", "username", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare("SELECT `id` from `tablename` WHERE `name` = :name");
$sth->bindParam(':name', $nametosearch);
// Or sth->bindParam(':name', $_POST['namefromform']); depending on application
$sth->execute();

16
아니요, 사용할 데이터베이스를 선택하지 않았으므로 그렇지 않습니다.
Rápli András 2014

3
즉 실제로 실제로 형태의 DSN 있어야 "서버"문자열에 있어야합니다 "{드라이버} : DBNAME = {DB_NAME}; 호스트 = {서버}"중괄호 값을 대체 무엇과 연결 요구
thorne51

12

bindParam또는 bindValue방법을 사용 하여 진술을 준비 할 수 있습니다. $check->execute(array(':name' => $name));특히 여러 값 / 변수를 바인딩하는 경우 작업을 수행하는 대신 첫눈에 더 명확하게 합니다.

아래에서 명확하고 읽기 쉬운 예를 확인하십시오.

$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname LIMIT 1");
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname',  'Bloggs');
$q->execute();

if ($q->rowCount() > 0){
    $check = $q->fetch(PDO::FETCH_ASSOC);
    $row_id = $check['id'];
    // do something
}

여러 행 이 예상되는 경우를 제거 LIMIT 1하고 가져 오기 방법을 fetchAll다음 으로 변경하십시오 .

$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname");// removed limit 1
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname',  'Bloggs');
$q->execute();

if ($q->rowCount() > 0){
    $check = $q->fetchAll(PDO::FETCH_ASSOC);
    //$check will now hold an array of returned rows. 
    //let's say we need the second result, i.e. index of 1
    $row_id = $check[1]['id']; 
    // do something
}

확실하지 않다. 나에게 유효한 대답 인 것 같습니다. 'name'대신 'myname'을 사용하고 하나가 아닌 여러 매개 변수를 사용하면 도움이 될 것이라고 생각합니다.
Joe Phillips

@GillianLoWong 무엇을 $check = $q->fetch(PDO::FETCH_ASSOC); if (!empty($check)){ $row_id = $check['id']; // do something }합니까?
Abdul

1
안녕하세요 @abdul, 어레이의 개수 / 빈 수표를 교체했습니다. 결과가 반환되었는지 확인해야했습니다. 그러나 pdo에는 rowCount ()라는 함수도있어 행이 영향을 받거나 가져 왔는지 확인할 수 있습니다. 행이 선택되었는지 알 수없는 경우 데이터를 가져올 필요가 없으므로 fetch 문을 if rowCount () 문으로 옮겼습니다. :)
Gilly

@Gillian La Wong은 여러 where 쿼리에 대한 bindValue의 깨끗한 쿼리에 감사드립니다. 내 프로젝트를 저장합니다.
php-coder

6

약간의 완전한 답변이 여기에 있습니다.

    $sql = "SELECT `username` FROM `users` WHERE `id` = :id";
    $q = $dbh->prepare($sql);
    $q->execute(array(':id' => "4"));
    $done= $q->fetch();

 echo $done[0];

다음 $dbh은 PDO db 연결기이며 id테이블 users을 기반으로 username사용하여fetch();

나는 이것이 누군가에게 도움이되기를 바랍니다.


또는 필요 fetchColumn()하지 않도록 사용 하십시오 [0]. 또한 LIMIT 1SQL에서 사용하는 것을 잊지 마십시오 .
rybo111

3

방법 1 : PDO 쿼리 방법 사용

$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

행 수 얻기

$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';

방법 2 : 매개 변수가있는 문

$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->execute(array($name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

방법 3 : 매개 변수 결합

$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

**bind with named parameters**
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

or
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->execute(array(':name' => $name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

링크 에서 더 많은 것을 알고 싶습니다


4
방법 1을 제거하십시오. mysql 주입이 가능합니다.
Tomahock

-2

단일 페이지에서 인라인 코딩을 사용하고이 전체 예제를 사용하는 것보다 oops를 사용하지 않는 경우 도움이 될 것입니다.

//connect to the db
$dbh = new PDO('mysql:host=localhost;dbname=mydb', dbuser, dbpw); 

//build the query
$query="SELECT field1, field2
FROM ubertable
WHERE field1 > 6969";

//execute the query
$data = $dbh->query($query);
//convert result resource to array
$result = $data->fetchAll(PDO::FETCH_ASSOC);

//view the entire array (for testing)
print_r($result);

//display array elements
foreach($result as $output) {
echo output[field1] . " " . output[field1] . "<br />";
}

이 코드 스 니펫은 문제를 해결할 수 있지만 질문에 대한 이유 또는 답을 설명하지 않습니다. 게시물의 품질을 높이는 데 도움이되므로 코드에 대한 설명을 포함 해주세요 . 미래에 독자를 위해 질문에 답하고 있으며 해당 사용자는 코드 제안 이유를 모를 수 있습니다. 신고자 / 검토 자 : 이 답변과 같은 코드 전용 답변의 경우 반대 투표, 삭제하지 마세요!
Scott Weldon

그래서 나는 그것을 내 스스로 무엇을 삭제해야합니다
칼 싱

아니, 정반대. 저품질 게시물 대기열 에서이 게시물을 보았 으므로 내 댓글의 뒷부분은 사람들 에게 삭제 투표를 하지 말라고 말하는 것이 습니다. (대신에 반대 투표 제안은 게시물이 편집 된 후 제거되는 임시 반대 투표를 유도하기위한 것이 었습니다.) 이전 의견에서 언급했듯이 코드를 제안한 이유에 대한 설명을 추가하면 더 좋을 것입니다. . 또한이 질문은 매개 변수화 된 쿼리에 대해 묻지 만 매개 변수화 field > 6969된 것이 아니라 하드 코딩 된 것처럼 보입니다.
Scott Weldon 2016
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.