Search code examples
phpyii2firebirdfirebird-3.0

Yii2 returns Firebird 3.0 dialect 1 numeric(15,2) field as string with constant junk value (24833794986.24 or 4039119896.80)


I am using Yii2 PHP framework to access Firebird 3.0 database which, unfortunately, is still in dialect 1. I have lot of numeric(15,2) fields in it. That is quite natural approach to store monetary values, double precision is not the type for that.

My table is declared as:

create table invoices(
  id integer not null,
  total_amount numeric(15,2),
  primary key(id));

I am using this Yii2 controller function to access database:

 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);    
    }

And my db2.php access configuration is:

    <?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',
];

So, I am not using Yii2 ORM, I am just using Yii2 database access, ORM is not working for dialect 1, of course.

The var_dump result gives: ["total_amount"]=> string(13) "4039119896.80" but the reading from the $db_data array may give 4039119896.80 or 24833794986.24 depending whether I am reading list of records of just single recod (for specific id value).

I have no problems reading numeric values from the fields whose types are integer or double precision, just numeric(...) has such problems.

Of course, the solution could be bypassing Yii2 database structures and making direct read against PDO or some other low level driver, but, still, maybe there is some solution to stay with Yii2 DB facilities?


Solution

  • As @pilcrow rightly suggested, I stuck on https://github.com/php/php-src/issues/9971 error and moving my project from PHP/php_pdo_firebird.dll 7.3.10 to PHP/php_pdo_firebird.dll 8.2.4 solved the issue.

    I tested low level PDO and ibase code and it confirmed, that ibase Firebird driver worked correctly (at least wrt this issue) even on the old PHP versions, but PDO Firebird drived required move to PHP 8.2 to solve the issue. So, this was not Yii2 issue, this was PDO issue used by Yii2.