Last active
November 30, 2023 12:04
-
-
Save makomweb/7d1090984a99bbc4cc83b3dc2df74223 to your computer and use it in GitHub Desktop.
Reflecting a PHP class and it's attributes (traverse properties and attributes)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Tests\Unit\Playground; | |
use Attribute; | |
use PHPUnit\Framework\TestCase; | |
use ReflectionAttribute; | |
use ReflectionClass; | |
use ReflectionProperty; | |
class MyTest extends TestCase | |
{ | |
public function testClass(): void | |
{ | |
$reflection = new ReflectionClass(Thing::class); | |
$data = self::getData($reflection); | |
self::assertIsArray($data); | |
} | |
public function testObject(): void | |
{ | |
$reflection = new ReflectionClass(new Thing(new Bam())); | |
$data = self::getData($reflection); | |
self::assertIsArray($data); | |
} | |
private static function getData(ReflectionClass $reflection): array | |
{ | |
return [ | |
'attributes' => self::traverseAttributes($reflection->getAttributes()), | |
'properties' => array_map( | |
static fn(ReflectionProperty $p) => [ | |
'name' => $p->getName(), | |
'type' => $p->getType()->getName(), | |
'attributes' => self::traverseAttributes($p->getAttributes()) | |
], | |
$reflection->getProperties() | |
), | |
]; | |
} | |
private static function traverseAttributes(array $attributes): array | |
{ | |
return array_map( | |
static fn (ReflectionAttribute $a) => [ | |
'name' => $a->getName(), | |
'arguments' => $a->getArguments(), | |
'target' => $a->getTarget(), | |
'new_instance' => $a->newInstance(), | |
], | |
$attributes | |
); | |
} | |
} | |
#[Attribute] | |
class AttachedInteger | |
{ | |
public int $value; | |
public function __construct(int $value) | |
{ | |
$this->value = $value; | |
} | |
} | |
#[Attribute] | |
class AttachedString | |
{ | |
public string $value; | |
public function __construct(string $value) | |
{ | |
$this->value = $value; | |
} | |
} | |
#[AttachedString(value: 'this is my baam!')] | |
class Bam | |
{ | |
#[AttachedString(value: 'this is my noise!')] | |
public string $noise; | |
} | |
#[AttachedInteger(value: 1234)] | |
class Thing | |
{ | |
#[AttachedString(value: 'foobar')] | |
public string $name; | |
public Bam $bam; | |
public function __construct(Bam $bam) | |
{ | |
$this->bam = $bam; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment