Skip to content

Commit 36cf219

Browse files
committed
readme + examples
1 parent 5f22b86 commit 36cf219

File tree

5 files changed

+210
-0
lines changed

5 files changed

+210
-0
lines changed

README.MD

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,108 @@ Fully tested, phpstan level 9 compliant.
55
### Installation:
66

77
> composer require zrnik/php-attribtue-reflection
8+
9+
### Usage & Reason why this library exists.
10+
11+
I use attributes on enum cases a lot. It's a good way to put
12+
metadata on the cases. Let's look at this example:
13+
14+
```php
15+
<?php
16+
17+
namespace Zrnik\Example;
18+
19+
use ReflectionClass;
20+
use RuntimeException;
21+
22+
enum CaseToSolve
23+
{
24+
#[AttributeToFind('AnyParameter')]
25+
case FirstCase;
26+
27+
#[AttributeToFind('DifferentParameter')]
28+
#[AnotherAttribute('WhateverIsHere')]
29+
case SecondCase;
30+
31+
case ThirdCase;
32+
33+
public function getParameter(): string
34+
{
35+
$reflection = new ReflectionClass(self::class);
36+
$caseReflection = $reflection->getReflectionConstant($this->name);
37+
38+
if($caseReflection === false) {
39+
throw new RuntimeException('case not found');
40+
}
41+
42+
foreach ($caseReflection->getAttributes() as $reflectionAttribute) {
43+
if ($reflectionAttribute->getName() === AttributeToFind::class) {
44+
/** @var AttributeToFind $attributeToFindInstance */
45+
$attributeToFindInstance = $reflectionAttribute->newInstance();
46+
return $attributeToFindInstance->customValue;
47+
}
48+
}
49+
50+
throw new RuntimeException(
51+
sprintf(
52+
'attribute "%s" not found on "%s"!',
53+
AttributeToFind::class,
54+
$this->name
55+
)
56+
);
57+
}
58+
}
59+
```
60+
61+
You probably know what its meant to do:
62+
63+
```php
64+
CaseToSolve::FirstCase->getParameter(); // 'AnyParameter'
65+
CaseToSolve::SecondCase->getParameter(); // 'DifferentParameter'
66+
CaseToSolve::ThirdCase->getParameter(); // RuntimeException
67+
```
68+
69+
This is what this library does, it just returns the attribute value.
70+
Now let's see how this code would work with this library:
71+
72+
```php
73+
<?php
74+
75+
namespace Zrnik\Example;
76+
77+
use Zrnik\AttributeReflection\AttributeReflection;
78+
use Zrnik\AttributeReflection\AttributeReflectionException;
79+
80+
enum SolvedCase
81+
{
82+
#[AttributeToFind('AnyParameter')]
83+
case FirstCase;
84+
85+
#[AttributeToFind('DifferentParameter')]
86+
#[AnotherAttribute('WhateverIsHere')]
87+
case SecondCase;
88+
89+
case ThirdCase;
90+
91+
/**
92+
* @return string
93+
* @throws AttributeReflectionException
94+
*/
95+
public function getParameter(): string
96+
{
97+
return AttributeReflection::getClassConstantAttribute(
98+
AttributeToFind::class,
99+
self::class,
100+
$this->name
101+
)->customValue;
102+
}
103+
}
104+
```
105+
106+
The `getParameter` method is much better, isn't it? Works the same:
107+
108+
```php
109+
SolvedCase::FirstCase->getParameter(); // 'AnyParameter'
110+
SolvedCase::SecondCase->getParameter(); // 'DifferentParameter'
111+
SolvedCase::ThirdCase->getParameter(); // \Zrnik\AttributeReflection\AttributeReflectionException
112+
```

example/AnotherAttribute.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Zrnik\Example;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
8+
class AnotherAttribute
9+
{
10+
public function __construct(
11+
public readonly string $customValue
12+
)
13+
{
14+
}
15+
}

example/AttributeToFind.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Zrnik\Example;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
8+
class AttributeToFind
9+
{
10+
public function __construct(
11+
public readonly string $customValue
12+
)
13+
{
14+
}
15+
}

example/CaseToSolve.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Zrnik\Example;
4+
5+
use ReflectionClass;
6+
use RuntimeException;
7+
8+
enum CaseToSolve
9+
{
10+
#[AttributeToFind('AnyParameter')]
11+
case FirstCase;
12+
13+
#[AttributeToFind('DifferentParameter')]
14+
#[AnotherAttribute('WhateverIsHere')]
15+
case SecondCase;
16+
17+
case ThirdCase;
18+
19+
public function getParameter(): string
20+
{
21+
$reflection = new ReflectionClass(self::class);
22+
$caseReflection = $reflection->getReflectionConstant($this->name);
23+
24+
if($caseReflection === false) {
25+
throw new RuntimeException('case not found');
26+
}
27+
28+
foreach ($caseReflection->getAttributes() as $reflectionAttribute) {
29+
if ($reflectionAttribute->getName() === AttributeToFind::class) {
30+
/** @var AttributeToFind $attributeToFindInstance */
31+
$attributeToFindInstance = $reflectionAttribute->newInstance();
32+
return $attributeToFindInstance->customValue;
33+
}
34+
}
35+
36+
throw new RuntimeException(
37+
sprintf(
38+
'attribute "%s" not found on "%s"!',
39+
AttributeToFind::class,
40+
$this->name
41+
)
42+
);
43+
}
44+
}

example/SolvedCase.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Zrnik\Example;
4+
5+
use Zrnik\AttributeReflection\AttributeReflection;
6+
use Zrnik\AttributeReflection\AttributeReflectionException;
7+
8+
enum SolvedCase
9+
{
10+
#[AttributeToFind('AnyParameter')]
11+
case FirstCase;
12+
13+
#[AttributeToFind('DifferentParameter')]
14+
#[AnotherAttribute('WhateverIsHere')]
15+
case SecondCase;
16+
17+
case ThirdCase;
18+
19+
/**
20+
* @return string
21+
* @throws AttributeReflectionException
22+
*/
23+
public function getParameter(): string
24+
{
25+
return AttributeReflection::getClassConstantAttribute(
26+
AttributeToFind::class,
27+
self::class,
28+
$this->name
29+
)->customValue;
30+
}
31+
}

0 commit comments

Comments
 (0)