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


85

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

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

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

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

답변:


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.