PHP 클라이언트

PHP 클라이언트 (PDO)

PHP DuckDB PDO 확장은 tertiary client(3차 클라이언트)이며 서드파티가 유지 관리해요.

pdo_duckdb를 사용하려면 아래 지침을 따르세요.

pdo_duckdb의 최신 버전은 DuckDB {{ site.current_duckdb_php_version }}을 지원해요.

pdo_duckdbPHP Data Objects (PDO) 인터페이스를 위한 네이티브 DuckDB 데이터베이스 드라이버예요.

PDO와 호환되는 모든 애플리케이션이나 프레임워크는 pdo_duckdb를 직접 사용할 수 있어요. 스레드 안전하며 FrankenPHP (PHP-ZTS), TrueAsync, Swoole에서 완전히 테스트됐어요.

네이티브 PHP 확장이므로 C/C++로 구현되어 있고 PHP FFI나 프리로딩이 필요 없어요. 릴리스 패키지에는 지원되는 모든 플랫폼의 사전 컴파일 바이너리가 들어 있으며 DuckDB가 직접 포함돼요. DuckDB 확장은 DuckDB CLI에서와 동일하게 동작해요.

출처: 문서

본문

지원되는 PHP 버전: 8.2 이상

운영체제: Ubuntu 24+, Debian 12+, Fedora 42+, openSUSE 16+, AmazonLinux 2023+, Wolfi OS, Windows Server 2022+ (x64), macOS 14+ (arm64)

모든 DuckDB 타입이 지원돼요: Text, Numeric, Date, Time, Interval, JSON, Array, Struct, Map, List, Enum, Variant, Geometry, Union, Bitstring, Blob 그리고 Boolean

GitHub: pdo-duckdb-php

Packagist: pdo-duckdb-php

설치 (Installation)

pdo_duckdb는 PHP Installer for Extensions (PIE)와 완전 호환되며 다음으로 설치할 수 있어요:

pie install thomas-0816/pdo-duckdb-php

테스트:

php -m | grep duckdb
php -r 'print_r((new PDO("duckdb::memory:"))->query("SELECT 42 as n")->fetch(PDO::FETCH_ASSOC));'

# Array
# (
#     [n] => 42
# )

Laravel 및 Symfony 통합

DuckDB용 Laravel Eloquent 드라이버: laravel-duckdb

DuckDB용 Doctrine DBAL: doctrine-dbal-duckdb

예시 (Examples)

기본 사용법

<?php

$duckDb = new PDO('duckdb::memory:');
$duckDb->exec('CREATE TABLE table1 (id INTEGER, amount DECIMAL(10, 2), description VARCHAR)');

$statement = $duckDb->prepare('INSERT INTO table1 VALUES (?, ?, ?)');
$statement->execute([1, 42.21, 'Hello DuckDB! 🐘 💓 🦆']);

$statement = $duckDb->query('SELECT * FROM table1');
print_r($statement->fetchAll(PDO::FETCH_ASSOC));

# Array
# (
#     [0] => Array
#         (
#             [id] => 1
#             [amount] => 42.21
#             [description] => Hello DuckDB! 🐘 💓 🦆
#         )
# )

디스크 또는 인메모리 데이터베이스 열기

<?php

$db = new PDO('duckdb::memory:'); // 인메모리 데이터베이스 열기

$db = new PDO('duckdb:/tmp/test.db'); // 디스크에서 데이터베이스 파일 열기

// 데이터베이스 파일을 읽기 전용으로 열기
$db = new PDO('duckdb:/tmp/test.db', null, null, [PDO::DUCKDB_ATTR_CONFIG => ['access_mode' => 'read_only']]);

Parquet 파일 읽기 및 쓰기

<?php

$db = new PDO('duckdb::memory:');
$db->exec('CREATE TABLE table1 (id INTEGER, text VARCHAR USING COMPRESSION zstd, data JSON)');

$statement = $db->prepare('INSERT INTO table1 VALUES (?, ?, ?)');
$statement->execute([1, 'Hello DuckDB 🦆', ['foo' => 'bar', 'baz' => 42]]);

$db->exec("COPY (SELECT * FROM table1) TO '/tmp/table1.parquet' (COMPRESSION zstd)");

foreach ($db->query("SELECT * FROM '/tmp/table1.parquet'", PDO::FETCH_ASSOC) as $row) {
    print_r($row);
}

# Array
# (
#     [id] => 1
#     [text] => Hello DuckDB 🦆
#     [data] => Array
#         (
#             [foo] => bar
#             [baz] => 42
#         )
# )

CSV 파일 읽기

<?php

$list = [
    ['aaa', 'bbb', 'ccc'],
    ['123', '456', '789'],
    ['aaa', 'bbb', 'ccc']
];
$fp = fopen('/tmp/test.csv', 'w');
foreach ($list as $fields) {
    fputcsv($fp, $fields, ',', '"', '');
}
fclose($fp);

$db = new PDO('duckdb::memory:');
$statement = $db->query("SELECT * FROM '/tmp/test.csv'");
print_r($statement->fetchAll(PDO::FETCH_ASSOC));

# Array
# (
#     [0] => Array
#         (
#             [aaa] => 123
#             [bbb] => 456
#             [ccc] => 789
#         )
#     [1] => Array
#         (
#             [aaa] => aaa
#             [bbb] => bbb
#             [ccc] => ccc
#         )
# )

JSON 파일 읽기

<?php

file_put_contents('/tmp/logs.json', json_encode(['log' => 'log text']) . PHP_EOL, FILE_APPEND);
file_put_contents('/tmp/logs.json', json_encode(['log' => 'log text 2']) . PHP_EOL, FILE_APPEND);

$db = new PDO('duckdb::memory:');
$statement = $db->query("SELECT * FROM '/tmp/logs.json'");
print_r($statement->fetchAll(PDO::FETCH_ASSOC));

# Array
# (
#     [0] => Array
#         (
#             [log] => log text
#         )
#     [1] => Array
#         (
#             [log] => log text 2
#         )
# )

$db->exec("COPY (SELECT * FROM '/tmp/logs.json') TO '/tmp/logs_json.parquet' (COMPRESSION zstd)");

고정 스키마를 가진 구조화 컬럼 사용

<?php

# s is array{v: string, i: int, a: string[], d: float}

$db = new PDO('duckdb::memory:');
$db->exec('CREATE TABLE table1 (s STRUCT(v VARCHAR, i INTEGER, a VARCHAR[], d DECIMAL))');

$statement = $db->prepare('INSERT INTO table1 VALUES (?)');
$statement->execute([['v' => 'foo', 'i' => 21, 'a' => ['b', 'c'], 'd' => 42.21]]);

$statement = $db->query('SELECT * FROM table1');
print_r($statement->fetch(PDO::FETCH_ASSOC));

# Array
# (
#     [s] => Array
#         (
#             [v] => foo
#             [i] => 21
#             [a] => Array
#                 (
#                     [0] => b
#                     [1] => c
#                 )
#             [d] => 42.21
#         )
# )

자동 증가 컬럼

<?php

$db = new PDO('duckdb::memory:');
$db->exec('CREATE SEQUENCE table1_id');
$db->exec("CREATE TABLE table1 (id INTEGER PRIMARY KEY DEFAULT nextval('table1_id'))");
$statement = $db->query('INSERT INTO table1 VALUES (default) RETURNING *');
print_r($statement->fetch(PDO::FETCH_ASSOC));

# Array
# (
#     [id] => 1
# )

더 알아보기 (Learn more)

pdo_duckdb의 GitHub 저장소와 Packagist 페이지에서 자세한 정보와 최신 릴리스를 확인해요.