sebastian/object-reflector
sebastian/object-reflector lets you reflect an object's properties, including inherited, private, and protected ones. Install it via Composer to inspect and access object state that PHP's default reflection utilities don't easily expose.
Architecture fit
final, dependency-free utility that wraps PHP's native reflection to return a flat name => value map of all properties, including inherited private/protected ones (inherited members are keyed as ParentClass::property).ReflectionClass is the ergonomics: one call, no visibility-filtering loop, no manual parent-chain traversal.sebastian/object-enumerator → object-reflector). "Adoption" therefore means sanctioning direct use of a package our test toolchain already pins, not adding a new supply-chain node.dump()/dd() (Symfony VarDumper) already renders private properties. The real gap this fills is programmatic assertions and custom debug output, not human-readable dumps.Integration feasibility
composer require --dev, PSR-4 autoload, no PHP extensions required.require-dev constraint can conflict with PHPUnit's pin and block a PHP downgrade or a PHPUnit major bump. The lower-risk play is to consume it transitively and code against our own wrapper.Technical risk
readonly (readable, not writable), static properties, closures/resources, and cyclic object graphs. Key format (Parent::prop) silently breaks naive string matching in assertions.Dependents: 0 contradicts documented use inside PHPUnit, and a Last release: 2026-08-13 date is not credible as-is. Treat both as telemetry defects and confirm against Packagist before any decision. 6.2k stars on a ~40-line utility is a popularity proxy for the maintainer and the PHPUnit ecosystem, not evidence of scope.Key questions
ReflectionClass plus a ~15-line helper cannot serve? If no, the correct decision is "do not adopt."require-dev pin (contract clarity, conflict risk) or rely on the transitive install (zero cost, no contract)?tests/ — PHPStan rule, PHPCS sniff, Pest architecture expectation, or code review only?Stack fit
dd()/dump().app/ outside Testing/ namespaces.Migration path
composer show sebastian/object-reflector — confirm it is already present and at which version via PHPUnit. Count existing hand-rolled ReflectionClass/ReflectionProperty usage in tests/.PropertyInspector built on native reflection. If that meets 90% of cases, adopt nothing.App\Testing\Support\ObjectInspector exposing get($object, string $property), has(), all(), with the Parent::prop convention normalized and uninitialized properties handled explicitly. Application tests depend on our interface, never on SebastianBergmann\ObjectReflector directly. This is the single most important step — it makes the third-party dependency replaceable and gives us one place to add sanitization of closures/resources.Compatibility
require-dev line if we need a contractual guarantee of availability.--prefer-lowest CI job so constraint drift surfaces before a release, not after.Sequencing
Maintenance
Support
Scaling
Failure modes
composer update, blocking the platform upgrade. Highest-probability failure; owned by the upgrade runbook.Parent::prop key collisions and uninitialized typed properties producing confusing false failures. Mitigated by wrapper accessors.Ramp-up
tests/, reduction in hand-written reflection code, and no added time to the PHP upgrade cycle. If the upgrade cost shows up in the next platform bump, that is the trigger to revert to native reflection via the wrapper.How can I help you explore Laravel packages today?