Hi,

Lately I made a small object initializer/builder with php Attributes.

'Directly' accessing properties and methods of the class as a parameter in
an Attribute is not really possible.
You can do that for a class with: \path\to\MyClass::class, but for
properties or methods you have to use strings, without recognition in
editors.

It would be so nice if more items in php could be accessed with a magic
constant as you can do with ::class.
With magic constant an editor could recognize it and it limits typos etc.
and it provides the developer with a list of the properties/methods in
scope.

At the moment I implemented a kind of workaround by providing simple
classes with the property names in class constants.
Or add an extra property to a class with a property name that can be used
in an attribute.

I will try to explain with examples of my code.

abstract class SaveFactoryAbstract {
use ObjectBuilderTrait;

#[ResetValue]
protected bool $isSaved = false;

#[InitObject] // tells the builder to initialize this property with the
latest specs provided by (other) attributes
#[ResetObject]
protected ?SaveInterface $oSave = null;

public function __construct(){
$this->buildMe(); // provided by the trait
}
}


This is straightforward. Until you extend this class and want to set the
class for $oSave.
The other developer does not know which properties he can declare with an
attribute....

#[UseClass('oSave', ImageSave::class)]
#[ResetValue('isSaved', default: true)]
class ImageSaveFactory extends SaveFactoryAbstract { }


As workaround I make classes like:

class oop { // lower character on purpose, for this is not a normal class

final public const isSaved = 'isSaved';

final public const Save = 'oSave';
final private function __construct() {}
}

So the extending class can be:
This is recognized by the editor and gives the developer some clues.
#[UseClass(oop::Save, ImageSave::class)]
#[ResetValue(oop::isSaved, default: true)]
class ImageSaveFactory extends SaveFactoryAbstract { }

But this is really annoying.....


It would be much better if we could do something like:
#[UseClass(static::$oSave::name, ImageSave::class)] // 'static::' can be
used, since the attribute belong to the scope of this class
#[ResetValue(static::$isSaved::name, default: true)]
class ImageSaveFactory extends SaveFactoryAbstract {
}

This could also extend possibilities with/for variable variables....
Like:
$this->myProp::name
myClass::$staticProp::name


A potential difficulty is: how to access normal properties/methods....
Maybe just as if they are static?
Like parent::normalMethod() is working....
A normal property or method cannot have the same name as its static partner
(sadly) so internally I hope it is not a problem.

outside scope:
myClass::$staticProperty::name
myClass::$normalProperty::name
myClass::normalMethod::name

inside scope:
static::$normalProperty::name
self::$normalProperty::name // I do not know if 'self::' adds anything for
this purpose, except for private properties/methods maybe

inside class/object:
$this->normalProperty::name
$this->normalMethod::name
$this::$staticProperty::name
I hope you like the idea! Greetz, Lydia

Reply via email to