我正在使用 Yii2 PHP 框架访问 Firebird 3.0 数据库,不幸的是,该数据库仍然采用方言 1。其中有很多数字(15,2)字段。这是存储货币值的非常自然的方法,双精度不是这种类型。
我的表声明为:
create table invoices(
id integer not null,
total_amount numeric(15,2),
primary key(id));
我正在使用这个 Yii2 控制器功能来访问数据库:
public function actionGetList() {
$sql_text="
select
d.id,
d.total_amount
from invoices
";
$data = new \stdClass();
$data->invoices = Array();
$db_data = Yii::$app->db2->createCommand($sql_text, [])->queryAll();
//var_dump($db_data);
foreach ($db_data as $rec) {
$inv = new \stdClass();
$inv->id = $rec["id"];
$inv->total_amount = $rec["total_amount"];
$data->invoices[] = $inv;
}
return json_encode($data);
}
我的db2.php访问配置是:
<?php
if (!extension_loaded('interbase')) {
echo "Firebird/InterBase extension not loaded";
exit;
}
return [
'class' => 'edgardmessias\db\firebird\Connection',
'dsn' => 'firebird:dbname=192.168.1.1/3050:/database/INVOICES.FDB',
'username' => 'SYSDBA',
'password' => 'masterkey',
'charset' => 'cp1257',
'enableSchemaCache' => false,
'schemaCacheDuration' => 3600,
'schemaCache' => 'cache',
];
所以,我没有使用 Yii2 ORM,我只是使用 Yii2 数据库访问,ORM 当然不适用于方言 1。
var_dump 结果给出:
["total_amount"]=> string(13) "4039119896.80"
,但是从 $db_data
数组中读取可能会给出 4039119896.80
或 24833794986.24
,具体取决于我是否正在读取单个记录的记录列表(对于特定 id 值)。
我从类型为
integer
或 double
精度的字段读取数值没有问题,只是 numeric(...) 有这样的问题。
当然,解决方案可以绕过 Yii2 数据库结构并直接读取 PDO 或其他一些低级驱动程序,但是,也许还有一些解决方案可以保留 Yii2 DB 设施?
正如@pilcrow正确建议的那样,我坚持了https://github.com/php/php-src/issues/9971错误并将我的项目从 PHP/php_pdo_firebird.dll 7.3.10 移动到 PHP/php_pdo_firebird.dll 8.2 .4 解决了问题。
我测试了低级 PDO 和 ibase 代码,并确认 ibase Firebird 驱动程序即使在旧的 PHP 版本上也能正常工作(至少在这个问题上),但 PDO Firebird 驱动程序需要迁移到 PHP 8.2 才能解决该问题。所以,这不是 Yii2 问题,这是 Yii2 使用的 PDO 问题。