Skip to content

[PHP 8.3] constants have their namespace lowercased #11423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ju1ius opened this issue Jun 11, 2023 · 13 comments
Closed

[PHP 8.3] constants have their namespace lowercased #11423

ju1ius opened this issue Jun 11, 2023 · 13 comments

Comments

@ju1ius
Copy link
Contributor

ju1ius commented Jun 11, 2023

Description

The following code:

const char* name = "Foo\\Bar\\BAZ";
zend_register_long_constant(name, strlen(name), 42, CONST_CS|CONST_PERSISTENT, module_number);
$re = new \ReflectionExtension('my_extension');
var_dump($re->getConstants());

Resulted in this output:

array(1) {
  ["foo\bar\BAZ"]=>
  int(42)
}

But I expected this output instead:

array(1) {
  ["Foo\Bar\BAZ"]=>
  int(42)
}

This also affects user-defined constants, see #11423 (comment).

This behaviour was introduced in php 8.3 by the removal of the name field of the zend_constant struct in f42992f (#10954).

PHP Version

PHP 8.3-dev

Operating System

irrelevant

@kocsismate
Copy link
Member

Uhh, thanks for raising this issue! I'll definitely look at it ASAP, possibly tomorrow.

@kocsismate
Copy link
Member

kocsismate commented Jun 14, 2023

The behaviour which causes the issue was introduced in e2ad4e01780bf1e6cba162750946b9adfc40526b for fixing a bug. I missed to remove it since the bug is not possible anymore (as constants are always case sensitive now).

UPDATE: case-insensitive constants are irrelevant here, since this bug is about the namespace.

@kocsismate
Copy link
Member

kocsismate commented Jun 14, 2023

I added the invalid tag for now because surprisingly, the new behavior is still consistent with userland constants defined via define().

If you have a look at this test, you'll notice that the namespace of userland constants defined by define() is also converted to lowercase characters.

So I'm not sure if we have to/can follow any strict rule regarding how the namespace of constants should be stored.

UPDATE: I'm a bit tired I guess... Of course, this behavior is the result of my changes in PHP 8.3.. And previously, the constant names were displayed with the correct casing.

So do you guys think that my changes should be reverted? Or do you see any reasonable fix for the problem? @Girgias @iluuu1994

@iluuu1994
Copy link
Member

This is not limited to internal constants.

--TEST--
get_defined_constants() namespace casing
--FILE--
<?php
namespace Foo {
    const BAR = 'BAR';
}
namespace {
    foreach (get_defined_constants() as $name => $value) {
        if ($value === 'BAR') {
            var_dump($name);
        }
    }
}
?>
--EXPECT--
string(7) "foo\BAR"

Tbh I don't believe shrinking the size of constants is particularly important. We're saving 8 bytes per constant. It doesn't matter too much for space or cache locality. We do try to preserve casing in most cases, including error messages. There is already an edge case where the name casing is not preserved: php/doc-en#2383.

Casing consistency is not a huge deal to me, but I'm not sure if we should intentionally break unless there is a clear win.

@Girgias
Copy link
Member

Girgias commented Jun 15, 2023

I didn't know we stored namespaces in lowercase form. Is this because of how we store namespaces in a similar way to class/function names which are case insensitive?

@iluuu1994
Copy link
Member

@Girgias Yes, namespaces are case-insensitive, the constant itself is not. So the namespace is lower-cased for canonicalization. The original constant name was previously stored in zend_constant.

@Girgias
Copy link
Member

Girgias commented Jun 15, 2023

TIL, thanks for the expllanation!

@ju1ius
Copy link
Contributor Author

ju1ius commented Jun 15, 2023

This is not limited to internal constants.

Indeed, title updated to reflect this fact.

@ju1ius ju1ius changed the title [PHP 8.3] internal constants have their namespace lowercased [PHP 8.3] constants have their namespace lowercased Jun 15, 2023
@ju1ius
Copy link
Contributor Author

ju1ius commented Jun 27, 2023

So do you guys think that my changes should be reverted? Or do you see any reasonable fix for the problem?

Unfortunately, without storing the original names somewhere, they will be lost in time like tears in the rain. I can't see any viable solution other than retire the changes...

@kocsismate
Copy link
Member

With somewhat sad heart, I've just reverted my commit :(

@ju1ius
Copy link
Contributor Author

ju1ius commented Jul 6, 2023

Hi @kocsismate, I tried a new build from master but although I can see the commit in the git log, the revert doesn't appear there... It shows up when using the php8.3alpha3 tag though... Is that to be expected ?

@iluuu1994
Copy link
Member

I had to revert the revert because it caused segfaults in CI. I'll have to take a closer look why.

@ju1ius
Copy link
Contributor Author

ju1ius commented Jul 6, 2023

I had to revert the revert because it caused segfaults in CI. I'll have to take a closer look why.

Ah sorry, I guess the revert revert message tripped me up...

Maybe the issue should be reopened then?

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

No branches or pull requests

4 participants