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
Le 12 mai 2023 à 19:29, Lydia de Jongh flexjoly@gmail.com a écrit :
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::nameA 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::nameinside scope:
static::$normalProperty::name
self::$normalProperty::name // I do not know if 'self::' adds anything for
this purpose, except for private properties/methods maybeinside class/object:
$this->normalProperty::name
$this->normalMethod::name
$this::$staticProperty::name
I hope you like the idea! Greetz, Lydia
Hi,
That looks like the nameof
operator proposed a few days ago?
https://externals.io/message/120173
https://externals.io/message/120173
—Claude