Skip to content

PDO_OCI returns NULL on INSERT...RETURNING operations in PHP 8.2 - #4617

Open
andreaepifani-afk wants to merge 4 commits into
yiisoft:masterfrom
andreaepifani-afk:master
Open

PDO_OCI returns NULL on INSERT...RETURNING operations in PHP 8.2#4617
andreaepifani-afk wants to merge 4 commits into
yiisoft:masterfrom
andreaepifani-afk:master

Conversation

@andreaepifani-afk

Copy link
Copy Markdown

A critical issue encountered when migrating from PHP 7.3 to PHP 8.2 using the PDO_OCI driver with Oracle database.

After migrating from PHP 7.3.20, the application stopped functioning correctly. Whenever a new record was created in Oracle, the RETURNING INTO clause failed to populate the ID reference, returning NULL instead. I fixed this by explicitly casting the variable to an integer to ensure proper binding in the PHP 8 environment.

Forced $this->returnID = 0; immediately before bindParam to ensure a clean integer memory buffer is allocated.
Tested with php 8.2.28 and work fine, backward compatibility maintained.

Q A
Is bugfix? ✔️

Forced $returnID to integer.
@marcovtwout

Copy link
Copy Markdown
Member

I understand this fixed the issue in your application, but the fix itself looks like a workaround for a bug somewhere.

Based on your information I cannot judge if this is a framework issue or part of the environment (application code, specific Oracle, PHP and driver versions). To judge that we would need a reproducable example of the bug you encountered and/or insight into the exact root cause for which component update exactly caused a regression.

@andreaepifani-afk

Copy link
Copy Markdown
Author

Hi @marcovtwout ,

To isolate the issue from my specific application, I created a clean project using ./yiic webapp test-oci and performed the following steps:

  • Configured the connection string for the Oracle database.
  • Generated a single model using Gii.
  • Implemented the following logic in the SiteController action:
    $model = new LOG(); $model->LOGLEVEL = 'low'; $model->CATEGORY = 'home'; if($model->save()) { echo $model->ID; var_dump($model->ID); }
    The output is NULL.

I have identified that the bug is located in COciCommandBuilder, specifically regarding how returnID is handled during the binding process.

Fixed a random 503 Service Unavailable crash on PHP 8.2 caused by the previous fix. Following Yii2 strategies, the RETURNING INTO clause was removed from INSERT statements in PDO_OCI. The last insert ID is now safely retrieved via a separate sequence_name.CURRVAL query.
@marcovtwout

marcovtwout commented Mar 5, 2026

Copy link
Copy Markdown
Member

Thanks for looking further into it :)

I'm not sure the actual bug is in the framework code, it looks like the call to $command->bindParam() is done correctly, passing PDO::PARAM_INT as the explicit parameter type: https://github.com/yiisoft/yii/blob/master/framework/db/schema/oci/COciCommandBuilder.php#L112

Since you now have a reproducable test case, could you test further to see where the regression starts, ie. which version of PHP or PDO_OCI exactly breaks the update? And which version of Oracle Database on which platform are you using?

@marcovtwout

Copy link
Copy Markdown
Member

Update: I think the bug is in the PDO_OCI library, this looks very similar to your report: php/pecl-database-pdo_oci#26
You can verify this by creating a reproducable example, using only PHP code (without framework code) using the same queries Yii is using.

@andreaepifani-afk

andreaepifani-afk commented Mar 5, 2026

Copy link
Copy Markdown
Author

Hi have alredy testing with pdo:

`
$yp0 = 'low';
$yp1 = 'home';
$sql = 'INSERT INTO "LOG" ("LOGLEVEL", "CATEGORY") VALUES (:yp0,:yp1) RETURNING "ID" INTO :id';
$stmt = $conn->prepare($sql);
//$id = 0; // force $id to int

$stmt->bindParam(':id', $id, PDO::PARAM_INT, 12);
$stmt->bindParam(':yp0', $yp0, PDO::PARAM_INT);
$stmt->bindParam(':yp1', $yp1, PDO::PARAM_STR);

$stmt->execute();
$stmt->closeCursor();
echo "Inserted ID: " . $id . "
";
var_dump($id);
`

this code, similar at yii1 implementation, the id return NULL.
If $id = 0 forced (commented), $id returned with newid sequence.
Oracle 19, PHP 8.2.28, pdo_oci [1.1.0] from pecl, redhat 9.6

I updated my PR with commit that remove RETURNING INTO clause.

implement method getTableSequenceName to retrieve the correct sequence name of table.
@marcovtwout

Copy link
Copy Markdown
Member

@andreaepifani-afk That confirms the source of the issue is not in the Yii framework but in PHP / PHP-OCI. It's not yet clear to me which version/change exactly broke the previous behavior, that would help to understand it better.

I suggest to investigate that further through php/pecl-database-pdo_oci#26 and once more info comes back we can see if there's anything we should do here.

@terabytesoftw

terabytesoftw commented Mar 16, 2026

Copy link
Copy Markdown
Member

The problem is that OCI, in many operations, returns null, and in versions 7x it works because the use of null is not deprecated; it is a silent error, while in versions 8.1+ the deprecation error appears.

@marcovtwout

Copy link
Copy Markdown
Member

@terabytesoftw You are saying this issue is actually about a deprecation warning and not about a regression since a specific PHP/OCI update? Where exactly in our framework is the deprecation warning triggered?

@terabytesoftw

terabytesoftw commented Mar 16, 2026

Copy link
Copy Markdown
Member

If the error occurs in a function such as strpos(), I'm sure that's it; both yii1 and yii2 don't use strict types or default values, and these problems arise with depreciation. In 7x work.

Also, sometimes PDO varies according to the PHP version, and the problem must be resolved somehow.

btw I'll try this on Yii2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants