引言:当国产数据库遇见PHP生态的桥梁
在数字化转型的浪潮中,国产数据库正以惊人的速度崛起。作为人大金仓自主研发的核心产品,KingbaseES凭借其与PostgreSQL的高度兼容性、金融级安全特性以及国产化适配优势,已成为政企领域替代Oracle的主流选择。然而,对于PHP开发者而言,如何高效连接并操作这款国产数据库却成为一道技术门槛。
KingbaseES 数据库【系列篇章】:
| No. | 文章地址(点击进入) |
|---|---|
| 1 | 电科金仓KingbaseES数据库解析:国产数据库的崛起与技术创新 |
| 2 | KingBase数据库迁移利器:KDTS工具深度解析与实战指南 |
| 3 | KingBase数据库迁移利器:KDTS工具 MySQL数据迁移到KingbaseES实战 |
| 4 | 电科金仓KingbaseES V9数据库:国产数据库的自主创新与行业实践深度解析 |
| 5 | KingbaseES客户端工具Ksql使用全指南:从安装到高级操作 |
| 6 | Spring JDBC与KingbaseES深度集成:构建高性能国产数据库应用实战 |
| 7 | 深度解析:基于 ODBC连接 KingbaseES 数据库的完整操作与实践 |
| 8 | Python驱动Ksycopg2连接和使用Kingbase:国产数据库实战指南 |
| 9 | Go语言×Kingbase数据库极速打通:Gokb驱动三步实操,让国产数据库连接效率嘎嘎提升! |
| 10 | 金仓数据库KingbaseES实现MongoDB平滑迁移全攻略:从架构适配到性能调优的完整实践 |
本文将通过实战案例+原理剖析+避坑指南的三维视角,系统讲解如何通过PHP的PDO_KDB驱动实现与Kingbase数据库的无缝连接。从环境搭建到CRUD操作,从异常处理到性能优化,构建安全可靠的国产化应用。
一、技术背景:国产数据库的崛起与PHP的适配需求
1.1 KingbaseES数据库的技术特性
KingbaseES(人大金仓数据库管理系统)作为国产数据库的代表,具有以下核心优势:
- PostgreSQL兼容性:完整支持PostgreSQL 9.6协议,90%以上SQL语法可直接迁移
- 金融级安全:通过国家信息安全等级保护三级认证,支持三权分立管理
- 国产化适配:全面支持飞腾、鲲鹏、龙芯等国产CPU架构,适配统信UOS、麒麟等操作系统
- 高可用架构:提供读写分离、故障自动切换、数据同步复制等企业级功能
1.2 PHP生态的连接挑战
尽管KingbaseES与PostgreSQL高度兼容,但直接使用PHP的PDO_PGSQL驱动连接时仍会遇到:
- 驱动不兼容:部分PostgreSQL特有函数在Kingbase中实现不同
- 数据类型差异:如SERIAL序列类型在Kingbase中的生成机制
- 连接参数差异:Kingbase默认端口为54321而非PostgreSQL的5432
1.3 PDO_KDB驱动的诞生意义
为解决上述问题,人大金仓官方推出了PDO_KDB专用驱动。该驱动:
- 完整实现PDO标准接口
- 针对Kingbase特性进行优化
- 支持Windows/Linux双平台
- 提供数据批量导入导出等扩展功能
二、环境搭建:从零开始的完整配置指南
2.1 环境准备
- 已安装与驱动对应版本的数据库
- Pdo_kdb 驱动包版本与 PHP 版本一致
Pdo_kdb 驱动对 PHP API 版本有严格要求,一般要求 Pdo_kdb 驱动与 PHP 版本完全一致,如 PHP8.0.28 版本最好使用 PHP8.0.28 编译出的 Pdo_kdb 驱动。
PHP 有线程安全(Thread Safe,简称 TS)与非线程安全(Non-Thread Safe,简称 NTS)版本,Pdo_Kdb 驱动也需要与 PHP 版本是否线程安全相对应,可通过 php -v 查看当前环境的 PHP 版本是否线程安全,以下是 PHP8.0.28 非线程安全版本说明输出的示例:
$ php -v
PHP 7.2.0 (cli) (built: Aug 15 2024 16:59:37) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
以下是 Kingbase 默认提供的 Pdo_kdb 驱动包版本:
| PHP版本 | 是否线程安全 |
|---|---|
| 5.6.22 | 非线程安全(NTS) |
| 7.2.0 | 非线程安全(NTS) |
还可以通过Pdo_kdb产品手册的版本下载说明获取其他版本的驱动包。
2.2 操作实例
基于 Ksycopg2 编译开发应用程序,主要步骤如下:
安装部署 PHP 驱动 Pdo_kdb -> 测试能否成功加载 Pdo_kdb 驱动 -> 编写应用程序 -> 运行
下文将通过具体示例说明如何使用 PHP 驱动连接操作数据库:
2.3 下载合适 PHP 驱动
查看当前环境架构及 PHP 版本,选用合适的 PHP 驱动 Pdo_kdb 。
命令行执行 php -v,执行查看 PHP 版本:
$ php -v
PHP 7.2.0 (cli) (built: Aug 15 2024 16:59:37) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
当前环境使用的是 x86_64 PHP7.2.0 非线程安全版本,需要使用对应 x86_64 架构的 PHP7.2.0 非线程安全的 Pdo_kdb 驱动包。
参考 Pdo_kdb 产品手册的更多版本的下载链接(点击下载),可在浏览器输入以下 URL 下载对应版本的驱动
https://kingbase.oss-***-beijing.aliyuncs.***/KES_INTERFACE/history/PHP/all/r6/PDO/x86_64/uzts/v9_pdo_kdb_for_php-7.2.0_x86_64_uzts.tar.gz
三、PHP 驱动连接操作数据库——安装部署 PHP 驱动
一般可通过单独编译安装指定版本 PHP,也可通过集成环境安装 PHP,而 WEB 应用实际多是用的 PHP-FPM,故实际生产环境的 PHP 环境无法一言以蔽之,以下以命令行 PHP 环境及 PHP-FPM 环境作简要的 Pdo_kdb 驱动的安装部署说明。
命令行 PHP
3.1 Linux 环境
命令行 PHP 环境的加载对应驱动,将 Pdo_kdb 放置在 PHP 安装路径的
lib/php/extensions/no-debug-non-zts-20170718
路径下,再通过php.ini配置 Pdo_kdb,最后使用php -m命令查看驱动是否成功加载,示例具体步骤如下:
3.1.1 解压安装
若本地 PHP7.2.0 安装在/home/kingbase/php/php-7.2.0路径下,则 PHP 默认驱动的安装路径为/home/kingbase/php/php-7.2.0/lib/php/extensions/no-debug-non-zts-20170718,否则默认为/usr/local/lib/php/extensions/no-debug-non-zts-20170718路径下,如下表所示:
| 安装方式 | PHP可执行文件路径 | 驱动安装路径 |
|---|---|---|
| 指定路径 | /home/kingbase/php/php-7.2.0/bin/php | /home/kingbase/php/php-7.2.0/lib/php/extensions/no-debug-non-zts-20170718 |
| 默认路径 | /usr/local/bin/php | /usr/local/lib/php/extensions/no-debug-non-zts-20170718 |
将 Pdo_kdb 驱动包解压后得到的库全部拷贝到上述驱动安装路径下即可。
备注
PHP 拓展模块默认安装路径,可在命令行执行
php -i | grep extension_dir
查看对应模块拓展路径。
3.1.2 配置 Pdo_kdb
执行php --ini查看 PHP 配置文件路径:
$ php --ini
Configuration File (php.ini) Path: /home/kingbase/php/php-7.2.0/lib
Loaded Configuration File: /home/kingbase/php/php-7.2.0/lib/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
修改 /home/kingbase/php/php-7.2.0/lib/php.ini 的 php.ini 文件,在 extension=pdo; 下方添加一行 extension=pdo_kdb;,让 PHP 能加载 Pdo_kdb 驱动。
extension 也可配置全路径的形式,诸如:extension=/home/kingbase/pdo_kdb.so; 去加载指定路径的 Pdo_kdb 驱动。
3.1.3 查看加载情况
修改配置文件后,执行 php -m 查看 Pdo_kdb 是否加载成功,以下是加载成功的正常输出:
$ php -m
[PHP Modules]
...
PDO
pdo_kdb
...
此时执行 php -m 出现报错,请参考常见问题说明。
3.2 Windows 环境
Windows 环境大多数 PHP 环境是直接使用的 PHP 安装包的形式,PHP 驱动包的安装路径相对固定,以下是一个 PHP 安装包的安装路径示例:
| 安装方式 | PHP可执行文件路径 | 驱动安装路径 |
|---|---|---|
| 安装包 | D:\PHP_install\php-7.2.0 | D:\PHP_install\php-7.2.0\ext |
Pdo_kdb 驱动安装的具体步骤如下:
3.2.1 解压安装
将 Pdo_kdb 驱动包解压后得到的库 php_pdo_kdb.dll 拷贝到上述驱动安装路径下即可。
需要注意的是 Windows 加载 DLL 的顺序,需要将 Pdo_kdb 驱动的依赖库 libkci.dll 及其依赖库(即驱动包内非 Pdo_kdb 的库)拷贝到 PHP 可执行文件路径下,对应上述表格的 D:\PHP_install\php-7.2.0 路径,否则 Windows 无法成功识别对应库导致 PHP 加载 Pdo_kdb 失败。
也可在 Windows 加载 DLL 的任一默认路径放置 Pdo_kdb 驱动的依赖库,本文不对此作详细描述。
3.2.2 配置 Pdo_kdb
执行 php --ini 查看 PHP 配置文件路径:
$ php --ini
Configuration File (php.ini) Path: C:\Windows
Loaded Configuration File: C:\Windows\php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
修改 C:\Windows\php.ini 的 php.ini 文件,在 extension=pdo; 下方添加一行 extension=pdo_kdb;,让 PHP 能加载 Pdo_kdb 驱动。
extension 也可配置全路径的形式,诸如:extension=D:\PHP_install\php_pdo_kdb.dll; 去加载指定路径的 Pdo_kdb 驱动。
3.2.3 查看加载情况
修改配置文件后,执行 php -m 查看 Pdo_kdb 是否加载成功,以下是加载成功的正常输出:
$ php -m
[PHP Modules]
...
PDO
pdo_kdb
...
此时执行 php -m 出现报错,请参考常见问题说明。
3.3 PHP-FPM
PHP-FPM(PHP FastCGI Process Manager),PHP FastCGI 进程管理器,用于管理 PHP 进程池的软件,用于接受 Web 服务器的请求。
PHP-FPM 主要用于 Web 应用,会有单独的进程处理 HTTP 请求。
从驱动安装部署的角度理解,用户开发环境的命令行执行 php -m 后发现安装了 Pdo_kdb 驱动,但并不一定在 Web 应用使用的 PHP 也安装了对应的 Pdo_kdb,因为命令行使用的 PHP 和 Web 应用使用的 PHP 可能不是同一个。
Web 应用部署的服务器多在 Linux 环境上,下文以 Linux 环境 PHP-FPM 安装部署 Pdo_kdb 作简要说明:
3.3.1 解压安装 Pdo_kdb 驱动包
若已知当前 Web 应用使用的 PHP 的驱动安装路径,则将 Pdo_kdb 驱动包解压放置在对应路径下。
若不清楚,也通过当前命令行环境执行 PHP-FPM 进程,如 php-fpm -m 查看是否有输出,若有,可参考命令行执行 PHP 的步骤添加 Pdo_kdb 驱动。
若不清楚 PHP 驱动安装路径,当前命令行环境也没有对应 PHP-FPM 进程,则跳过该步骤,参考下方修改配置文件步骤,修改 extension_dir 参数,让 PHP 加载指定路径的 Pdo_kdb 驱动。
3.3.2 创建测试用 PHP 文件,查看当前 PHP 信息
在当前 Web 开发环境下,浏览器可访问的 PHP 源文件开头,添加 phpinfo();,用于查看当前 Web 应用使用的 PHP 的详细信息:
如上图所示,可以清晰地看到 PHP 版本及对应参数信息,其中需要我们关注的是 Loaded Configuration File 栏对应的 php.ini 路径,有的 PHP-FPM 还会加载 Loaded Configuration File 下方两栏对应的额外配置文件,对应 conf.d 路径。
3.3.3 修改配置文件
PHP 会优先读取 conf.d 路径下的额外配置文件,再读取 php.ini。
若存在 conf.d 路径的额外配置文件,需要找到该路径下的配置文件有包含 pdo 模块的文件,在 extension=pdo; 下方添加一行 extension=pdo_kdb;,让 PHP 能识别并加载 Pdo_kdb 驱动。
若不存在 conf.d 路径,则直接修改 php.ini 配置文件,在 extension=pdo; 下方添加一行 extension=pdo_kdb; 即可。
备注:
若不清楚 PHP 加载模块路径,也可修改 php.ini 配置文件的 extension_dir 参数,让 PHP 读取指定路径下的 Pdo_kdb 驱动。
3.3.4 查看 PHP 信息
修改配置文件后,浏览器刷新页面,查看 phpinfo(); 对应的网页,ctrl+f 搜索是否有 pdo_kdb 加载,若没有,可按以下步骤依次排查:
• PHP 加载依赖库失败
可在命令行执行 ldd pdo_kdb.so 查看系统默认的加载路径是啥,并将 pdo_kdb 驱动的依赖库放置到系统路径下,以下是一个具体示例:
$ ldd pdo_kdb.so
...
libc.so.6 => /lib64/libc.so.6 (0x0000fffe1cde0000)
...
执行 ldd 后,将打印当前环境变量下的默认搜索路径,如示例所示,当前系统默认搜索 /lib64 下的动态库。
将 Pdo_kdb 驱动包内非 pdo_kdb.so 的所有 so 库拷贝到 /lib64 路径下即可。
• PHP 读取到其他的配置文件
若使用了集成环境,如:宝塔、phpstudy等,对应 PHP 配置文件需要在集成环境页面 PHP 设置页修改,在 extension=pdo; 下方添加一行 extension=pdo_kdb; 即可。
• PHP-FPM 进程需要重启
若当前环境有常驻的 PHP-FPM 进程,则需要在修改 php.ini 配置文件后,重启 PHP-FPM 进程。
按上述步骤排查后,刷新页面,可在网页看到 pdo_kdb 加载成功。
四、测试场景
确保 PHP 已成功加载 Pdo_kdb 驱动的前提下,此时可编写测试用例连接并操作数据库,以下是一个具体的操作示例:
创建连接:
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
例:
$dbh = new PDO("kdb:host=127.0.0.1;dbname=test;port=54321;", "system", "123456", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
使用刚刚创建的 $dbh 对象执行建表语句:
$stmt = $dbh->prepare('drop table if exists test_kdb');
$stmt->execute();
$stmt = $dbh->prepare('create table test_kdb(id int, name varchar(20))');
$stmt->execute();
绑定参数,并执行插入:
# 插入
$name = 'kingbase';
$stmt = $dbh->prepare("insert into test_kdb values(1, :name)");
$stmt->execute(array($name));
插入成功后,执行查询,并打印结果集:
$id = 1;
$stmt = $dbh->prepare('select * from test_kdb where id=?');
$stmt->execute(array($id));
$res = $stmt->fetchAll();
var_dump($res);
完整示例如下:
<?php
$dsn = "kdb:host=127.0.0.1;dbname=test;port=54321;";
$user = 'system';
$password = '123456';
$dbh = null;
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$stmt = $dbh->prepare('drop table if exists test_kdb');
$stmt->execute();
$stmt = $dbh->prepare('create table test_kdb(id int, name varchar(20))');
$stmt->execute();
# 插入
$name = 'kingbase';
$stmt = $dbh->prepare("insert into test_kdb values(1, :name)");
$stmt->execute(array($name));
# 查询
$id = 1;
$stmt = $dbh->prepare('select * from test_kdb where id=?');
$stmt->execute(array($id));
$res = $stmt->fetchAll();
var_dump($res);
?>
示例期望输出如下:
array(1) {
[0]=>
array(4) {
["id"]=>
int(1)
[0]=>
int(1)
["name"]=>
string(8) "kingbase"
[1]=>
string(8) "kingbase"
}
}
五、常见问题处理
-
执行
php -m,报错:libkci.so.5: cannot open shared object file: No such file or directory
Pdo_kdb 驱动依赖 Libkci 库(老版本会依赖 Libpq 库),系统加载 Pdo_kdb 时,无法加载 Pdo_kdb 驱动的依赖库及其依赖导致的问题
处理:
将 Libkci 及其驱动包(老版本为 Libpq)放置在ldd pdo_kdb.so的系统默认搜索路径下即可。 -
执行
php -m,报错:undefined symbol: pdo_parse_params
PHP 未成功加载 PDO 模块的前提下加载 Pdo_kdb 驱动导致的问题。
处理:
将extension=pdo_kdb的配置放置在extension=pdo下方即可。 -
执行
php -m,报错:undefined symbol: file_globals_id
PHP 是否线程安全与 Pdo_kdb 驱动包的是否线程安全版本不一致,如:PHP 非线程安全版本使用的线程安全版本的 Pdo_kdb 驱动。
处理:
使用线程安全版本一致的 Pdo_kdb 驱动包。 -
PHP 操作数据库,表存在但无法查找对应表;
可能是由于当前表及库存在在非 public 的 schema 下。
处理:
可在连接串指定 search_path 为期望搜索的 schema 解决:
# 如期望搜索 newschema 这个 schema 下的表
$dsn = "kdb:host=127.0.0.1;dbname=test;port=54321;options='-csearch_path=newschema'";
$dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
六、总结
KingbaseES数据库兼具国产数据库的高性能与高可用特性,为各类应用场景提供可靠支持。无论是传统行业数字化转型,还是互联网创新项目,Kdbndp都能作为理想的数据访问层解决方案。同时,该数据库提供完善的迁移支持,可轻松应对Oracle/MySQL等数据库迁移需求,并为使用PHP驱动Pdo_kdb的开发者提供良好开发体验。