Skip to content

use the empty string instead of null as an array offset#12160

Closed
xabbuh wants to merge 1 commit intodoctrine:3.5.xfrom
xabbuh:php-8.5
Closed

use the empty string instead of null as an array offset#12160
xabbuh wants to merge 1 commit intodoctrine:3.5.xfrom
xabbuh:php-8.5

Conversation

@xabbuh
Copy link
Copy Markdown
Member

@xabbuh xabbuh commented Sep 9, 2025

No description provided.

@xabbuh xabbuh force-pushed the php-8.5 branch 2 times, most recently from 0e2692f to 3aa7791 Compare September 9, 2025 19:54
@greg0ire
Copy link
Copy Markdown
Member

greg0ire commented Sep 9, 2025

What prompted you to contribute this? Was it static analysis or was it tests? If it's static analysis and there are no unit tests covering theses cases, maybe we should use assertions instead?

@xabbuh
Copy link
Copy Markdown
Member Author

xabbuh commented Sep 10, 2025

Sorry I forgot to mention. This is a deprecation that will be introduced with PHP 8.5. We caught this in the Symfony CI. So I enabled a PHP 8.5 job on my fork and these were the places that were caught by the tests.

@greg0ire
Copy link
Copy Markdown
Member

Oh ok so there are actual situations where this can happen 🤯

{
if (isset($this->class->fieldMappings[$this->class->versionField]->inherited)) {
$definingClassName = $this->class->fieldMappings[$this->class->versionField]->inherited;
if (isset($this->class->fieldMappings[$this->class->versionField ?? '']->inherited)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we take this one as an example, does it happen in a realistic scenario, or would it make sense to trigger a deprecation ourselves in the next major release?

Copy link
Copy Markdown
Member Author

@xabbuh xabbuh Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea. 🤷 But it's actually triggered a lot of times in the tests (see https://github.com/xabbuh/orm/actions/runs/17612071318/job/50036129395#step:6:84).

greg0ire
greg0ire previously approved these changes Sep 10, 2025
$sqlParts[] = $col . ' AS ' . $columnAlias;

$this->scalarResultAliasMap[$resultAlias][] = $columnAlias;
$this->scalarResultAliasMap[$resultAlias ?? ''][] = $columnAlias;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it even be added in scalarResultAliasMap if there is no result alias ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure here about the implications if we don't add it. In other places we use the $scalarResultCounter property but I have no idea if that would work as expected here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after re-reading how the map is accessed in walkResultVariable() it's probably safe to assume that adding an entry here in case of $resultAlias being null doesn't make much sense

// Get any aliases that are available for select expressions.
foreach ($AST->selectClause->selectExpressions as $selectExpression) {
$selectAliasToExpressionMap[$selectExpression->fieldIdentificationVariable] = $selectExpression->expression;
$selectAliasToExpressionMap[$selectExpression->fieldIdentificationVariable ?? ''] = $selectExpression->expression;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we rather skip expressions that have no identification variable (instead of keeping only the last one as they will anyway override each other in that map) ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, it didn't make a difference before as we never read from the map below when $orderByItem->expression was not a string. So we can just abstain from adding it.

foreach ($orderByClause->orderByItems as $orderByItem) {
if (is_string($orderByItem->expression) && isset($selectAliasToExpressionMap[$orderByItem->expression])) {
$orderByItem->expression = $selectAliasToExpressionMap[$orderByItem->expression];
if (is_string($orderByItem->expression) && isset($selectAliasToExpressionMap[$orderByItem->expression ?? ''])) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is useless, as is_string($orderByItem->expression) already ensures it is not null (same on next line)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, reverted

{
if (isset($this->class->fieldMappings[$this->class->versionField]->inherited)) {
$definingClassName = $this->class->fieldMappings[$this->class->versionField]->inherited;
if (isset($this->class->fieldMappings[$this->class->versionField ?? '']->inherited)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be clearer to handle the (common) case of classes without a version field explicitly instead of attempting an array check with the empty string.

Suggested change
if (isset($this->class->fieldMappings[$this->class->versionField ?? '']->inherited)) {
if ($this->class->versionField !== null && isset($this->class->fieldMappings[$this->class->versionField]->inherited)) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

nicolas-grekas added a commit to symfony/symfony that referenced this pull request Sep 16, 2025
This PR was merged into the 6.4 branch.

Discussion
----------

 Fix ord()-related PHP 8.5 deprecations

| Q             | A
| ------------- | ---
| Branch?       | 6.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | -
| License       | MIT

The remaining deprecations will be fixed by doctrine/orm#12160

Commits
-------

5314fd5 Fix ord()-related PHP 8.5 deprecations
@xabbuh xabbuh force-pushed the php-8.5 branch 3 times, most recently from 530099d to 3bb9931 Compare September 20, 2025 08:12
@xabbuh
Copy link
Copy Markdown
Member Author

xabbuh commented Sep 20, 2025

thanks for the reviews, comments addressed, this is ready from my side

SenseException
SenseException previously approved these changes Sep 21, 2025
@derrabus
Copy link
Copy Markdown
Member

I thought it might be great if PHPStan could help us in that regard. phpstan/phpstan#13592

derrabus
derrabus previously approved these changes Sep 26, 2025
Copy link
Copy Markdown
Member

@derrabus derrabus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a nit-pick.

$sqlParts[] = $col . ' AS ' . $columnAlias;

$this->scalarResultAliasMap[$resultAlias][] = $columnAlias;
if (is_string($resultAlias)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it explicit that this is actually a null-check.

Suggested change
if (is_string($resultAlias)) {
if ($resultAlias !== null) {

$sqlParts[] = $col . ' AS ' . $columnAlias;

$this->scalarResultAliasMap[$resultAlias][] = $columnAlias;
if (is_string($resultAlias)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

@xabbuh
Copy link
Copy Markdown
Member Author

xabbuh commented Sep 29, 2025

@derrabus made me aware that 2.20 is still maintained so here is another PR targeting the 2.20.x branch: #12181 (merging up will later then lead to conflicts so I keep this PR open as a reference on how to resolve them)

@xabbuh
Copy link
Copy Markdown
Member Author

xabbuh commented Oct 7, 2025

#12191 handles this

@xabbuh xabbuh closed this Oct 7, 2025
@xabbuh xabbuh deleted the php-8.5 branch October 7, 2025 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants