不能,PHP无法直接连接DuckDB,因官方无原生驱动;可行方案为通过CLI工具(shell_exec)或HTTP服务(如duckdb-http)间接交互,需注意并发写锁、大结果集格式及绝对路径问题。

PHP 能直接连接 DuckDB 吗?不能,得走 HTTP 或 CLI 代理
DuckDB 官方没有提供 PHP 的原生驱动,pdo_duckdb 不存在,ext-duckdb 也不在 PHP 扩展仓库里。硬连 libduckdb 需要自己写 ZE 扩展,实际项目中几乎没人这么做。可行路径只有两条:用 duckdb 命令行工具 + shell_exec(适合小数据、低频操作),或起一个 DuckDB HTTP 服务(如用 duckdb-http 或自建 FastAPI/Express 封装)再用 file_get_contents 或 cURL 调用。
用 duckdb CLI 读写本地 .duckdb 文件最简单
前提是服务器装了 DuckDB CLI(Linux/macOS 下 curl -fsSL https://duckdb.org/install.sh | sh;Windows 可下载二进制并加到 PATH)。注意权限:PHP 进程需对数据库文件有读写权限,且不能被其他进程独占锁住(DuckDB 不支持多写并发)。
-
查数据:用
shell_exec("duckdb my.db \"SELECT * FROM users LIMIT 5;\""),输出是带表头的 ASCII 表格,需用preg_split或fgetcsv(配合-csv参数)解析 -
写数据:推荐先导出 CSV 到临时目录,再用
duckdb my.db "INSERT INTO users SELECT * FROM read_csv_auto('tmp.csv');"—— 直接拼 SQL 插入大量数据容易触发 shell 字符转义问题 -
错误捕获:CLI 出错时返回非零码但 stdout 可能为空,务必检查
$output和$return_var,例如shell_exec("duckdb my.db \"...\" 2>&1")把 stderr 合并进来
用 DuckDB HTTP Server 替代 CLI 更可控
如果已有 Node.js 或 Python 环境,跑一个轻量服务比反复 fork 进程更稳。比如用 duckdb-http(npm i -g duckdb-http)启动:duckdb-http --db ./my.db --port 8080,然后 PHP 侧:
file_get_contents("http://localhost:8080/query?sql=" . urlencode("SELECT count(*) FROM logs"));返回 JSON 格式,含 results 数组和 column_names。写操作需用 POST(cURL 发送 {"sql": "INSERT..."}),注意服务默认只允许 GET 查询,POST 需加 --allow-write 启动参数。
立即学习“PHP免费学习笔记(深入)”;
PHP 读写 DuckDB 最容易卡死的三个点
一是并发写:DuckDB 在单文件模式下不允许多个连接同时写,shell_exec 多次调用可能因锁等待超时失败;二是大结果集:CLI 默认输出表格格式,10 万行会吃光内存,必须加 -json 或 -csv 参数;三是路径陷阱:PHP 的 chdir() 或 Web 服务器工作目录不确定,所有 .duckdb 文件路径建议用 __DIR__ . '/data/my.db' 写死绝对路径。



















