728x90

mysql 확장 기능은 마침내 PHP 7에서 제거되었다.
PHP는 급격하게 성장하며 더 나은 프로그래밍 언어가 되고 있다.
PDO를 사용하는 것은 객체지향과 재사용 가능한 애플리케이션의 데이터베이스 층을 만드는 첫단계이다.

PDO(PHP Data Objects)란 여러가지 데이터베이스를 제어하는 방법을 표준화시킨 것이다.
데이터베이스는 다양한 종류가 있다. PDO 를 사용하면 동일한 방법으로 데이터베이스를 제어할 수 있다.

 

PDO를 이용하기 위한 준비사항

윈도우 Autoset9 (Apache + PHP + MySQL) 에서 PDO를 이용하려면 php.ini 파일에서 주석처리된 것을 없앤다. extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll

 

Autoset9을 다시 실행하면 phpinfo() 에서 설치된 것을 확인할 수 있다.

 

PDO 를 이용하기 위한 준비가 되었다.

PHP 5.5 이상에서 이용 가능하다. AutoSet9 을 설치하면 PHP 5.6.0 버전을 이용한다.

CentOS 6.6 에서 APM 소스 설치방법으로 하는 방법도 가능하더라. 소스 설치 스크립트를 만들어 두면 편리하다.

 

PDO 기본 사용법

$variable = new PDO(DSN, 사용자명, PW);
$variable = null; // PDO 접속 종료
DSN : 접두사:host=localhost;dbname=DB명;charset=utf8;
접두사 : DB의 종류(MySQL, Pgsql, Sqlite)

 

=== dbinfo.php ===

<?php
$db['host'] = "localhost";
$db['name'] = "address";
$db['user'] = "address_root";
$db['pass'] = "autoset";
$db['port'] = "3306";

//use mysql;
//create user address_root@localhost identified by 'autoset';
//grant all privileges on address.* to address_root@localhost;  -- 사용자 권한 부여
//flush privileges;    -- // 변경된 내용을 메모리에 반영(권한 적용)
?>

 

객체 생성 : try catch 문에서 생성한다.

===  pdoconn.php ===

<?php
include_once 'dbinfo.php';
try{
    // MySQL PDO 객체 생성
    $dbconn = new PDO('mysql:host='.$db['host'].';dbname='.$db['name'].';charset=utf8', $db['user'], $db['pass']);

    // 에러 출력
    $dbconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e) {
    echo 'Failed to obtain database handle : '.$e->getMessage();
}
?>

 

new PDO DSN 입력할 때 실수하면 에러가 발생한다.

 

 

PDO SQL 실행

 

<?php
require_once 'pdoconn.php';
// SELECT
$sql="select uid,ItemName,Price,Quantity from table_items";
$stmt = $dbconn->prepare($sql);
$stmt->execute();

// Fetch 모드를 설정
$stmt->setFetchMode(PDO::FETCH_BOTH); // PDO::FETCH_ASSOC, PDO::FETCH_NUM
// 1 row 씩 가져오기
while($row= $stmt->fetch()) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
?>

 

검색조건을 추가해보자.

위의 내용과 비교해서 달라진 점이 무엇인지 확인해보면

검색조건이 where ItemName=:ItemName 로 되어 있고, $stmt->bindParam(':ItemName', $ItemName); 한줄을 추가했고, 실제 검색어 Value 인 $ItemName ='사과'; 을 한줄 추가했다.

<?php
require_once 'pdoconn.php';
// SELECT
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemName ='사과';
$stmt->execute();

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
?>
 

 

$stmt->bindValue(':id', '1', PDO::PARAM_STR);

$stmt->bindValue(':ItemName', '사과');

'1', '사과' 처럼 값을 직접 넣을 때는 bindValue 를 사용해야 한다.

 

$stmt->bindParam(':ItemName', '사과'); // bindParam 을 사용하면 에러가 발생한다.

 

 

이제 bindParam 과 bindValue 차이를 확인할 수 있는 예제를 한번 보자.

아래의 첫번째 예제는 '사과'에 대한 결과를 반환하고, 아래의 두번째 예제는 '복숭아'에 대한 결과를 반환한다.

<?php
require_once 'pdoconn.php';
// SELECT
$ItemName ='사과';
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindValue(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemName ='복숭아'; // 이건 실행안함. Value 로 이미 인식되어서 인듯....
$stmt->execute();

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
$dbconn = null; // DB접속 종료
?>

<?php
require_once 'pdoconn.php';
// SELECT
$ItemName ='사과';
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemName ='복숭아';
$stmt->execute();

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
$dbconn = null;
?>

 

이렇게 실행해야 하는 경우가 있는지는 모르지만 결과는 두개를 반환한다.

<?php
require_once 'pdoconn.php';
// SELECT
$sql="select uid,ItemName,Price,Quantity from table_items where ItemName=:ItemName";
$stmt = $dbconn->prepare($sql);
$stmt->bindParam(':ItemName', $ItemName); // 변수에 바인딩하기 위해 bindParam을 사용
$ItemNames = array('사과','복숭아');
foreach($ItemNames as $ItemName){
    $stmt->execute();
    // Fetch 모드를 설정 및 1 row 씩 가져오기
    while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
        echo $row[0].' | ';
        echo $row[1].' | ';
        echo $row[2].' | ';
        echo $row[3].'<br />';
    }
}
$dbconn = null;
?>

 

IN 으로 받은 걸 처리하는게 올바른 것인지 궁금하여 Stakoverflow 에서 검색하고 테스트 해본 결과를 적어둔다.

<?php
require_once 'pdoconn.php';
// SELECT
$ItemNames = array('사과','복숭아');
$total_items = count($ItemNames);
$question_marks = array_fill(0, $total_items, '?');
$sql='select uid,ItemName,Price,Quantity from table_items where ItemName IN ('.implode(',', $question_marks). ')';
$stmt = $dbconn->prepare($sql);
$stmt->execute(array_values($ItemNames));

// Fetch 모드를 설정 및 1 row 씩 가져오기
while($row= $stmt->fetch(PDO::FETCH_BOTH)) {
    echo $row[0].' | ';
    echo $row[1].' | ';
    echo $row[2].' | ';
    echo $row[3].'<br />';
}
$dbconn = null;
?>

 

이제 배우는 중이라 그런지 MySQLi 에 비해 불편해보이는 것도 있는거 같다.

익숙해지면 장점이 보일지도.....

 

LIKE 검색어 예제

$likeString = '%' . $string . '%';
 $stmt = $dbconn->prepare("SELECT * FROM tableName WHERE columnName LIKE ?");
 $stmt->bind_param('s', $likeString);
 $stmt->execute();

 

 

Insert 예제

 $stmt = $dbconn->prepare("INSERT INTO db_fruit (id, type, colour) VALUES (:id, :name, :color)");
 $stmt->execute(array('id' => $newId, 'name' => $name, 'color' => $color));

 $stmt = $dbconn->prepare("INSERT INTO db_fruit (id, type, colour) VALUES (? ,? ,?)");
 $stmt->execute(array($newId, $name, $color));

 $stmt = $dbconn->prepare("INSERT INTO db_fruit (`id`, `type`, `colour`) VALUES (:id, :name, :colour)");
 $stmt->bindParam(':id', $newId, PDO::PARAM_INT);
 $stmt->bindParam(':type', $type, PDO::PARAM_INT);
 $stmt->bindParam(':colour', $colour, PDO::PARAM_STR);
 $stmt->execute();

 

https://www.w3schools.com/php/php_mysql_prepared_statements.asp 게시글도 읽어보니 도움 많이 된다.

 

블로그 이미지

Link2Me

,