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
This library provides attributes for extending the PHP language (e.g. adding `package` visibility).
13
+
This library provides [attributes](https://www.php.net/manual/en/language.attributes.overview.php) that are used by static analysers to enforce new language features.
15
14
The intention, at least initially, is that these extra language features are enforced by static analysis tools (such as Psalm, PHPStan and, ideally, PhpStorm) and NOT at runtime.
16
15
17
16
**Language feature added:**
@@ -51,7 +50,7 @@ Use one of these:
51
50
52
51
### PHPStan
53
52
54
-
To use PHPStan to enforce package level visibility add [this extension](https://github.com/DaveLiddament/phpstan-php-language-extensions).
53
+
If you're using PHPStan then use [this extension](https://github.com/DaveLiddament/phpstan-php-language-extensions) to enforce the rules.
By default, only constructor arguments are checked. Most DI should be done via constructor injection.
332
+
By default, only constructor arguments are checked. Most DI should be done via constructor injection.
334
333
335
334
In cases where dependencies are injected by methods that aren't constructors, the method must be marked with a `#[CheckInjectableVersion]`:
336
335
@@ -353,6 +352,70 @@ class MyService
353
352
354
353
355
354
355
+
356
+
## Sealed
357
+
358
+
This is inspired by the rejected [sealed classes RFC](https://wiki.php.net/rfc/sealed_classes)
359
+
360
+
The `#[Sealed]` attribute takes a list of classes or interfaces that can extend/implement the class/interface.
361
+
362
+
E.g.
363
+
364
+
```php
365
+
366
+
#[Sealed([Success::class, Failure::class])]
367
+
abstract class Result {} // Result can only be extended by Success or Failure
368
+
369
+
// OK
370
+
class Success extends Result {}
371
+
372
+
// OK
373
+
class Failure extends Result {}
374
+
375
+
// ERROR AnotherClass is not allowed to extend Result
376
+
class AnotherClass extends Result {}
377
+
```
378
+
379
+
380
+
## TestTag
381
+
382
+
The `#[TestTag]` attribute is an idea borrowed from hardware testing. Methods marked with this attribute are only available to test code.
383
+
384
+
E.g.
385
+
386
+
```php
387
+
class Person {
388
+
389
+
#[TestTag]
390
+
public function setId(int $id)
391
+
{
392
+
$this->id = $id;
393
+
}
394
+
}
395
+
396
+
397
+
function updatePersonId(Person $person): void
398
+
{
399
+
$person->setId(10); // ERROR - not test code.
400
+
}
401
+
402
+
403
+
class PersonTest
404
+
{
405
+
public function setup(): void
406
+
{
407
+
$person = new Person();
408
+
$person->setId(10); // OK - This is test code.
409
+
}
410
+
}
411
+
```
412
+
413
+
NOTES:
414
+
- Methods with the`#[TestTag]` MUST have public visibility.
415
+
- For determining what is "test code" see the relevant plugin. E.g. the [PHPStan extension](https://github.com/DaveLiddament/phpstan-php-language-extensions) can be setup to either:
416
+
- Assume all classes that end `Test` is test code. See [className config option](https://github.com/DaveLiddament/phpstan-php-language-extensions#exclude-checks-on-class-names-ending-with-test).
417
+
- Assume all classes within a given namespace is test code. See [namespace config option](https://github.com/DaveLiddament/phpstan-php-language-extensions#exclude-checks-based-on-test-namespace).
418
+
356
419
## Further examples
357
420
358
421
More detailed examples of how to use attributes is found in [examples](examples/).
0 commit comments