PHP PDO 사용

서린·2024년 3월 20일
0

greenstudy

목록 보기
27/44
post-thumbnail

PDO 란 ?

  • 현재 PHP 개발현장에서 많이 사용되는 DB 엑세스 방법 중 하나

PDO Class 인스턴스 생성

<?php
// 기본 문법
$conn = new PDO(DB접속정보 문자열, DB계정명, DB계정비밀번호, PDO설정 배열);

// 예)
// DB 접속에 필요한 값들을 미리 셋팅
$db_host	= "localhost"; // host
$db_user	= "root"; // user
$db_pw		= "php504"; // password
$db_name	= "employees"; // DB name
$db_charset	= "utf8mb4"; // charset
$db_dns		= "mysql:host=".$db_host.";dbname=".$db_name.";charset=".$db_charset;

$db_options	= [
	// DB가 Prepared Statement를 에뮬레이션하도록 설정
	PDO::ATTR_EMULATE_PREPARES => false
	// DB에러 발생 시, PDO Exception을 Throws하도록 설정
	,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
	// 연상배열로 Fetch를 하도록 설정
	,PDO::ATTR_DEFAULT_FETCH_MODE	=> PDO::FETCH_ASSOC 
];

// PDO Class 인스턴스 생성
$obj_conn = new PDO($db_dns, $db_user, $db_pw, $db_options);

1. PDO::ATTR_EMULATE_PREPARES

Prepared Statement로 쿼리를 준비할 때, PHP와 DB 어디에서 에뮬레이션 할지 여부를 결정
true면 PHP에서 처리하고, false면 DB에서 처리
일반적으로 보안상의 이유로 false로 설정

2. PDO::ATTR_ERRMODE

PDO에서 에러를 처리하는 방식을 지정
일반적으로 예외처리의 용이성을 위해 “PDO::ERRMODE_EXCEPTION”설정

3. PDO::ATTR_DEFAULT_FETCH_MODE

DB의 데이터를 fetch할 때 어떤 방식으로 데이터를 가져올지 결정
일반적으로 “PDO::FETCH_ASSOC” 또는 “PDO::FETCH_OBJ”로 설정
- PDO::FETCH_ASSOC : 연상배열로 데이터 fetch
- PDO::FETCH_OBJ : stdClass객체로 데이터 fetch

PDO Class로 DB에 질의 및 결과 획득

placeholder 셋팅이 필요없는 경우

// DB 접속에 필요한 값들을 미리 셋팅
$db_host	= "localhost"; // host
$db_user	= "root"; // user
$db_pw		= "root"; // password
$db_name	= "employees"; // DB name
$db_charset	= "utf8mb4"; // charset
$db_dns		= "mysql:host=".$db_host.";dbname=".$db_name.";charset=".$db_charset;

$db_options	= [
	// DB가 Prepared Statement를 에뮬레이션하도록 설정
	PDO::ATTR_EMULATE_PREPARES => false
	// DB에러 발생 시, PDO Exception을 Throws하도록 설정
	,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
	// 연상배열로 Fetch를 하도록 설정
	,PDO::ATTR_DEFAULT_FETCH_MODE	=> PDO::FETCH_ASSOC 
];

// PDO Class 인스턴스 생성
$obj_conn = new PDO($db_dns, $db_user, $db_pw, $db_options);

$sql = "select * from boards"; // 쿼리 작성
$stmt = $conn->query($sql); // 쿼리 준비 및 DB에 질의
$result = $stmt->fetchAll(); // 질의 결과 fetch
print_r($result); // 결과 출력

placeholder 셋팅이 필요 한 경우

  • 쿼리 작성에서 “:키명”의 형태로 placeholder 셋팅이 필요한 부분을 설정
  • placeholder 배열을 준비
    (작성한 쿼리에서 placeholder로 셋팅한 키명와 일치한 키명을 가진 요소를 준비)
<?php
// DB 접속에 필요한 값들을 미리 셋팅
$db_host	= "localhost"; // host
$db_user	= "root"; // user
$db_pw		= "root"; // password
$db_name	= "employees"; // DB name
$db_charset	= "utf8mb4"; // charset
$db_dns		= "mysql:host=".$db_host.";dbname=".$db_name.";charset=".$db_charset;

$db_options	= [
	// DB가 Prepared Statement를 에뮬레이션하도록 설정
	PDO::ATTR_EMULATE_PREPARES => false
	// DB에러 발생 시, PDO Exception을 Throws하도록 설정
	,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
	// 연상배열로 Fetch를 하도록 설정
	,PDO::ATTR_DEFAULT_FETCH_MODE	=> PDO::FETCH_ASSOC 
];

// PDO Class 인스턴스 생성
$conn = new PDO($db_dns, $db_user, $db_pw, $db_options);

$sql = "SELECT * FROM boards WHERE id = :id"; // 쿼리 작성
// Prepared Statement 배열 준비
$arr_prepare = [
	"id" => 2
];
$stmt = $conn->prepare($sql); // 쿼리 준비
$stmt->execute($arr_prepare); // DB에 질의
$result = $stmt->fetchAll(); // 질의 결과 fetch
print_r($result); // 결과 출력

CRUD

  • lib_db.php 파일을 하나 만들어서 DB 접속 정보와 PDO 옵션을 넣은 함수를 만들어 놓은 상태
  • SELECT 예시 (placeholder를 사용해서)
require_once("./lib_db.php");

try {
    $conn = db_conn(); // PDO객체 리턴 함수 호출
    $limit = 5;
   $sql = " SELECT * FROM employees LIMIT :limit OFFSET :offset"; // : 뒤에 limit 이건 나중에 limit 값을 주겟다는것
   $arr_prepare = [
      "limit" => $limit
      ,"offset" => 10
   ];
   $stmt = $conn->prepare($sql); // 쿼리 준비
   $stmt->execute($arr_prepare);  // 쿼리 실행
   $result = $stmt->fetchAll();  // 질의 결과 패치

   print_r($result);   
} catch (\Throwable $e) {
    echo "예외 발생 :".$e->getMessage()."\n";
} finally {
    $conn = null; // PDO 파기
}
  • INSERT 예시
require_once("./lib_db.php");
try {
    $conn = db_conn(); // PDO 인스턴스 생성

    // 쿼리작성
  $sql= "INSERT INTO employees ( "
  . "  emp_no "
  . "  ,birth_date "
  . "  ,first_name "
  . "  ,last_name "
  . "  ,gender "
  . "  ,hire_date "
  . " ) "
  . " VALUES ( "
  . "  :emp_no "
  . "  ,:birth_date "
  . "  ,:first_name "
  . "  ,:last_name "
  . "  ,:gender "
  . "  ,DATE(NOW()) "
  . " )"
  ;
  $arr_prepare = [
       "emp_no" => 700000
       ,"birth_date" => 20000124
       ,"first_name" => "hong"
       ,"last_name" => "hong"
       ,"gender" => "M"
    ];
    // transaction 시작
    $conn->beginTransaction();
    $stmt = $conn->prepare($sql); // DB 질의 준비
    $result = $stmt->execute($arr_prepare); // DB 질의 실행
    $result_cnt = $stmt->rowCount(); // 영향받은 레코드 수 획득
    // 예외 처리
    if($result_cnt !== 1){
        // 개발자의 필요에 따라 강제로 예외 발생 시키는 방법
        throw new Exception("영향 받은 레코드 수 이상");
    }

    // 정상 완료
    $conn->commit();
    echo $result_cnt."커밋 완료\n";
} catch (\Throwable $e) {
    // $conn이 NULL이 아니면 롤백
    if(!empty($conn)){
        $conn->rollBack();
    }
    echo "예외 발생 : ".$e->getMessage();
} finally {
    $conn = null;
}
  • UPDATE 예시
require_once("./lib_db.php");

try {
    $conn = db_conn(); // PDO 인스턴스 생성

    // 쿼리 작성
    $sql = 
    " UPDATE employees 
    SET first_name = :first_name
    WHERE emp_no = :emp_no
    ";

    $arr_prepare = [
       "first_name" => "gildong"
       ,"emp_no" => "700000"
    ];

    $conn->beginTransaction(); // 트랜잭션 시작
    $stmt = $conn->prepare($sql); // DB 질의 준비
    $stmt->execute($arr_prepare); // DB 질의 실행
    
    $conn->commit();
    echo "수정 완료\n";
} catch (\Throwable $e) {
    if(!empty($conn)){
       $conn->rollBack(); // 롤백 처리
    }
    echo "예외 발생 : ".$e->getMessage();
} finally {
    $conn = null;
}
  • DELETE 예시
<?php
require_once("./lib_db.php");

try {
    $conn = db_conn(); // PDO 인스턴스 생성

    // 쿼리 작성
    $sql = 
    " DELETE FROM employees WHERE emp_no = :emp_no";

    $arr_prepare = [
       "emp_no" => "700000"
    ];

    $conn->beginTransaction(); // 트랜잭션 시작
    $stmt = $conn->prepare($sql); // DB 질의 준비
    $stmt->execute($arr_prepare); // DB 질의 실행
    
    $conn->commit();
    echo "삭제 완료\n";
} catch (\Throwable $e) {
    if(!empty($conn)){
       $conn->rollBack(); // 롤백 처리
    }
    echo "예외 발생 : ".$e->getMessage();
} finally {
    $conn = null;
}
profile
개발 일기 ( •̀ ω •́ )✧

0개의 댓글

관련 채용 정보