hsunny study blog

PDO 적용기 본문

programming/PHP

PDO 적용기

헤써니 2020. 12. 27. 22:50

해당 포스팅은 기존에 개인 github에 작성한 내용으로, 내용을 다듬어 tistory에 재공유한 것입니다 :)

 

PHP Database Extension 을 변경하는 작업을 진행했던 과정을 공유합니다.

Original MySQL Functions(mysql_%)을 PHP에서 권장하는 방식인 PDO_MySQL로 변경했습니다.

 

변경한 사유

사용하고 있는 PHP의 버전은 5였지만, 버전업을 고려하여 Database Extension을 변경하는 작업을 진행했습니다.

더보기

Original MySQL Functions은 PHP 4, PHP 5에서 사용되던 방식입니다.

PHP 공식 문서에서는 mysqli(MySQL Improved Extension) PDO_MySQL를 사용하라고 권장합니다.

 

mysqli가 아닌 PDO를 선택한 이유

더 다양한 방법으로 사용할 수 있는 PDO를 선택했습니다.  
1. mysqli는 MySQL Database에서만 사용할 수 있습니다. MySQL에서만 사용할 수 있는 대신 MySQL에 특화되었습니다. MySQL을 사용하고 있긴 하지만, 커넥션만 할 뿐 PHP 코드로 mySQL을 깊이 다루고 있진 않기 때문에 MySQL에 특화된 것이 큰 장점은 아니었습니다.  
2. PDO는 14종류의 RDBMS를 커버합니다. 또한, Prepared Statement를 사용할 때 이름을 가진 플레이스 홀더를 이용할 수 있는 장점이 있습니다.

mysqli 와 PDO 모두 Prepared Statement 를 제공합니다.
두 Database Extention에서 기본적인  ? 를 이용한 플레이스 홀더는 사용가능합니다.
PDO에서는 key값을 이용한 :key (=이름을 가진 플레이스 홀더)로 사용이 가능합니다.
:key를 이용하는 것 코딩의 완성도를 더 높여주었습니다.
여기서 말하는 완성도: 가독성, 의미전달

 

PDO를 적용한 커넥션 파일 구조

<?php
class DBConnection {
    public function __construct() {}
    public function changeDB($db) {}
    public function excuteQuery($query, $parameters) {}
}

클래스 변수

<?php
private $dbname = '';
private $host = '';
private $password = '';
private $options = array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false
);
private $connected = false;
private $quer;
private $conn;

function __construct()

<?php
function __construct($postdata) {
    $this->host = $postdata->host;
    $this->dbname = $postdata->dbname;
    $this->username = $postdata->username;
    $this->password = $postdata->password;
    $dsn = "mysql:host={$this->host};dbname={$this->dbname}";

    if ($this->connected == true) {
        return true;
    }

    $this->conn = new PDO($dsn, $this->username, $this->password, $this->options);
    $this->connected = true;
}
DB와 PHP 파일의 인코딩이 다르다면  $dsn에 ;charset=utf8 를 붙여주세요.
  - PHP 5.3.6 버전 이상에서만 가능합니다.
  - 5.3.6보다 낮은 버전의 PHP를 사용한다면, PDO 객체를 생성하는 곳의 다음 라인에 $this->conn->exec('SET NAMES utf8');을 넣어주세요.

 

function changeDB($db)

<?php
try {
    $this->conn->exec("USE {$db}");
}
catch (PDOException $e) {
    return array("result" => "error",
                 "message" => "오류가 발생했습니다.",
                 "log" => $e->getMessage());
}

 

function excuteQuery($query, $parameters)

<?php
  try {
    if (!$this->connected) {
      throw new Exception ("Not Conneted to Database Server", 1);
    }

    if (!(is_string($query) && $query !== "" && is_array($parameters))) { 
      throw new Exception ("Invalid Query or Parameters", 2);
    }

    $this->quer = $this->conn->prepare($query);
    $this->quer->execute($parameters); // **A**
    $results = $this->quer->fetchAll(); // **B**
    return $results;

  } catch (PDOException $e) {
    return array("result" => "error",
                  "message" => "오류가 발생했습니다.",
                  "log" => $e->getMessage()
                  "code"=> $e->getCode());

  } catch (Exception $e) {
    return array("result" => "error",
                  "message" => "오류가 발생했습니다.",
                  "log" => $e->getMessage()
                  "code"=> $e->getCode());

  }

A

실행하는 쿼리가 INSERT, UPDATE, DELETE 라면 이 부분을 return 해야합니다.

B

SELECT해서 받는 결과가 항상 row 1개라면 fetch()를 사용하면 되고, 2개 이상이라면 fetchAll()을 사용하면 됩니다.

어떻게 사용하냐에 따라 받아서 처리하는 부분도 달라져야겠죠!

 

PDO를 적용한 커넥션 사용하기

<?php
private function getUserTel($userName) {
  $param = array("userName" => $userName);
  $query = "SELECT tel
            FROM member
            WHERE user_name = :userName";

  $excute = $this->dbconn->querySelect($query, $param);
  return $excute;
}

 

 

참고링크

 

 

 

 

'programming > PHP' 카테고리의 다른 글

httpd  (0) 2021.03.07
apachectl  (0) 2021.03.07
전화번호 정규식  (0) 2020.08.31
쿼리스트링 형식을 변수로 인식하는 parse_str()  (0) 2019.10.05
-> 와 =>의 차이점  (0) 2019.07.28