- Can I use this package to replace manual `new` calls in Laravel controllers or services?
- Yes, this package replaces manual instantiation by building objects from arrays or scalars using constructor reflection. For example, replace `new User($request->input())` with `ClassBuilder::build(User::class, $request->all())`. It integrates well with Laravel’s dependency injection patterns but requires PHP 8.0+.
- Does this work with Laravel’s service container (e.g., binding classes dynamically)?
- Not natively, but you can integrate it with Laravel’s container by creating a custom resolver or using `bindWhen` for dynamic instantiation. The package doesn’t provide Laravel-specific service container hooks, so you’ll need to write glue code for seamless integration.
- How does performance compare to Laravel’s `make()` or manual `new` for simple objects?
- Reflection-based construction adds overhead, especially on cold starts. For simple cases, Laravel’s `make()` or manual `new` may be faster. However, caching reflection data (e.g., via a static instance) can mitigate this. Benchmark in your environment to compare latency.
- Will this break if I use it with Eloquent models or database queries?
- Avoid using it directly with Eloquent models unless wrapped in a repository pattern, as it may conflict with Laravel’s ORM. For API responses or DTOs, it works well. For database hydration, consider Laravel’s built-in `hydrate()` or query builder methods instead.
- Does it support Laravel’s request validation data (e.g., replacing `Validator::make()` + manual instantiation)?
- Yes, you can replace `Validator::make($request->all())->validate()` followed by manual instantiation with `ClassBuilder::build(Model::class, $request->all())`. This reduces boilerplate for request-to-object mapping, especially for complex DTOs or API resources.
- How do I handle abstract classes or interfaces with multiple inheritors?
- Use the `@AvailableInheritors` attribute to specify possible classes that implement the interface or extend the abstract class. The builder will attempt to instantiate each until one succeeds. For conditional logic, use the `@BuildIf` attribute with a `CheckerInterface` implementation.
- Is there a way to cache reflection data for better performance in production?
- Yes, wrap the `ClassBuilder` in a static instance or cache reflection data manually. For example, use `ClassBuilder::getInstance()->build()` to reuse the same builder instance across requests. This reduces reflection overhead significantly in high-traffic applications.
- Are there alternatives like this for Laravel, and how does this compare?
- Alternatives include `spatie/fractal` (for API resources) or `league/arrayobjects` (for typed collections). However, this package uniquely supports complex type systems (unions, intersections, generics) and abstract classes/interfaces, making it ideal for domain-driven design or API request mapping.
- Will this work in Laravel queues or concurrent environments (e.g., WebSockets)?
- Reflection-heavy operations may cause issues in concurrent environments like queues or WebSockets. For production use, cache reflection data and test thoroughly. Avoid real-time systems where low latency is critical, as reflection adds overhead.
- How do I handle errors or unsupported cases (e.g., private properties, recursive types)?
- Use try-catch blocks to gracefully fall back to manual instantiation. The package lacks built-in error handling for edge cases like private properties or complex inheritance. For critical paths, implement a fallback mechanism (e.g., `config('app.use_class_builder')` toggle).