extended-type-system / type-reflection
Typhoon Reflection
Installs: 1 808
Dependents: 0
Suggesters: 0
Security: 0
Stars: 10
Watchers: 2
Forks: 2
Open Issues: 5
Requires
- php: ^8.1
- extended-type-system/type: ^0.1@dev
- extended-type-system/type-stringifier: ^0.1@dev
- phpdocumentor/reflection-docblock: ^5.2
- phpdocumentor/type-resolver: ^1.3
- phpstan/phpdoc-parser: ^1.0
- phpyh/lru-memoizer: ^0.2
Requires (Dev)
- ergebnis/composer-normalize: ^2.30
- friendsofphp/php-cs-fixer: ^3.14.4
- phpunit/phpunit: ^9.6.3
- phpyh/coding-standard: ^2.0.0
- psalm/plugin-phpunit: ^0.18.4
- symfony/finder: ^6.2.5
- vimeo/psalm: ^5.7.7
README
This library is an alternative to native PHP Reflection.
It is static, cacheable, supports Psalm/PHPStan types (non-empty-string
, list<T>
, X::CONSTANT
, etc.) and can resolve templates.
Installation
composer require typhoon/reflection jetbrains/phpstorm-stubs
Installing jetbrains/phpstorm-stubs
is highly recommended.
Without stubs native PHP classes are reflected via native reflector that does not support templates.
Basic Usage
namespace My\Awesome\App; use Typhoon\Reflection\Reflector; final readonly class Article { /** * @param non-empty-list<non-empty-string> $tags */ public function __construct( private array $tags, ) {} } $reflector = Reflector::build(); $articleReflection = $reflector->reflectClass(Article::class); var_dump($articleReflection->isFinal()); // true var_dump($articleReflection->getNamespaceName()); // 'My\Awesome\App' $tagsReflection = $articleReflection->getProperty('tags'); var_dump($tagsReflection->isReadOnly()); // true var_dump($tagsReflection->getType()->getNative()); // class Typhoon\Type\ArrayType (2) { // $keyType => enum Typhoon\Type\ArrayKeyType; // $valueType => enum Typhoon\Type\MixedType; // } var_dump($tagsReflection->getType()->getPhpDoc()); // class Typhoon\Type\NonEmptyListType (1) { // $valueType => enum Typhoon\Type\NonEmptyStringType; // }
Compatibility
This library tries to replicate native reflection API as long as it is possible and makes sense. See compatibility and ReflectorCompatibilityTest for more details.
The main difference is in getType
method.
Caching
use Typhoon\Reflection\Reflector; $reflector = Reflector::build( // toggle caching (might be useful in tests) // cacheDirectory and detectChanges options have no effect when caching is disabled cache: false, // set custom cache directory // defaults to system temp location according to XDG cacheDirectory: '/path/to/cache', // optimize DX during development or performance in production detectChanges: $_ENV['mode'] !== 'prod', );
Class locators
By default, reflector uses ComposerClassLocator
if it detects composer autoloading and PhpStormStubsClassLocator
if jetbrains/phpstorm-stubs
is installed.
You can implement your own locators and pass them to build
method:
use Typhoon\Reflection\Reflector; use Typhoon\Reflection\ClassLocator; final class CustomClassLocator implements ClassLocator { // ... } $reflector = Reflector::build( classLocator: new ClassLocator\ClassLocatorChain([ new CustomClassLocator(), new ClassLocator\PhpStormStubsClassLocator(), new ClassLocator\ComposerClassLocator(), ]), );
TODO
- anonymous classes
- attributes
- traits
- class constants
- functions