注册
php8.5版本驱动验证
专栏/技术分享/ 文章详情 /

php8.5版本驱动验证

青空 2026/08/28 140 0 0
摘要

1. 背景介绍

客户希望使用php8.5.8进行开发,但达梦数据库之前没有php8.5版本的驱动,向开发提需求后得到了开发提供的该版本驱动,需要进行测试,确认确实能连接php8.5

2. 环境

内容 版本/类型
操作系统 Kylin-Server-V10-SP3-2403
CPU x86_64bit
达梦数据库 达梦9(达梦8也可用)
php 8.5.8

3. 验证步骤

3.1. 先编译安装php8.5.8

因为麒麟的软件源里php最新只到8.0,所以从php官方下载源码编译安装

安装完成

[root@localhost ~]# php -v
PHP 8.5.8 (cli) (built: Aug 17 2026 10:58:25) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.5.8, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.8, Copyright (c), by Zend Technologies

3.2. 配置达梦pdo驱动

确认php8.5的扩展目录在哪

# 确认php的扩展目录 [root@localhost php-8.5.8]# php -i | grep extension_dir extension_dir => /usr/local/php858/lib/php/extensions/no-debug-non-zts-20250925 => /usr/local/php858/lib/php/extensions/no-debug-non-zts-20250925 sqlite3.extension_dir => no value => no value

复制达梦驱动到php的扩展目录,这里因为是php8.5.8版本,需要复制名字里带85(代表php8.5.x版本)的驱动

[root@localhost x86_kylin10_sp1_64]# cp libphp85_dm.so php85_pdo_dm.so /usr/local/php858/lib/php/extensions/no-debug-non-zts-20250925/ [root@localhost x86_kylin10_sp1_64]# ls -la /usr/local/php858/lib/php/extensions/no-debug-non-zts-20250925/ | grep dm -rw-r--r-- 1 root root 132512 8月 17 11:29 libphp85_dm.so -rw-r--r-- 1 root root 74016 8月 17 11:29 php85_pdo_dm.so

修改php.ini,让php能够加载达梦驱动

[root@localhost x86_kylin10_sp1_64]# vi /usr/local/php858/etc/php.ini

在末尾添加

[PHP_DM]
extension = libphp85_dm.so
extension = php85_pdo_dm.so

[dm]
dm.port = 5236
dm.allow_persistent = 1
dm.max_persistent = -1
dm.max_links = -1
dm.default_host = localhost
dm.default_db = SYSTEM
dm.default_user = SYSDBA
dm.default_pw = Dameng123
dm.connect_timeout = 10
dm.defaultlrl = 4096
dm.defaultbinmode = 1
dm.check_persistent = ON

设置环境变量

[root@localhost x86_kylin10_sp1_64]# export LD_LIBRARY_PATH=/data/dmdbms/bin:$LD_LIBRARY_PATH

3.3. 测试

检查php扩展是否安装成功

[root@localhost ~]# php -m | grep -i dm dm PDO_DM

扩展安装成功,测试一下连接是否成功

[root@localhost ~]# php -r " > try { > \$dbh = new PDO('dm:host=localhost;port=5236;dbname=SYSTEM', 'SYSDBA', 'Dameng123'); > echo '连接成功!' . PHP_EOL; > } catch (PDOException \$e) { > echo '连接失败:' . \$e->getMessage() . PHP_EOL; > } > " 连接成功!

3.3.1. 客户同款表测试

连接成功,测试一下建表,建个和客户一样的表

# 先创建模式
[root@localhost ~]# php -r "\$dbh = new PDO('dm:host=localhost;port=5236;dbname=SYSTEM', 'SYSDBA', 'Dameng123'); \$dbh->exec('CREATE SCHEMA \"gw_etc\"'); echo '模式创建成功' . PHP_EOL;"
模式创建成功

# 然后建表
[root@localhost ~]# vi /tmp/create_table.php
写入如下内容

<?php
$dbh = new PDO('dm:host=localhost;port=5236;dbname=SYSTEM', 'SYSDBA', 'Dameng123');
$sql = <<<SQL
CREATE TABLE "gw_etc"."admininfo" (
  "id" INT IDENTITY(3, 1) NOT NULL,
  "admin_id" VARCHAR(64 CHAR) DEFAULT '' NOT NULL,
  "admin_pass" VARCHAR(64 CHAR),
  "admin_type" VARCHAR(11 CHAR) DEFAULT '' NOT NULL,
  "admin_purview" TINYINT DEFAULT 0 NOT NULL,
  "admin_name" VARCHAR(16 CHAR),
  "admin_desc" VARCHAR(128 CHAR),
  "change_password" TINYINT DEFAULT 1 NOT NULL,
  "enable_flag" TINYINT DEFAULT 1 NOT NULL,
  "expired_time" BIGINT DEFAULT 0,
  "comment" VARCHAR(128 CHAR),
  "domain_name" TEXT NOT NULL,
  NOT CLUSTER PRIMARY KEY("id"),
  CONSTRAINT "uni@gw_etc@admininfo@admin_id" UNIQUE("admin_id")
) STORAGE(ON "MAIN", CLUSTERBTR);
SQL;
$dbh->exec($sql);
echo "表 admininfo 创建成功\n";

[root@localhost ~]# php /tmp/create_table.php
表 admininfo 创建成功

# 验证表记录数
[root@localhost ~]# php -r "
> \$dbh = new PDO('dm:host=localhost;port=5236;dbname=SYSTEM', 'SYSDBA', 'Dameng123');
> \$stmt = \$dbh->query('SELECT COUNT(*) FROM \"gw_etc\".\"admininfo\"');
> echo '表记录数:' . \$stmt->fetchColumn() . PHP_EOL;
> "
表记录数:0

一切正常,刚创的表肯定是没记录

测试一下增删查改是否正常

[root@localhost ~]# vi /tmp/test_crud.php
【文件内容见附录】
[root@localhost ~]# php /tmp/test_crud.php
插入影响行数:1
查询结果:
Array
(
    [id] => 4
    [admin_id] => test001
    [admin_name] => 测试员
    [domain_name] => test.domain.com
)
更新影响行数:1
更新后查询结果:
Array
(
    [id] => 4
    [admin_id] => test001
    [admin_name] => 更新测试
    [domain_name] => test.domain.com
)
删除影响行数:1
剩余记录数(应等于0):0

3.3.2. 验证columnCount()和fetch()是否正常

用客户相同的测试逻辑

[root@localhost ~]# vi /tmp/reproduce_customer_test.php [root@localhost ~]# php /tmp/reproduce_customer_test.php ======================================== PHP 8.5.8 + 达梦 8.5 驱动 验证测试 ======================================== ✓ PDO 连接成功 ✓ 测试数据插入成功 query() 测试 返回类型: PDOStatement columnCount(): 3 (期望: 3) rowCount(): -1 列元数据 (getColumnMeta): 列 0: id (int) 列 1: admin_id (varchar) 列 2: admin_type (varchar) fetch(PDO::FETCH_ASSOC) 测试: 返回: 数组 Array ( [id] => 3 [admin_id] => test_customer [admin_type] => admin ) fetchAll() 测试: 行数: 1 第1行数据: Array ( [id] => 3 [admin_id] => test_customer [admin_type] => admin ) ======================================== 环境信息 ======================================== PHP 版本: 8.5.8 PDO 驱动: mysql, sqlite, dm 达梦服务器版本: 9.1.0.26

3.3.3. 测试各种类型列能否正常创建、插入、读取

[root@localhost ~]# vi /tmp/test_dm_types.php
【文件内容见附录】
[root@localhost ~]# php /tmp/test_dm_types.php
=== 达梦数据类型测试 ===

0. 清理旧表...
✅ 旧表已删除

1. 创建测试表 type_test...
✅ 表 type_test 创建成功

2. 查看表结构 (DESC)...
列名               | 数据类型    | 长度     | 精度     | 小数位 | 可空
-------------------------------------------------------------------------------------
id                   | INT             | 4          | -          | -        | 非空
varchar_col          | VARCHAR         | 100        | -          | -        | 可空
char_col             | CHAR            | 20         | -          | -        | 可空
int_col              | INT             | 4          | -          | -        | 可空
bigint_col           | BIGINT          | 8          | -          | -        | 可空
decimal_col          | DECIMAL         | 22         | 18         | 2        | 可空
number_col           | NUMBER          | 22         | 10         | 3        | 可空
real_col             | REAL            | 4          | 24         | -        | 可空
double_col           | DOUBLE          | 8          | 53         | -        | 可空
float_col            | FLOAT           | 8          | 53         | -        | 可空
date_col             | DATE            | 3          | -          | -        | 可空
time_col             | TIME            | 5          | -          | -        | 可空
timestamp_col        | TIMESTAMP       | 8          | -          | 6        | 可空
datetime_col         | DATETIME        | 8          | -          | 6        | 可空
blob_col             | BLOB            | 2147483647 | -          | -        | 可空
clob_col             | CLOB            | 2147483647 | -          | -        | 可空
text_col             | TEXT            | 2147483647 | -          | -        | 可空
tinyint_col          | TINYINT         | 1          | -          | -        | 可空
smallint_col         | SMALLINT        | 2          | -          | -        | 可空
bit_col              | BIT             | 1          | -          | -        | 可空

3. 插入测试数据...
✅ 测试数据插入成功

4. 查询数据 (SELECT *)...

字段名 | 值
----------------------------------------------------------------------
id                   | 1
varchar_col          | 测试字符串
char_col             | CHAR类型测试
int_col              | 12345
bigint_col           | 9876543210
decimal_col          | 12345.67
number_col           | 987.654
real_col             | 3.1415901
double_col           | 2.718281828
float_col            | 1.41421356
date_col             | 2026-08-17
time_col             | 14:30:25
timestamp_col        | 2026-08-17 14:30:25.000000
datetime_col         | 2026-08-17 14:30:25.123000
blob_col             | BLOB二进制数据测试
clob_col             | CLOB大文本内容测试
text_col             | TEXT大文本内容测试
tinyint_col          | 127
smallint_col         | 32767
bit_col              | 1

5. 表统计信息...
总行数: 1

✅ 测试完成!

4. 结论

该pdo驱动能在php8.5.8版本上正常使用,增删查改都正常,columnCount()和fetch()也能正常调用,各种类型(clob、blob、double、real、number、decimal、timestamp等)的创建、插入、删除也正常

5. 附录

5.1. 问题

5.1.1. 如果报错PHP Fatal error: Unable to start dm module in Unknown on line 0 Stack trace: #0 {main}

检查/usr/lib或/usr/lib64/下有没有libdmdpi.so文件,达梦pdo驱动依赖这个库。如果没有,可以在达梦数据库安装目录下的bin文件夹找到,复制到/usr/lib下

或者(临时)设置环境变量

[root@localhost php]# export LD_LIBRARY_PATH=/data/dmdbms/bin:$LD_LIBRARY_PATH

5.2. 驱动下载

下载链接:

5.2.1. x86架构版本

版本标识:releasing-3241-20260814-php-x86_kylin10_sp1_64

版本信息:releasing-3241-20260814-php-x86_kylin10_sp1_64

安装包链接:链接地址:https://eco.dameng.com/s/YHTOZL4I6E提取码:a83x

5.2.2. HWarm920版本

版本标识:releasing-3241-20260814-php-HWarm920_kylin10_sp1_64

版本信息:releasing-3241-20260814-php-HWarm920_kylin10_sp1_64

安装包链接:链接地址:https://eco.dameng.com/s/QJ11DAOI68提取码:wtrj

5.3. 测试用例

5.3.1. test_crud.php

<?php $dbh = new PDO('dm:host=localhost;port=5236;dbname=SYSTEM', 'SYSDBA', 'Dameng123'); // 1. 插入测试数据 $sql = 'INSERT INTO "gw_etc"."admininfo" ("admin_id", "admin_pass", "admin_type", "admin_purview", "admin_name", "admin_desc", "domain_name") VALUES (\'test001\', \'pass123\', \'admin\', 1, \'测试员\', \'测试描述\', \'test.domain.com\')'; $affected = $dbh->exec($sql); echo "插入影响行数:" . $affected . "\n"; // 2. 查询刚插入的数据 $stmt = $dbh->query('SELECT "id", "admin_id", "admin_name", "domain_name" FROM "gw_etc"."admininfo" WHERE "admin_id"=\'test001\''); $row = $stmt->fetch(PDO::FETCH_ASSOC); echo "查询结果:\n"; print_r($row); // 3. 更新数据 $sql = 'UPDATE "gw_etc"."admininfo" SET "admin_name"=\'更新测试\' WHERE "admin_id"=\'test001\''; $affected = $dbh->exec($sql); echo "更新影响行数:" . $affected . "\n"; // 4. 再次查询验证更新 $stmt = $dbh->query('SELECT "id", "admin_id", "admin_name", "domain_name" FROM "gw_etc"."admininfo" WHERE "admin_id"=\'test001\''); $row = $stmt->fetch(PDO::FETCH_ASSOC); echo "更新后查询结果:\n"; print_r($row); // 5. 删除测试数据 $sql = 'DELETE FROM "gw_etc"."admininfo" WHERE "admin_id"=\'test001\''; $affected = $dbh->exec($sql); echo "删除影响行数:" . $affected . "\n"; // 6. 最终验证删除成功 $stmt = $dbh->query('SELECT COUNT(*) FROM "gw_etc"."admininfo" WHERE "admin_id"=\'test001\''); $count = $stmt->fetchColumn(); echo "剩余记录数(应等于0):" . $count . "\n"; ?>

5.3.2. reproduce_customer_test.php

<?php echo "========================================\n"; echo " PHP 8.5.8 + 达梦 8.5 驱动 验证测试\n"; echo "========================================\n\n"; $dbh = new PDO('dm:host=localhost;port=5236;dbname=SYSTEM', 'SYSDBA', 'Dameng123'); echo "✓ PDO 连接成功\n\n"; // 先插入一条测试数据 $sql = 'INSERT INTO "gw_etc"."admininfo" ("admin_id", "admin_pass", "admin_type", "admin_purview", "admin_name", "admin_desc", "domain_name") VALUES (\'test_customer\', \'pass123\', \'admin\', 1, \'客户测试\', \'复现测试\', \'test.customer.com\')'; try { $dbh->exec($sql); echo "✓ 测试数据插入成功\n\n"; } catch (PDOException $e) { echo "ℹ 测试数据可能已存在\n\n"; } // 查询测试 $sql = 'SELECT "id", "admin_id", "admin_type" FROM "gw_etc"."admininfo"'; $stmt = $dbh->query($sql); echo "query() 测试\n"; echo "返回类型: " . get_class($stmt) . "\n"; echo "columnCount(): " . $stmt->columnCount() . " (期望: 3)\n"; echo "rowCount(): " . $stmt->rowCount() . "\n\n"; // 列元数据 echo "列元数据 (getColumnMeta):\n"; for ($i = 0; $i < $stmt->columnCount(); $i++) { $meta = $stmt->getColumnMeta($i); echo " 列 $i: " . $meta['name'] . " (" . $meta['native_type'] . ")\n"; } echo "\n"; // fetch 测试 echo "fetch(PDO::FETCH_ASSOC) 测试:\n"; $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row === false) { echo " 返回: false (无数据)\n"; } elseif (empty($row)) { echo " 返回: 空数组\n"; } else { echo " 返回: 数组\n"; print_r($row); } echo "\n"; // fetchAll 测试 echo "fetchAll() 测试:\n"; $stmt = $dbh->query('SELECT "id", "admin_id", "admin_type" FROM "gw_etc"."admininfo"'); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); echo " 行数: " . count($rows) . "\n"; if (count($rows) > 0) { echo " 第1行数据:\n"; print_r($rows[0]); } echo "\n"; echo "========================================\n"; echo " 环境信息\n"; echo "========================================\n"; echo "PHP 版本: " . PHP_VERSION . "\n"; echo "PDO 驱动: " . implode(", ", PDO::getAvailableDrivers()) . "\n"; echo "达梦服务器版本: " . $dbh->getAttribute(PDO::ATTR_SERVER_VERSION) . "\n"; ?>

5.3.3. test_dm_types.php

<?php $conn = dm_connect("localhost", "SYSDBA", "Dameng123"); if (!$conn) { die("连接失败: " . dm_error()); } echo "=== 达梦数据类型测试 ===\n\n"; $table_name = "type_test"; // 1. 删除旧表(如果存在) echo "0. 清理旧表...\n"; $drop_sql = "DROP TABLE IF EXISTS \"GW_ETC\".\"{$table_name}\" CASCADE"; if (dm_exec($conn, $drop_sql)) { echo "✅ 旧表已删除\n"; } else { // 如果表不存在,忽略错误 if (strpos(dm_error(), "无效的表或视图名") !== false) { echo "✅ 表不存在,跳过删除\n"; } else { echo "⚠️ 删除表时出现其他错误: " . dm_error() . "\n"; } } // 2. 创建测试表 echo "\n1. 创建测试表 {$table_name}...\n"; $create_sql = <<<SQL CREATE TABLE "GW_ETC"."{$table_name}" ( "id" INT IDENTITY(1, 1) NOT NULL, "varchar_col" VARCHAR(100), "char_col" CHAR(20), "int_col" INT, "bigint_col" BIGINT, "decimal_col" DECIMAL(18, 2), "number_col" NUMBER(10, 3), "real_col" REAL, "double_col" DOUBLE, "float_col" FLOAT, "date_col" DATE, "time_col" TIME, "timestamp_col" TIMESTAMP, "datetime_col" DATETIME, "blob_col" BLOB, "clob_col" CLOB, "text_col" TEXT, "tinyint_col" TINYINT, "smallint_col" SMALLINT, "bit_col" BIT, NOT CLUSTER PRIMARY KEY("id") ) STORAGE(ON "MAIN", CLUSTERBTR); SQL; if (dm_exec($conn, $create_sql)) { echo "✅ 表 {$table_name} 创建成功\n"; } else { echo "❌ 创建表失败: " . dm_error() . "\n"; dm_close($conn); exit; } // 3. 查看表结构 (DESC) echo "\n2. 查看表结构 (DESC)...\n"; $desc_sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE FROM USER_TAB_COLS WHERE TABLE_NAME = '{$table_name}' ORDER BY COLUMN_ID"; $result = dm_exec($conn, $desc_sql); if ($result) { echo sprintf("%-20s | %-15s | %-10s | %-10s | %-8s | %s\n", "列名", "数据类型", "长度", "精度", "小数位", "可空"); echo str_repeat("-", 85) . "\n"; while ($row = dm_fetch_array($result)) { echo sprintf("%-20s | %-15s | %-10s | %-10s | %-8s | %s\n", $row['COLUMN_NAME'], $row['DATA_TYPE'], $row['DATA_LENGTH'] ?: '-', $row['DATA_PRECISION'] ?: '-', $row['DATA_SCALE'] ?: '-', $row['NULLABLE'] == 'Y' ? '可空' : '非空' ); } dm_free_result($result); } // 4. 插入测试数据(BLOB使用HEXTORAW转换) echo "\n3. 插入测试数据...\n"; // 将字符串转换为十六进制(用于BLOB) $blob_data = "BLOB二进制数据测试"; $blob_hex = bin2hex($blob_data); // CLOB和TEXT可以直接插入字符串 $clob_data = "CLOB大文本内容测试"; $text_data = "TEXT大文本内容测试"; $insert_sql = <<<SQL INSERT INTO "GW_ETC"."{$table_name}" ( "varchar_col", "char_col", "int_col", "bigint_col", "decimal_col", "number_col", "real_col", "double_col", "float_col", "date_col", "time_col", "timestamp_col", "datetime_col", "blob_col", "clob_col", "text_col", "tinyint_col", "smallint_col", "bit_col" ) VALUES ( '测试字符串', 'CHAR类型测试', 12345, 9876543210, 12345.67, 987.654, 3.14159, 2.718281828, 1.41421356, DATE '2026-08-17', TIME '14:30:25', TIMESTAMP '2026-08-17 14:30:25', DATETIME '2026-08-17 14:30:25.123', HEXTORAW('{$blob_hex}'), '{$clob_data}', '{$text_data}', 127, 32767, 1 ) SQL; if (dm_exec($conn, $insert_sql)) { echo "✅ 测试数据插入成功\n"; } else { echo "❌ 插入失败: " . dm_error() . "\n"; echo "SQL: " . $insert_sql . "\n"; } // 5. 查询数据 echo "\n4. 查询数据 (SELECT *)...\n"; $select_sql = "SELECT * FROM \"GW_ETC\".\"{$table_name}\""; $result = dm_exec($conn, $select_sql); if ($result) { $row = dm_fetch_array($result); if ($row) { echo "\n字段名 | 值\n"; echo str_repeat("-", 70) . "\n"; foreach ($row as $key => $value) { if (is_null($value)) { $display = "NULL"; } elseif (strlen($value) > 100) { $display = substr($value, 0, 100) . "..."; } else { $display = $value; } echo sprintf("%-20s | %s\n", $key, $display); } } else { echo "❌ 没有数据\n"; } dm_free_result($result); } // 6. 查看行数 echo "\n5. 表统计信息...\n"; $count_sql = "SELECT COUNT(*) AS total_rows FROM \"GW_ETC\".\"{$table_name}\""; $result = dm_exec($conn, $count_sql); if ($result) { $row = dm_fetch_array($result); echo "总行数: " . $row['TOTAL_ROWS'] . "\n"; dm_free_result($result); } dm_close($conn); echo "\n✅ 测试完成!\n"; ?>
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服