본문 바로가기

프로그래밍 공부/PHP

PHP - PHP에서 데이터베이스 조작 上

데이터베이스 접속

PHP 내부에서 데이터베이스에 접속하려면 PHP에 포함된 API(Application Programming Interface)를 이용한다. API란 PHP에서 MySQL로 접속하기 위해 정해진 창구와 같은 것이다. PHP에서는 MySQL로 접속할 수 있는 3가지 API가 있다.

mysql 함수와 이것을 보완할 mysqli와 PDO이다. 함수인 mysql과 달리 mysqli와 PDO는 객체를 생성해 메서드를 통해 조작한다. 형식과 호출 방법은 다르지만 MySQL에 접속한다는 것은 같다.

지금까지 mysql 명령행 도구로 조작한 것을 떠올리며 아래의 표를 참고하자.

접속에서 접속 종료까지
MySQL에 접속
데이터베이스를 선택
입력, 검색, 수정, 삭제를 실행
결과 받기
접속 종료

mysql 함수를 사용한 접속

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
    <title>PHP 테스트</title>
</head>
<body>
    <?php
        $con = mysql_connect('localhost''root''********') or die('접속할 수 없습니다.');
        print 'mysql 함수로 접속이 성공하였습니다.';
        mysql_select_db('phpdb');
        // 여기에서 데이터베이스 관련 처리를 합니다.
        mysql_close($son);
    ?>
</body>
</html>
cs

mysql 함수 형식을 먼저 살펴보면, 먼저 이 함수는 PHP 7에서는 더 이상 지원을 하지 않는 기능이기 때문에 mysqli와 PDO를 사용해야 한다. mysql_connect라는 접속용 함수가 존재하고, 이것의 인수로 호스트명, 사용자명, 패스워드를 지정하면 MySQL 서버에 접속할 수 있다. 이것으로 접속에 성공하면 mysql_select_db함수를 이용해 데이터베이스명을 지정하여 이용하려는 데이터 베이스를 정한다. 종료시에는 mysql_close 함수를 이용해 접속을 종료한다.

mysqli 클래스를 사용한 접속

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
    <title>PHP 테스트</title>
</head>
<body>
    <?php
        $mysqli = new mysqli('localhost''root''********''phpdb');
        if($mysqli->connect_error){
            die('Connect Error:('.$mysqli->connect_errno.')'.$mysqli->connect_error);
        }
        print 'mysqli 클래스를 통해 접속이 성공하였습니다.';
        // 여기에서 데이터베이스 관련 처리를 합니다.
        $mysqli->close();
    ?>
</body>
</html>
cs

mysqli는 객체 지향형과 함수형이라는 두 가지 방식이 존재한다. 먼저 객체 지향 방식인 mysqli를 사용할수 있다. MySQL 서버에 접속하려면, mysqli 클래스에서 new 연산자를 사용해 객체를 생성한다. 객체를 생성시 인수에 호스트명, 사용자명, 패스워드, 데이터베이스명을 지정한다. 또한 select_db 메서드를 이용하면 다른 데이터베이스로 변경이 가능하다. 처리가 끝나면 close 메서드를 이용해 접속을 종료한다.

PDO를 사용한 접속

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
    <title>PHP 테스트</title>
</head>
<body>
    <?php
        $pdo = new pdo('mysql:host=localhost;dbname=phpdb;charset=utf8''root''********');
        print 'PDO 클래스를 통해 접속이 성공하였습니다.';
        // 여기에서 데이터베이스 관련 처리를 합니다.
        $pdo = null;
    ?>
</body>
</html>
cs

PDO는 C 언어로 개발된 확장 모듈로, PHP에 표준으로 포함되어 있다. PDO 클래스를 이용해서 MySQL에 접속한다. 접속방법은 mysqli 클래스와 같으나 PDO는 객체를 생성할 때 접속을 완료하는 차이가 있다. new를 사용해 PDO 클래스에 객체를 생성한다. 이때 인수에 DSN을 지정한다. 

1
2
3
4
5
<?php
    DSN 접두사:host=호스트명;
    dbname=데이터베이스명;
    charset=문자 코드
?>
cs

DSN은 위와 같이 지정할 수 있다. PDO 클래스는 new 연산자를 통해 생성하고 인수에는 DSN, 사용자명, 패스워드를 지정한다. 접속을 종료할 때는 오브젝트가 할당된 변수에 null값을 할당하면 접속이 종료가 된다.

PDO

어플리케이션 PHP
데이터베이스 추상화 레이어 PDO
MySQL 드라이버 PostgreSQL 드라이버 SQLite 드라이버
데이터베이스
MySQL PostgreSQL SQLite

PDO(PHP Date Object)란 PHP에서 데이터베이스에 접속할 때 여러 가지 처리를 하기 위한 기능(메서드)을 모은 클래스이다. mysql 함수나 mysqli 클래스는 MySQL 서버만을 대상으로 하고 있지만, PDO는 드라이버(데이터베이스를 제어하는 기능)를 변경할 수 있기 때문에 MySQL뿐만 아니라 PostgreSQL, SQLite 등 여러 데이터베이스를 조작할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
    <title>PHP 테스트</title>
</head>
<body>
    <?php
        // MySQL의 접속과 접속 종료
        $pdo = new PDO('mysql:host=localhost; dbname=phpdb; charset=utf8''root''********');
        $pdo = null;
 
        // PostgreSQL의 접속과 접속 종료
        $pdo = new PDO('pgsql:host=localhost dbname=phpdb''root''********');
        $pdo = null;
 
        // SQLite의 접속과 접속 종료
        $pdo = new PDO('sqlite:데이터베이스 파일까지의 절대경로');
        $pdo = null;
    ?>
</body>
</html>
cs

세 가지 접속방법을 적었다. MySQL은 이전에 본 것이고, PostgreSQL의 접두사는 pgsql이고 DSN 구성의 차이점은 사용자명과 패스워드를 DSN에 포함할수 없다. SQLite는 서버가 동작하는 것이 아니라 파일을 데이터베이스로서 조작한다. 데이터베이스 파일까지의 절대 경로가 필요하다.

핸들러의 3가지 유형

1. 데이터베이스 핸들러

PDO를 사용해 데이터베이스에 접속하려면 이제까지와 같이 new 연산자로 PDO 클래스에서 객체를 생성한다. 이 객체를 데이터베이스 핸들러 라고 부른다. 

메서드명 설명
__construct PDO 인스턴스를 생성할 때에 실행되며 데이터베이스에 접속한다.
beginTransaction 트랜잭션을 시작한다.
commit 트랜잭션을 커밋한다.
errorCode 데이터베이스 핸들러와 관련된 SQL STATE라는 오류 코드를 얻는다.
errorInfo 데이터베이스 핸들러와 관련된 오류 정보를 얻는다.
exec SQL문(스테이트먼트)을 실행하고 검색결과나 수정 시의 행수를 돌려준다.
getAttribute 데이터베이스 접속의 속성을 취득한다.
getAvailableDrivers 이용가능한 PDO 드라이버의 배열을 돌려준다. 접속가능한 데이터베이스를 알려준다. 
inTransaction 현재 처리가 트랜잭션인지를 조사한다.
lastInsertid 마지막에 입력된 행의 ID 또는 시퀸스 값을 돌려준다.
prepare SQL문을 실행하는 표준을 처리하고 스테이트먼트 핸들러를 돌려준다.
query 이것만으로 SQL문을 실행하고 결과를 PDOStatement 객체로 돌려준다.
quote SQL문에서 DB 처리에 대한 특별한 의미를 무효로 한다.
rollBack 트랜잭션을 롤백한다.
setAttribute 속성을 설정한다.

2. 스테이트먼트 핸들러

PDO를 조작하는 중요한 핸들러 중에 스테이트먼트 핸들러가 있다. 스테이트먼트 핸들러는 PDOStatement 클래스를 이용해 SQL을 조작하며 프리페어드 스테이트먼트의 바인드나 검색 결과를 패치하는 기능이 있다.

메서드명 설명
bindColumn 가져온 데이터 배열 안의 칼럼과 지정한 변수를 결합한다.
bindParam SQL 실행 전에 값을 입력할 위치를 확보하고 위치와 참조된 값을 결합한다.
bindValue SQL 실행 전에 값을 입력할 위치를 확보하고 위치와 확정된 값을 결합한다. 
closeCursor 연속하여 SQL을 실행할 때는 현재 연결된 접속을 해제하고 재실행할 수 있게 한다.
columnCount 가져온 데이터 안에 칼럼 수를 돌려준다.
dabugDumpParam 디버그용. 프리페어드 스테이트먼트에 포함된 정보를 출력한다.
errorCode 스테이트먼트 핸들러에 관련된 SQL STATE라는 오류 코드를 가져온다.
errorInfo 스테이트먼트 핸들러와 관련된 오류를 가져온다.
execut 프리페어드 스테이트먼트를 실행한다.
fetch 검색 결과에서 1행을 가져온다.
fetchAll 검색 결과에서 모든 데이터를 가져온다.
fetchColumn 검색 결과에서 칼럼의 값을 돌려준다.
fetchObject 다음 행을 가져와 객체로 돌려준다.
getAttribute 속성을 가져온다.
getColumnMeta 검색 결과의 칼럼에 대한 메타 데이터를 돌려준다.
nextRowset 다음 Row Set(Result Set)을 가져온다.
rowCount SQL문을 실행하고 검색 결과나 수정/삭제된 행 수를 돌려준다.
setAttribute 속성을 설정한다.
setFetchMode 스테이트먼트 핸들러의 표준 패치 모드를 설정한다.

3. 오류 핸들러

데이터베이스에 접속할 수 없다던가, 발생한 SQL이 잘못된 경우 오류가 발생한다. 이 오류를 알리고 프로그램을 정상적인 상태로 복귀하는 처리를 오류 처리라고 하며, 이러한 조작을 담당하는 기능을 오류 핸들러 라고 한다. PDO 클래스의 errorInfo와 PDOStatement 클래스의 errorInfo가 그것이다.

속성변경

PDO의 객체 변수->setAttribute(속성명, 속성값);

위의 형태가 PDO 클래스 속성을 설정할 때의 형태이다.

오류 속성을 설정할 때는 오류 정보를 가져오는 모드를 속성명 PDO::ATTR_ERRMODE에 설정한다. 이 속성에 설정할 수 있는 값는 3가지가 있다.

오류 속성에 설정 가능한 값
PDO::ERRMODE_SILENT 오류 코드만을 설정한다.
PDO::ERRMODE_WARNING E_WARNING을 발생시킨다.
PDO::ERRMODE_EXCEPTION 예외를 발생시킨다.

아무것도 설정하지 않는다면 기본적으로 PDO::ERRMODE_SILENT로 설정이 되기 때문에 오류가 발생해도 아무것도 표시가 되지 않는다.

프리페어드 스테이트먼트에 대한 속성은 프페어드 스테이트먼트를 이용할 수 있도록 PDO::ATTR_EMULATE_PREPARES속성에 false값을 설정한다. 프리페어드 스테이트먼트는 속도와 안정성을 향상시킨다.

접속 오류 표시

try-catch 구문은 PDO를 사용해 데이터베이스에 접속해 조작할 때 발생하는 오류를 포착할 수 있다.

1
2
3
4
5
6
7
8
9
<?php
    try{
        // 이상이 발생할 가능성이 있는 처리를 기술한다.
        throw new 예외클래스('오류가 발생하였습니다.');
    }catch(예외클래스 변수){
        // 예외인 경우의 처리를 기술한다.
        print 변수->메서드();
    }
?>
cs

사용하게 되면 아래와 같이 나타낼 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
    <title>PHP 테스트</title>
</head>
<body>
    <?php
        // 사용자명 root를 rooot로 입력하여 접속 오류가 발생한다.
        try{
            $pdo = new PDO('mysql:host=localhost; dbname=phpdb; charset=utf8''rooot''********');
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            print "접속하였습니다.";
        }catch(PDOException $Exception){
            die('접속 오류:'.$Exception->getMessge());
        }
    ?>
</body>
</html>
cs

PDOException 클래스의 getMessage를 통해 오류 메세지를 표시 해준다.