Schrank, German
@Schrank@phpc.social avatar

Hey people! Is there a way to implement an abstract constant? I have an abstract class which implements some stuff for my value objects and a constant IDENTIFIER I would like to enforce to be overwritten by the child classes.

It looks like there was a way in the past by using circular references: https://itecnote.com/tecnote/php-abstract-constants-in-php-force-a-child-class-to-define-a-constant/ but this doesn't work anymore.

heiglandreas,
@heiglandreas@phpc.social avatar

@Schrank A value-object that extends an abstract class?

That alone sounds ... interesting!

Schrank,
@Schrank@phpc.social avatar

@heiglandreas I’m happy to show you!

Girgias,
@Girgias@phpc.social avatar

@Schrank Have the constant in the abstract parent class be defined as follows:

const CONST_NAME = self::CONST_NAME;  

And if the child class tries to use it without redefining it, you get an Error at runtime.

https://3v4l.org/TURXT

Schrank,
@Schrank@phpc.social avatar

@Girgias this doesn’t work for me, good to know it should! Will investigate 🤔

Schrank,
@Schrank@phpc.social avatar

@Girgias @Crell @robchett @Sdfendor Thank you all for your input!

My code works as expected until I do:

protected const IDENTIFIER = Enum::CASE->value;

And then the error is thrown:
Uncaught Error: Cannot declare self-referencing constant self::IDENTIFIER

Which is totally misleading :D

I think this becomes a blogpost, not sure what about exactly yet 🙈 And I need to check wether I can set a constant with a enum value :D

Schrank,
@Schrank@phpc.social avatar

@Girgias @Crell @robchett @Sdfendor Case closed.

After refactoring (yesterday) all the constants to an Enum, there is no need for the constans anymore 🤦‍♂️ . So now the method itself is abstract and all is fine :D

heiglandreas,
@heiglandreas@phpc.social avatar

@Schrank TBH: Constants are never "abstract". They stand outside the inheritance logic.

But you know that. We had the duscussion 😁

You are probably looming for a method that returns a certain value.

Schrank,
@Schrank@phpc.social avatar

@heiglandreas Can't remember. I'm happy to do mistakes twice.

heiglandreas,
@heiglandreas@phpc.social avatar

@Schrank Then I need to find the time to write about it on the weekend.

In essence: IMO constants can be namespaced via classes but they live outside the inheritance. Constants are not overwritten but newly defined.

The fact that PHP allows to access constants from parent classes that are undefined in the current class via self:: is broken design.

SenseException,
@SenseException@phpc.social avatar

@heiglandreas @Schrank Once you experienced it with static:: you'll know how broken it is.

shochdoerfer,
@shochdoerfer@phpc.social avatar

@heiglandreas @Schrank I don't get the discussion. A constant is constant. If you want to change the value in a child class, it's not a constant anymore :P

Maybe using readonly properties would solve the use case?

Schrank,
@Schrank@phpc.social avatar

@shochdoerfer @heiglandreas it is an abstract method now, returning the string value of an enumerator 🙃

pierstoval,
@pierstoval@mastodon.social avatar

@Schrank @shochdoerfer @heiglandreas static abstract method is definitely the way to go 👍 with enum, even better ! 🎉

heiglandreas,
@heiglandreas@phpc.social avatar

@shochdoerfer One can't change the value in a child-class. It's a different constant.

parent::CONSTANT is something else than self::CONSTANT.

Sadly PHP allows to call self::CONST and get parent::CONST when the constant wasn't defined in self-context.

Which causes people to think constants are part of the inheritance contract.

But IME relying on this inheritance always proved to be a code-smell
/cc @Schrank

Crell,
@Crell@phpc.social avatar

@Schrank I don't think this can be done at the language level. It sounds like you want an interface with method. A static public readonly property would only work if it's set from the constructor, since they cannot have default values.

Alternatively, maybe an attribute? Depends what you're doing with it.

Sdfendor,
@Sdfendor@chaos.social avatar

@Crell A property declared readonly can be initialized from anywhere inside the class/the scope it was declared in, not necessarily the constructor.My idea was to have an abstract method doing it because of that.

Crell,
@Crell@phpc.social avatar

@Sdfendor Sure, yes, it can be set from anywhere private. Just not have a default value.

(Fun fact: Both major SA tools object to writing to readonly anywhere except the constructor. I've opened issues with both to say this is wrong, and they've both rejected it. This is problematic.)

robchett,

@Schrank any reason it needs to be a constant and not just a function that returns the identifier?

  • All
  • Subscribed
  • Moderated
  • Favorites
  • php
  • DreamBathrooms
  • magazineikmin
  • everett
  • InstantRegret
  • rosin
  • Youngstown
  • slotface
  • love
  • khanakhh
  • kavyap
  • tacticalgear
  • GTA5RPClips
  • thenastyranch
  • modclub
  • megavids
  • mdbf
  • normalnudes
  • Durango
  • ethstaker
  • osvaldo12
  • cubers
  • ngwrru68w68
  • tester
  • anitta
  • cisconetworking
  • Leos
  • provamag3
  • JUstTest
  • All magazines