bentools/reflection-plus

Another improved code reflection API

1.0 2025-05-20 13:25 UTC

This package is auto-updated.

Last update: 2025-05-20 13:26:06 UTC


README

Latest Version on Packagist Total Downloads Tests Coverage

ReflectionPlus is a lightweight wrapper around PHP's native Reflection API that makes working with reflection simpler, more efficient, and more intuitive.

Features

  • Cache-enabled reflection: Automatically caches reflection instances for better performance
  • Simplified API: Clean, intuitive methods for accessing reflection information
  • Type compatibility analysis: Easily determine if classes are compatible with property types
  • Support for complex type systems: Full handling of union types, intersection types, and named types
  • Performance optimized: Uses WeakMap and other optimizations to minimize memory usage

Why?

ReflectionPlus automatically caches:

  • ReflectionClass instances
  • ReflectionProperty instances
  • ReflectionMethod instances
  • Type compatibility results

This makes it highly efficient for repeated usage, especially in loops or recursive operations.

Use Cases

ReflectionPlus is particularly useful for:

  • Factory implementations that need to determine which concrete classes to instantiate
  • Dependency injection containers
  • Type-based serialization/deserialization systems
  • Code generators that need to inspect class structures
  • Data mappers that need to determine type compatibility
  • Framework development where reflection is frequently used

Requirements

  • PHP 8.4 or higher

Usage

Basic Reflection Operations

Get a reflection class:

use BenTools\ReflectionPlus\Reflection;

// From a class name
$reflectionClass = Reflection::class(MyClass::class);

// Or from an object
$object = new MyClass();
$reflectionClass = Reflection::class($object);

Get a reflection property:

// From a class name
$reflectionProperty = Reflection::property(MyClass::class, 'someProperty');

// Or from an object
$object = new MyClass();
$reflectionProperty = Reflection::property($object, 'someProperty');

Get a reflection method:

// From a class name
$reflectionMethod = Reflection::method(MyClass::class, 'someMethod');

// Or from an object
$object = new MyClass();
$reflectionMethod = Reflection::method($object, 'someMethod');

Working with Property Types

Get all instantiable class types that can be set to a property:

// Get a reflection property
$reflectionProperty = Reflection::property($myClass, 'myProperty');

// Get all class types that can be set to this property
$classTypes = Reflection::getSettableClassTypes($reflectionProperty);

// Returns an array of fully qualified class names
// that are compatible with the property type
// and are instantiable (no interfaces or abstract classes)

Check if a class is compatible with a property:

$reflectionProperty = Reflection::property($myClass, 'myProperty');

// Check if a particular class is compatible
$isCompatible = Reflection::isPropertyCompatible($reflectionProperty, SomeClass::class);

// Returns true if SomeClass can be assigned to the property

Find the best class for a property from a list of candidates:

$reflectionProperty = Reflection::property($myClass, 'myProperty');
$classNames = [ClassA::class, ClassB::class, ClassC::class];

// Find the first compatible class in the array
$bestClass = Reflection::getBestClassForProperty($reflectionProperty, $classNames);

// Returns the class name of the first compatible class
// or throws InvalidArgumentException if none are compatible

Type Compatibility

Check type compatibility with different type systems:

$reflectionProperty = Reflection::property($myClass, 'myProperty');
$type = $reflectionProperty->getType();

// Check if a class is compatible with this type
$isCompatible = Reflection::isTypeCompatible($type, SomeClass::class);

// Works with:
// - ReflectionNamedType (standard class or primitive types)
// - ReflectionUnionType (Type1|Type2)
// - ReflectionIntersectionType (Type1&Type2)

Advanced Use Cases

Working with Union Types

// For a property like: public ClassA|ClassB $property;

$reflectionProperty = Reflection::property($class, 'property');
$classTypes = Reflection::getSettableClassTypes($reflectionProperty);

// $classTypes will contain [ClassA::class, ClassB::class] if both are instantiable

Working with Intersection Types

// For a property like: public ClassA&InterfaceB $property;

$reflectionProperty = Reflection::property($class, 'property');

// You can check if a specific class meets all requirements
$isCompatible = Reflection::isPropertyCompatible($reflectionProperty, SomeClass::class);

// Returns true if SomeClass extends/is ClassA AND implements InterfaceB

Installation

You can install the package via composer:

composer require bentools/reflection-plus

License

MIT.