You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added support for customizing accessor method names using #[Format] attribute.
* Added support for customizing accessor method names using #[Format] attribute.
* Cleaned up Accessible trait and moved most of the code into ClassConf.
* Added missing copyright banners.
* Add @api tags to appropriate classes.
* Update documentation.
Copy file name to clipboardExpand all lines: README.md
+65-7Lines changed: 65 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ Current library can create automatic accessors (e.g. _getters_ and _setters_) fo
8
8
* direct assignment syntax:
9
9
* `$value = $foo->property`
10
10
* `$foo->property = 'value'`
11
-
* method syntax:
11
+
* method syntax (**customizable format**):
12
12
*`$value = $foo->get('property')`
13
13
*`$value = $foo->property()`
14
14
*`$foo->property('value')`
@@ -20,14 +20,14 @@ Current library can create automatic accessors (e.g. _getters_ and _setters_) fo
20
20
* Accessors can be configured _per_ property or for all class at once.
21
21
* Inheritance and override support. E.g. set default behaviour for whole class and make exceptions for specific properties.
22
22
* No variables, functions nor methods will be polluted into user classes or global namespace (except necessary `__get()`/`__set()`/`__isset()`/`__unset()`/`__call()`).
23
-
*[_PHPDoc_](https://docs.phpdoc.org/3.0/guide/references/phpdoc/tags/property.html) tags `@property`, `@property-read` and `@property-write`are also supported and can be used instead of Attributes on basic cases.
23
+
*[_PHPDoc_](https://docs.phpdoc.org/3.0/guide/references/phpdoc/tags/property.html) tags `@property`, `@property-read` and `@property-write` can be used instead of basic Attributes.
24
24
*_Weak_**immutability** support backed by _wither_ methods.
This has boilerplate code just to make 3 properties readable. In case there are tens of properties things could get quite tedious.
73
74
74
75
By using `Accessible` trait this class can be rewritten:
@@ -284,6 +285,7 @@ Notes:
284
285
* Immutable properties can be still changed inside the owner object.
285
286
* To prevent ambiguity, immutable properties must be changed using method `with` instead of `set`. Using `set` for immutable properties results in exception and vice versa.
286
287
* Unsetting immutable properties is not possible and results in exception.
288
+
* When `#[Immutable]` is defined on a class then it must be done on top of hierarchy and not in somewhere between. This is to enforce consistency throughout all of the inheritance. This effectively prohibits situations when there's mutable parent but in derived class the same inherited properties can be turned suddenly immutable.
287
289
288
290
### Mutator
289
291
@@ -398,11 +400,11 @@ unset($a->bar); // Results in Exception
398
400
```
399
401
400
402
Notes:
401
-
* since `Unset` is reserved word, `Delete` was chosen for attribute name instead.
403
+
* since `Unset` is reserved word, `Delete`is used as Attribute name instead.
402
404
403
405
### Configuration inheritance
404
406
405
-
Inheritance is quite straightforward. Attributes in parent class are inherited by children and can be overwritten (except for `Immutable`):
407
+
Inheritance is quite straightforward. Attributes in parent class are inherited by children and can be overwritten (except `#[Immutable]` and `#[Format]`):
echo $a->Foo; // Results in Exception because property "Foo" doesn't exist
465
467
```
466
468
469
+
### Customizing format of accessor method names
470
+
Usually the names for accessor methods are just straightforward _camel-case_'d names like `get<property>`, `set<property>` and so on. But if necessary, it can be customized.
471
+
472
+
Customization can be achieved using `#[Format(class-string<FormatContract>)]` attribute with first parameter specifying class name. This class is responsible for parsing out accessor methods names.
473
+
474
+
Following example turns _camel-case_ methods into _snake-case_:
475
+
476
+
```php
477
+
use margusk\Accessors\Attr\{
478
+
Get, Set, Format
479
+
};
480
+
use margusk\Accessors\Format\Method;
481
+
use margusk\Accessors\Format\Standard;
482
+
use margusk\Accessors\Accessible;
483
+
484
+
class SnakeCaseFmt extends Standard
485
+
{
486
+
public function matchCalled(string $method): ?Method
487
+
{
488
+
if (
489
+
preg_match(
490
+
'/^(' . implode('|', Method::TYPES) . ')_(.*)/i',
491
+
strtolower($method),
492
+
$matches
493
+
)
494
+
) {
495
+
$methodName = $matches[1];
496
+
$propertyName = $matches[2];
497
+
498
+
return new Method(
499
+
Method::TYPES[$methodName],
500
+
$propertyName
501
+
);
502
+
}
503
+
504
+
return null;
505
+
}
506
+
}
507
+
508
+
#[Get,Set,Format(SnakeCaseFmt::class)]
509
+
class A
510
+
{
511
+
use Accessible;
512
+
513
+
protected string $foo = "foo";
514
+
}
515
+
516
+
$a = new A();
517
+
echo $a->set_foo("new foo")->get_foo(); // Outputs "new foo"
518
+
echo $a->setFoo("new foo"); // Results in Exception
519
+
520
+
```
521
+
Notes:
522
+
*`#[Format(...)]` can be defined only for a class and on top of hierarchy. This is to enforce consistency throughout all of the inheritance tree. This effectively prohibits situations when there's one syntax in parent but in derived classes the syntax suddenly changes.
523
+
467
524
### IDE autocompletion
468
525
469
526
Having accessors with _magic methods_ can bring the disadvantages of losing somewhat of IDE autocompletion and make static code analyzers grope in the dark.
@@ -512,9 +569,10 @@ Since `@property[<-read>|<-write>]` tags act also in exposing properties, you ge
512
569
* if `string` type is used then it must contain regular function name or syntax `$this->someMutatorMethod` implies instance method.
513
570
* use `array` type for specifying static class method.
514
571
* and use `null` to discard any previously set mutator.
515
-
* `#[Immutable]`: turns an property or whole class immutable. Once the attribute is added, it can't be disabled later.
572
+
*`#[Immutable]`: turns an property or whole class immutable. When used on a class, then it must be defined on top of hierarchy. Once defined, it can't be disabled later.
573
+
*`#[Format(class-string<FormatContract>)]`: allows customization of accessor method names.
516
574
517
-
### Properties can be accessed with following syntaxes:
0 commit comments