Skip to content

[RFC] Implement dynamic class const fetch #9793

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
wants to merge 1 commit into from

Conversation

iluuu1994
Copy link
Member

@iluuu1994 iluuu1994 commented Oct 20, 2022

@bwoebi
Copy link
Member

bwoebi commented Oct 21, 2022

Foo::{$bar} ?? 'Bar' should likely suppress undefined class constant errors

Yes, I agree, but for consistency, all constant access should be able to isset/coalesced. I.e. also a trivial isset(NOT_DEFINED_CONST) and isset(Foo::NOT_DEFINED_CLASS_CONST). Because otherwise you introduce a discrepancy between Foo::{'NOT_DEFINED'} and either Foo::{$bar} or Foo::NOT_DEFINED.

@nikic
Copy link
Member

nikic commented Oct 22, 2022

Nice, this was always a bit of a weird hole in our variable variable syntax.

Foo::{$bar} ?? 'Bar' should likely suppress undefined class constant errors

Yes, I agree, but for consistency, all constant access should be able to isset/coalesced. I.e. also a trivial isset(NOT_DEFINED_CONST) and isset(Foo::NOT_DEFINED_CLASS_CONST). Because otherwise you introduce a discrepancy between Foo::{'NOT_DEFINED'} and either Foo::{$bar} or Foo::NOT_DEFINED.

That seems like an orthogonal change (not sure whether it's a good one). For the purposes of this proposal, the existing semantics should be followed, under which isset(), and consequently ??, has no interaction with constant lookup.

@iluuu1994
Copy link
Member Author

iluuu1994 commented Oct 22, 2022

@nikic

For the purposes of this proposal, the existing semantics should be followed, under which isset(), and consequently ??, has no interaction with constant lookup.

Suppressing errors would provide a direct counterpart for tryFrom: State::{$stateName} ?? State::Default. I don't necessarily think that's something you should do but without adjusting interaction with ?? the result is only slightly better than the status quo, if at all:

// PHP 8.2
$fqn = State::class . '::' . $stateName;
$result = defined($fqn) ? constant($fqn) : State::Default;

// Without ??
$fqn = State::class . '::' . $stateName;
$result = defined($fqn) ? State::{$stateName} : State::Default;

// WIth ??
$result = State::{$stateName} ?? State::Default;

We have three obvious options:

  1. Don't change the interaction of class constant lookups and ??
  2. Make ?? suppress missing class constant errors but only for dynamic lookups
  3. Make ?? suppress missing class constant errors for all cases, even if the constant name is specified literally

Number 3 sounds undesirable at first but given that ?? (and isset) only suppress errors in the root chain of which :: is not usually a part of it might be a viable option. (e.g. $foo->bar->{$baz}[$qux] ?? null will suppress undeclared $foo, undeclared ->bar but not undeclared $baz or $qux). :: in the root chain of ?? is uncommon because class constants historically could not contain objects on which you'd use -> (which does interact with ??) and exactly because it doesn't interact with ??, so there was no point in putting it there. One imaginable case is Foo::CONST_THAT_MGIHT_BE_NULL ?? 'foo' where the constant is overridden.

That said, I'm ok with starting with option 1. Relaxing it will always be easier than the opposite.

@mvorisek
Copy link
Contributor

mvorisek commented Oct 22, 2022

I would prefer ?? to silently ignore only missing array key (otheriwse huge BC break, related #8349) and emit a normal warning for missing property/key. So when moving into this safety direction, ?? should NOT suppress missing constant.

@bwoebi
Copy link
Member

bwoebi commented Oct 22, 2022

@iluuu1994 While it's certainly most useful that way, it might warrant two different RFCs, first a RFC for IS fetches on constants, then a RFC on dynamic class const fetch?

@iluuu1994 iluuu1994 force-pushed the dynamic-class-const-fetch branch from e348735 to d4c1c60 Compare November 3, 2022 19:11
@iluuu1994 iluuu1994 force-pushed the dynamic-class-const-fetch branch from a7cd4dc to 36db851 Compare November 4, 2022 01:05
@iluuu1994 iluuu1994 force-pushed the dynamic-class-const-fetch branch from c02e1b1 to e423774 Compare December 22, 2022 17:52
@iluuu1994 iluuu1994 force-pushed the dynamic-class-const-fetch branch from e423774 to 5c4394d Compare January 12, 2023 11:23
@iluuu1994 iluuu1994 force-pushed the dynamic-class-const-fetch branch from 5c4394d to 355b515 Compare January 12, 2023 12:19
@iluuu1994 iluuu1994 marked this pull request as ready for review January 12, 2023 13:03
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.

5 participants