ServBay에서 내장 SQLite 데이터베이스 모듈로 PHP 개발하기
ServBay는 개발자를 위해 설계된 강력한 로컬 웹 개발 환경으로, 여러 기술 스택을 지원합니다. 내장 SQLite 데이터베이스 모듈이 탑재되어 있어, PHP 앱에서 SQLite를 데이터 저장과 관리 용도로 매우 손쉽게 사용할 수 있습니다. 이 문서에서는 ServBay에서 이 기능을 활용하는 방법을 상세히 소개합니다.
SQLite 모듈 개요
SQLite는 경량의 임베디드 관계형 데이터베이스 관리 시스템입니다. 기존의 클라이언트/서버형 데이터베이스(MySQL, PostgreSQL 등)와 달리, 별도의 서버 프로세스가 필요 없으며 라이브러리 형태로 애플리케이션 내부에 직접 포함됩니다. 전체 데이터베이스가 단일 파일에 저장되어 배포 및 관리가 매우 간편합니다.
SQLite는 다음과 같은 특징 때문에 널리 사용되며, 특히 중소형 애플리케이션, 로컬 캐시, 모바일 앱, 개발 및 테스트 환경에 적합합니다.
주요 특징
- 가볍다: 핵심 라이브러리 크기가 작고 리소스 사용량이 적습니다.
- 설정 불필요: 서버 설치, 설정, 사용자 권한 관리를 따로 할 필요 없이 바로 사용할 수 있습니다.
- 고성능: 대부분의 읽기 작업과 적당한 수준의 쓰기 작업에 탁월한 성능을 보장합니다.
- 단일 파일 저장: 전체 데이터베이스가 하나의
.sqlite
파일에 보관되어 백업, 이동, 관리가 쉽습니다. - ACID 트랜잭션 지원: 신뢰할 수 있는 트랜잭션 처리로 데이터의 일관성과 완전성을 보장합니다.
- 크로스 플랫폼: 다양한 운영체제와 프로그래밍 언어를 지원합니다.
ServBay의 SQLite 지원
ServBay는 여러 PHP 버전과 함께 해당 버전에 맞는 SQLite 확장(sqlite3
, pdo_sqlite
등)을 미리 설치하고 기본적으로 활성화하여 제공합니다. 즉, 별도로 PHP 확장을 다운로드, 컴파일, 설정할 필요 없이 바로 PHP 프로젝트에서 SQLite를 사용할 수 있습니다.
사전 준비 사항
- macOS 환경에 ServBay가 설치되어 실행 중이어야 합니다.
- 원하는 PHP 버전이 ServBay 내에서 활성화 및 실행 중이어야 합니다.
- 웹사이트 파일을 저장할 디렉터리가 필요하며, ServBay의 기본 웹 루트 디렉터리
/Applications/ServBay/www
또는 하위 디렉터리 사용을 권장합니다.
ServBay에서 SQLite 사용 방법
ServBay는 SQLite 모듈이 기본적으로 활성화되어 있으므로, 별도의 활성화 작업이 필요하지 않습니다. PHP 환경에서 곧바로 SQLite 관련 함수와 클래스를 사용할 수 있습니다.
SQLite 확장 활성화 여부 확인하기:
SQLite 확장이 제대로 설치 및 활성화되었는지 확인하려면 phpinfo()
페이지 출력으로 확인할 수 있습니다.
<?php phpinfo(); ?>
내용을 가진 PHP 파일(예:info.php
)을 만듭니다.- 해당 파일을 ServBay 웹사이트 루트 디렉터리(예:
/Applications/ServBay/www/servbay.demo/info.php
) 아래의 사이트 디렉터리에 저장합니다. - 웹 브라우저에서 해당 파일 주소(예:
http://servbay.demo/info.php
)로 접속합니다. - 페이지에서 "sqlite" 또는 "pdo_sqlite"를 검색합니다. 관련 설정 섹션이 보이면 확장이 정상적으로 활성화된 것입니다.
PHP 코드에서 SQLite 활용하기
SQLite 확장이 사용 가능한지 확인되었다면, PHP 응용 프로그램에서 SQLite 관련 API를 즉시 이용해 데이터베이스 작업을 할 수 있습니다. PHP는 SQLite와 상호작용할 수 있는 여러 방법이 있는데, 그 중 가장 대표적인 것이 SQLite3
클래스(객체지향)와 PDO
(PHP Data Objects)입니다.
아래는 ServBay 환경에서 이 두 가지 방법을 사용하여 데이터베이스 연결, 테이블 생성, 데이터 삽입 및 조회 등을 수행하는 간단한 예제입니다. 해당 PHP 파일과 생성되는 .sqlite
데이터베이스 파일은 사이트 프로젝트 디렉터리(예: /Applications/ServBay/www/your-project-name/
)에 보관하는 것을 권장합니다.
예제 코드 (SQLite3 방식)
이 방법은 PHP 내장 SQLite3
클래스를 통해 객체지향적으로 SQLite 데이터베이스를 다룰 수 있습니다.
php
<?php
// 데이터베이스 파일 경로
// 데이터베이스 파일은 사이트 프로젝트 디렉터리의 하위 폴더(예: data/)에 보관하는 것을 권장합니다.
$db_file = __DIR__ . '/data/servbay_demo.sqlite'; // __DIR__는 현재 스크립트가 위치한 폴더를 의미
// 데이터 폴더 존재 여부 확인 및 생성
if (!is_dir(__DIR__ . '/data')) {
mkdir(__DIR__ . '/data', 0777, true);
}
// SQLite 데이터베이스 연결
// 파일이 없으면 SQLite가 자동으로 생성합니다.
try {
$db = new SQLite3($db_file);
echo "데이터베이스에 성공적으로 연결되었습니다: " . $db_file . "\n";
} catch (Exception $e) {
die("데이터베이스 연결 실패: " . $e->getMessage());
}
// 테이블 생성
// IF NOT EXISTS 사용 시 중복 생성 에러 방지
$create_table_sql = "CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
age INTEGER
)";
if ($db->exec($create_table_sql)) {
echo "'users' 테이블이 생성되었거나 이미 존재합니다\n";
} else {
echo "테이블 생성 실패: " . $db->lastErrorMsg() . "\n";
}
// 데이터 삽입
$name = 'ServBay Demo User';
$email = '[email protected]';
$age = 30;
// SQL 인젝션 방지를 위해 Prepared Statement 사용
$stmt = $db->prepare("INSERT INTO users (name, email, age) VALUES (:name, :email, :age)");
$stmt->bindValue(':name', $name, SQLITE3_TEXT);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':age', $age, SQLITE3_INTEGER);
// 삽입 실행 및 성공 여부 확인 (email은 UNIQUE라서 중복 삽입 시 실패)
if ($stmt->execute()) {
echo "데이터 삽입 성공: Name=" . $name . ", Email=" . $email . "\n";
} else {
// UNIQUE 제약 오류 확인
if (strpos($db->lastErrorMsg(), 'UNIQUE constraint failed') !== false) {
echo "데이터 삽입 실패: Email '" . $email . "'은(는) 이미 존재합니다\n";
} else {
echo "데이터 삽입 실패: " . $db->lastErrorMsg() . "\n";
}
}
$stmt->close(); // Prepared Statement 종료
// 데이터 조회
$search_name = 'ServBay Demo User';
$query_sql = "SELECT id, name, email, age FROM users WHERE name = :name";
$stmt = $db->prepare($query_sql);
$stmt->bindValue(':name', $search_name, SQLITE3_TEXT);
$result = $stmt->execute();
echo "조회 결과:\n";
$found = false;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
print_r($row);
$found = true;
}
if (!$found) {
echo "일치하는 데이터를 찾을 수 없습니다\n";
}
$result->finalize(); // 결과 집합 해제
$stmt->close(); // Prepared Statement 종료
// 데이터베이스 연결 종료
$db->close();
echo "데이터베이스 연결이 종료되었습니다\n";
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
예제 코드 (PDO 방식)
PDO(PHP Data Objects)는 다양한 데이터베이스 시스템을 동일하게 다룰 수 있는 추상화 계층을 제공합니다. SQLite에 PDO를 사용하는 것이 더 유연하고 폭넓은 데이터베이스 지원을 받기 때문에 권장됩니다.
php
<?php
// 데이터베이스 파일 경로
// 데이터베이스 파일은 사이트 프로젝트 디렉터리의 하위 폴더(예: data/)에 보관하는 것을 권장합니다.
$db_file = __DIR__ . '/data/servbay_demo_pdo.sqlite'; // __DIR__는 현재 스크립트가 위치한 폴더를 의미
// 데이터 폴더 존재 여부 확인 및 생성
if (!is_dir(__DIR__ . '/data')) {
mkdir(__DIR__ . '/data', 0777, true);
}
try {
// 새로운 PDO 인스턴스 생성
// DSN (데이터 소스 이름) 형식: 'sqlite:데이터베이스파일경로'
$dsn = 'sqlite:' . $db_file;
$pdo = new PDO($dsn);
// 오류 모드를 예외로 설정(디버깅에 용이)
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 기본 fetch 모드를 연관 배열로 지정
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
echo "데이터베이스에 성공적으로 연결되었습니다: " . $db_file . "\n";
// 테이블 생성
$create_table_sql = "CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
age INTEGER
)";
$pdo->exec($create_table_sql);
echo "'users' 테이블이 생성되었거나 이미 존재합니다\n";
// 데이터 삽입
$name = 'ServBay PDO User';
$email = '[email protected]';
$age = 35;
// Prepared Statement 사용
$stmt = $pdo->prepare("INSERT INTO users (name, email, age) VALUES (:name, :email, :age)");
// 삽입 실행 및 성공 여부 확인 (email은 UNIQUE라서 중복 삽입 시 실패)
try {
$stmt->execute([
':name' => $name,
':email' => $email,
':age' => $age
]);
echo "데이터 삽입 성공: Name=" . $name . ", Email=" . $email . "\n";
} catch (PDOException $e) {
// UNIQUE 제약 오류 확인 (SQLite 오류코드 19)
if ($e->getCode() == '23000' || strpos($e->getMessage(), 'UNIQUE constraint failed') !== false) {
echo "데이터 삽입 실패: Email '" . $email . "'은(는) 이미 존재합니다\n";
} else {
throw $e; // 다른 종류의 오류는 다시 throw
}
}
$stmt->closeCursor(); // Statement 리소스 해제
// 데이터 조회
$search_name = 'ServBay PDO User';
$stmt = $pdo->prepare("SELECT id, name, email, age FROM users WHERE name = :name");
$stmt->execute([':name' => $search_name]);
$data = $stmt->fetchAll(); // 모든 결과 행 가져오기
echo "조회 결과:\n";
if ($data) {
print_r($data);
} else {
echo "일치하는 데이터를 찾을 수 없습니다\n";
}
$stmt->closeCursor(); // Statement 리소스 해제
} catch (PDOException $e) {
// PDO 예외 처리
echo "데이터베이스 작업 실패: " . $e->getMessage();
// $e->getCode()로 SQLSTATE 오류 코드도 확인 가능
}
// PDO는 스크립트 종료 시 자동으로 연결이 해제되므로 명시적인 close() 호출 필요 없음
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
데이터베이스 파일 위치 안내:
위 예제에서는 데이터베이스 파일(servbay_demo.sqlite
및 servbay_demo_pdo.sqlite
)이 현재 PHP 스크립트가 위치한 디렉터리의 data/
하위 폴더에 생성됩니다. 예를 들어, PHP 파일이 /Applications/ServBay/www/my-servbay-project/index.php
에 있다면 데이터베이스 파일은 /Applications/ServBay/www/my-servbay-project/data/
에 생성됩니다.
프로젝트 하위 폴더에 데이터베이스 파일을 보관하는 것은 프로젝트 관리와 백업에 도움이 되므로 좋은 관례입니다. ServBay가 실행되는 사용자에게 해당 폴더에 쓸 수 있는 권한이 있는지도 꼭 확인하세요(macOS의 기본 ServBay 설정에서는 보통 문제가 없음).
주의사항
- SQLite 데이터베이스 파일은 민감한 데이터이므로 외부에 공개되지 않도록 주의해야 합니다. 데이터베이스 파일은 웹에서 직접 접근 가능한 디렉터리 밖에 두거나, 서버 설정(예: Caddy, Nginx)에서
.sqlite
파일에 대한 접근을 차단하는 것이 보다 안전합니다. 예제에서는 편의를 위해 사이트 디렉터리의data/
하위 폴더를 사용하였으나, 실제 운영 환경에서는 보안을 위해 별도의 조치를 권장합니다. - SQLite는 동시 쓰기 작업이 많지 않은 환경에 적합합니다. 높은 동시성의 쓰기 작업이 필요한 경우 성능 저하 또는 락 문제가 발생할 수 있으므로, 이런 경우에는 MySQL이나 PostgreSQL과 같은 클라이언트/서버형 데이터베이스 사용을 권장합니다.
- ServBay에서 기본적으로 SQLite 확장이 활성화되어 있지만,
phpinfo()
에서 관련 정보를 찾을 수 없을 경우 ServBay PHP 설정을 확인하거나 ServBay 서비스를 재시작해 보시기 바랍니다.
자주 묻는 질문 (FAQ)
Q: SQLite를 별도로 설치해야 하나요?
A: 아니요. ServBay의 PHP 패키지에는 SQLite 확장이 내장되어 있으며 기본적으로 활성화되어 있으므로, PHP 코드에서 바로 사용할 수 있습니다.
Q: .sqlite
데이터베이스 파일은 어디에 저장하는 것이 좋나요?
A: 웹에서 직접 접근할 수 없는 사이트 프로젝트의 하위 디렉터리(예: data/
, database/
등)에 두는 것이 보안상 안전합니다. 예제 코드에서는 __DIR__ . '/data/'
를 사용해 상대 경로로 지정했습니다.
Q: PHP 스크립트에서 SQLite 데이터베이스에 연결이 안 되거나 파일이 생성되지 않습니다.
A: 다음 사항을 확인해 보세요.
- ServBay가 실행 중이며, PHP 파일에 ServBay를 통해 접근하고 있는지 확인하세요.
phpinfo()
출력에서sqlite3
와pdo_sqlite
확장이 활성화되어 있는지 확인하세요.- 데이터베이스 파일이 저장될 디렉터리가 존재하는지, 그리고 ServBay 실행 사용자가 해당 디렉터리에 쓰기 권한이 있는지 확인하세요.
요약
ServBay는 PHP 개발자에게 손쉬운 SQLite 데이터베이스 지원을 제공합니다. ServBay에 내장되어 기본적으로 활성화된 SQLite 모듈 덕분에, 복잡한 설정이 필요 없이 로컬에서 SQLite 기반 애플리케이션 개발과 테스트를 바로 시작할 수 있습니다. SQLite의 경량성과 설정 불필요 이점과 결합되어, ServBay는 효율적이고 사용하기 쉬운 로컬 개발 도구로 자리잡고 있습니다.