Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Reflecta Laravel Package

veewee/reflecta

Reflecta is a PHP library for fast, reflection-based class inspection, letting you read properties, methods, and attributes without instantiating objects. Useful for building analyzers, mappers, and framework tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with Composer: composer require veewee/reflecta. The current release line is 1.2.x (1.2.0 added property_is_initialized), so pin ^1.2 if you intend to use the new helper. Confirm PHP 8+ and that your autoloader is configured. Start with src/ and tests/ — the test suite is the most reliable documentation.
  • Look for the main entry point — likely a factory or wrapper around ReflectionClass — and use the tests as executable documentation. Note that 1.2.0's small, additive changelog (one PR, no BC breaks advertised) suggests the API is still settling; read the diff of any version bump before upgrading.
  • A likely minimal flow is: create a reflector for a class, then navigate to methods, properties, parameters, and attributes. The exact names depend on the package API, so rely on IDE autocomplete and the test suite. Illustratively:
$class = Reflect::class(MyService::class); // illustrative; check actual API

$routeAttributes = $class->attributes(Route::class);
$publicMethods   = $class->methods()->public();

foreach ($publicMethods as $method) {
    foreach ($method->parameters() as $parameter) {
        // inspect parameter type, attributes, defaults
    }
}
  • Best first use case: an attribute-driven metadata scanner. Point it at a directory of classes, reflect each class, read custom attributes such as #[Route], #[Validate], or #[Serialize], and register the results in a container, router, validator, or schema generator. This plays directly to Reflecta's strengths: attribute inspection, fluent navigation, and type-safe wrappers.
  • A good second use case: a CLI/codegen command that lists public methods and parameter types for scaffolding, documentation, or OpenAPI generation.
  • A good third use case, now that 1.2.0 exposes property_is_initialized: a hydration/serialization inspector that reports which typed properties on a given object actually hold a value — useful for DTO mappers, snapshot diffs, and "lazy relation loaded?" checks.

Implementation Patterns

  • Use Reflecta for ergonomics, not as a total replacement for native reflection. Keep native ReflectionClass/ReflectionMethod available for edge cases the wrapper does not cover. If Reflecta becomes central, hide it behind a small internal adapter so you can swap or upgrade it later.
  • Reflect once, cache aggressively. Reflection is not free. In frameworks and CLI tools, scan classes during a build step or cache warm-up, produce plain metadata DTOs, and store them in an array, file cache, APCu, or PSR-6 cache. Do not re-reflect the same classes on every request.
  • Attribute scanning pattern. Filter attributes by class, build a registry map such as class => metadata, and defer newInstance() calls until you actually need the attribute object. This is the main day-to-day pattern for routing, validation, serialization, DI compilation, and documentation generation.
  • Guarded property reads (new in 1.2.0). Before calling getValue() on a typed property, check initialization via the new helper (native equivalent: ReflectionProperty::isInitialized()); naming in the wrapper may be isInitialized() or similar — confirm in tests/. Wrap this in a small helper so call sites read intentionally:
foreach ($reflector->properties() as $property) {
    $value = $property->property_is_initialized($instance) // illustrative name
        ? $property->value($instance)
        : null; // or a domain-specific "unset" sentinel
}
  • Distinguish "uninitialized" from "null". When mapping to your own DTOs, decide up front whether an uninitialized property becomes null, an omitted key, or a dedicated Uninitialized marker. Serializers that conflate the two produce subtly wrong payloads (e.g. PATCH semantics).
  • Fluent navigation for analyzers. Chain class → methods → parameters → types to build linters, schema generators, test helpers, or documentation tools. Keep traversal logic in a dedicated service class so reflection code does not leak across the codebase.
  • Handle PHP 8 types through the package wrappers. Use Reflecta's type objects for union and intersection types instead of parsing native reflection strings yourself. When mapping to your own domain model, explicitly decide how to represent unions, intersections, self, static, never, and enum types.
  • Put reflection-heavy work in build-time commands. Examples: an Artisan command that scans attributes and writes a cache file, a CI step that validates route metadata, or a Composer script that generates an OpenAPI schema. This keeps runtime request handling fast and makes reflection failures visible during builds.
  • Prefer composition over forking. If the package exposes extension points, add domain-specific helpers around it — e.g. findRouteAttributes(), publicMethodNames(), constructorParameterTypes() — rather than modifying package internals. A one-PR release like 1.2.0 is a good reminder that upstream moves on its own schedule.
  • Test with fixture classes. Create fixtures containing attributes, union types, intersection types, private/protected members, readonly properties, enums, internal classes, and — for 1.2.0 — classes with a mix of initialized and never-initialized typed properties. Assert on Reflecta's output, not just native reflection. This documents expected behavior and catches regressions when upgrading.

Gotchas and Tips

  • Maturity risk. With a small star count and a thin changelog, documentation and API stability may be limited. Pin a version in composer.json, read the tests before relying on a method, and wrap the package behind an internal interface if it becomes central to your application.
  • Uninitialized typed properties throw on read. Accessing getValue() on a typed property that was never assigned raises Error: Typed property ... must not be accessed before initialization. In 1.2.0 you can now guard this with property_is_initialized; before that you had to catch the error or pre-check with native reflection. Always guard, never try/catch (\Error) around a loop.
  • The initialization check needs an instance. Native isInitialized() takes the object under inspection; static properties behave differently (no instance required / instance ignored). Confirm how the wrapper models this and test on the PHP versions you deploy — semantics have shifted across PHP 8.x minors.
  • isInitialized() is not isset(). A property explicitly set to null is initialized. If your logic uses isset() today, switching to the new helper can change behavior for nullable properties. Decide intentionally.
  • Attribute instantiation can have side effects. Calling newInstance() on an attribute runs its constructor. Inspect metadata first and instantiate only when safe. Attribute classes must be autoloadable; a missing attribute class can throw during scanning.
  • Reflection throws on missing symbols. Reflecting a non-existent class, method, property, or parameter throws. In bulk scanners, catch per-class failures and collect/log them rather than letting one bad class abort the entire scan.
  • Performance is still reflection performance. Expect overhead compared with direct code access. Avoid reflection inside hot loops. In development, cache by class name plus file mtime; in production, use a build-time cache or precomputed metadata.
  • PHP type edge cases are easy to miss. Union/intersection types, never, static, self, parent, enums, readonly properties, and internal classes can behave differently across PHP versions. Test on the PHP versions you deploy and compare Reflecta's normalized output with native getType() when debugging.
  • Visibility, static, and readonly semantics still matter. A fluent API may expose non-public members, but that does not mean you should use them. Filter intentionally and respect readonly/static rules when reading or setting property values — readonly + uninitialized is a combination worth a dedicated fixture.
  • Do not casually mix native and wrapper objects. Passing a native ReflectionClass where a Reflecta wrapper is expected, or vice versa, will produce type errors. Keep a clear boundary: native reflection at the edge, Reflecta wrappers in your analysis services.
  • Debug by comparing with native reflection. When output looks wrong, dump Reflecta's result next to native ReflectionClass, ReflectionMethod, getAttributes(), getParameters(), getType(), and isInitialized() for the same target. This quickly isolates whether the issue is your traversal or the wrapper.
  • Configuration may be minimal. Look for a factory or static entry point rather than a large config file. If caching or extension hooks exist, configure them once at bootstrap, not per reflector instance.
  • Adopt incrementally. Start with a non-critical tool such as an attribute lister or documentation generator. Prove the API, performance, and upgrade story before using Reflecta in request handling, DI compilation, or other critical paths.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource