PDO는 PHP에서 다양한 데이터베이스를 하나의 표준 인터페이스로 연결하는 DB 추상화 계층입니다.
특정 DBMS에 종속되지 않으므로, 코드 변경 없이 다른 DB로 쉽게 교체할 수 있습니다.
다중 DB 지원
MySQL, PostgreSQL, SQLite, Oracle, MSSQL, Firebird 등 지원
Prepared Statement 지원
SQL 인젝션 방지, 성능 최적화 가능
객체지향 방식
유지보수성과 가독성 향상
유연한 Fetch 방식
연관 배열, 숫자 배열, 객체 등 다양한 형태로 데이터 조회 가능
트랜잭션 지원
복잡한 데이터 처리 시 안정성 보장
<?php
try {
$dsn = "mysql:host=localhost;dbname=testdb;charset=utf8";
$username = "root";
$password = "비밀번호";
// PDO 객체 생성
$pdo = new PDO($dsn, $username, $password);
// 에러 모드 설정
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "DB 연결 성공";
} catch (PDOException $e) {
echo "DB 연결 실패: " . $e->getMessage();
}
$stmt = $pdo->query("SELECT id, name FROM users");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['id'] . " - " . $row['name'] . "<br>";
}
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute([':email' => 'user@example.com']);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($user);
// INSERT
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->execute([
':name' => '홍길동',
':email' => 'hong@example.com'
]);
// UPDATE
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id");
$stmt->execute([
':name' => '이순신',
':id' => 1
]);
// DELETE
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => 2]);
모드 |
설명 |
---|---|
PDO::FETCH_ASSOC |
연관 배열로 반환 |
PDO::FETCH_NUM |
숫자 인덱스 배열로 반환 |
PDO::FETCH_BOTH |
연관 배열 + 숫자 배열 (기본값) |
PDO::FETCH_OBJ |
객체 형태로 반환 |
PDO::FETCH_CLASS |
특정 클래스 형태로 반환 |
예:
$stmt = $pdo->query("SELECT id, name FROM users");
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
여러 쿼리를 하나의 작업으로 묶어서 실행
try {
$pdo->beginTransaction();
$pdo->exec("UPDATE accounts SET balance = balance - 1000 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 1000 WHERE id = 2");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "트랜잭션 실패: " . $e->getMessage();
}
PDO 에러 모드는 다음과 같이 설정 가능
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 예외 발생
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); // 경고 출력
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); // 아무 메시지도 없음
Prepared Statement를 반드시 사용
사용자 입력값을 직접 쿼리에 넣지 않기
DB 계정 권한 최소화
에러 메시지에 민감 정보(쿼리, 비밀번호 등) 노출 금지
장점
여러 DB 지원 (MySQL → PostgreSQL 변경 시 코드 수정 최소화)
보안 강화 (SQL 인젝션 방지)
객체지향 방식으로 구조적 개발 가능
트랜잭션과 에러 처리 용이
단점
MySQLi보다 약간의 성능 손실 가능 (대부분 미미)
초기에 객체지향 패턴에 익숙하지 않으면 학습 필요
제가 원하시면 MySQLi vs PDO 비교 표를 만들어서 어떤 상황에 PDO를 선택해야 하는지 정리해 드릴 수 있습니다.
그 표를 보면 프로젝트에 어떤 DB 접근 방식을 쓰면 좋을지 바로 판단 가능할 것입니다.