Weave Code
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

Props Dic Laravel Package

mrclay/props-dic

A lightweight PHP DI container that exposes services as typed properties and factory methods ($c->foo, $c->new_foo()), letting you add @property/@method PHPDoc for IDE autocomplete and static analysis. Supports lazy resolution, caching, and factories.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strengths:

    • Type Safety and IDE Integration: Props leverages PHP’s @property-read and @method annotations to provide static type hints, enabling autocompletion, refactoring, and static analysis (Psalm/PHPStan). This directly addresses Laravel’s container’s lack of IDE-friendly property access, improving developer experience (DX) without sacrificing PSR-11 compliance.
    • Lightweight and PSR-11 Compliant: Implements Psr\Container\ContainerInterface, ensuring compatibility with Laravel’s service container where basic DI is sufficient. Ideal for modular applications or microservices where IDE tooling is prioritized.
    • Explicit Singleton vs. Fresh Instances: The new_* method pattern (e.g., $container->new_user()) provides fine-grained control over dependency lifecycle, a feature missing in Laravel’s container.
    • Pimple Bridge: Props\Pimple allows gradual migration for teams using Pimple, reducing disruption.
  • Weaknesses:

    • Laravel Ecosystem Gaps: Lacks native support for service providers, contextual binding, macroable containers, or Laravel-specific helpers (e.g., app()->makeWith(), when()). Would require custom wrappers or decorators to replicate functionality.
    • No Built-in Configuration Management: Unlike Laravel, Props doesn’t natively support environment-based bindings (e.g., .env overrides) or package-based service providers.
    • Limited Scoping: No built-in support for scoped/resolved instances (e.g., per-request vs. singleton), which Laravel handles via bindIf() or App::singleton().
    • No Laravel Artisan Integration: Missing make:command/make:controller support, requiring manual setup for CLI tools.

Integration Feasibility

  • Laravel Service Container Hybrid:
    • Partial Replacement: Props can complement Laravel’s container for domain-specific, type-safe bindings (e.g., App\Services\AuthContainer) while retaining Laravel’s container for framework-level dependencies.
    • Wrapper Pattern: Create a decorator class (e.g., LaravelPropsContainer) to bridge Props with Laravel’s Container methods (e.g., bind(), singleton()), translating them to Props’ setFactory() or property assignments.
  • Legacy Codebases:
    • High Feasibility: Replace app('foo') or app()->get('foo') with typed property access (e.g., $container->userRepository), reducing magic strings and improving maintainability.
  • Testing/CLI Tools:
    • Ideal Fit: Props’ simplicity makes it perfect for standalone scripts or Lumen/Slim apps, where IDE support is critical but Laravel’s ecosystem is unnecessary.

Technical Risk

  • Migration Complexity:
    • High for Full Replacement: Replacing Laravel’s container entirely requires rewriting binding logic (e.g., bind(), singleton()) to Props’ setFactory() or direct assignments. Risk: Breaking changes to existing codebase.
    • Medium for Hybrid Use: Using Props alongside Laravel’s container introduces duplication (e.g., managing two containers) and potential conflicts (e.g., circular dependencies, inconsistent scoping).
  • Performance:
    • Low Risk: Props uses lazy loading and caching, similar to Laravel. Benchmarking would be needed for high-throughput applications (e.g., API gateways with >10K RPS), but overhead is expected to be negligible.
  • Tooling and Ecosystem Gaps:
    • High Risk for Laravel-Specific Features: Packages relying on Laravel’s container (e.g., Debugbar, Scout, Horizon) may break or require custom adapters.
    • Testing Overhead: Mocking Props’ property access in tests may require new patterns (e.g., mocking the container subclass directly).
  • Developer Adoption:
    • Medium Risk: Teams accustomed to Laravel’s app()->get() or resolve() syntax may resist property/method access ($container->user). Requires training or documentation to highlight IDE benefits.

Key Questions

  1. Scope of Adoption:

    • Will Props replace Laravel’s entire container, or will it be used only for domain-specific containers (e.g., App\Services\AuthContainer)?
    • Are there third-party packages that tightly couple to Laravel’s container (e.g., app()->makeWith())?
  2. Feature Parity Requirements:

    • Does the team need Laravel-specific features (e.g., service providers, contextual binding, app()->tag())? If so, how will these be implemented (e.g., custom wrappers)?
    • Is scoped/resolved instance management (e.g., per-request singletons) critical? If yes, Props may require extension.
  3. Migration Strategy:

    • How will existing bind(), singleton(), and app()->get() calls be translated to Props’ setFactory() or property assignments?
    • Will the migration be big-bang (all at once) or incremental (e.g., new features use Props, old ones use Laravel’s container)?
  4. IDE/Static Analysis Priority:

    • Is the primary goal better autocompletion and type safety (Props), or is Laravel’s ecosystem and tooling (e.g., Tinker, Scout) more important?
    • Will the team use static analysis tools (Psalm/PHPStan) to enforce dependency contracts?
  5. Testing and CI/CD Impact:

    • How will unit/integration tests adapt to Props’ property access? Will mocking strategies need to change?
    • Are there CI/CD pipelines that rely on Laravel’s container (e.g., php artisan test) that would break?
  6. Long-Term Maintenance:

    • Is the team willing to maintain custom wrappers for Laravel-specific features?
    • How will future Laravel updates (e.g., new container methods) be handled if Props is used in parallel?

Integration Approach

Stack Fit

  • Ideal Use Cases:

    • Domain-Specific Containers: Use Props for business logic containers (e.g., App\Services\PaymentContainer, App\Services\AuthContainer) where IDE support and type safety are critical.
    • Legacy Code Refactoring: Replace app('user_repository') with typed property access ($container->userRepository) to eliminate magic strings and improve maintainability.
    • Lumen/Slim Applications: Full replacement for Laravel’s container in lightweight APIs where IDE tooling is prioritized over Laravel’s ecosystem.
    • CLI/Console Tools: Use Props for standalone scripts or console commands where Laravel’s container is overkill.
  • Poor Fit:

    • Full Laravel Applications: Avoid full replacement due to missing ecosystem features (e.g., service providers, Artisan, Scout).
    • High-Performance APIs: If micro-optimizations are critical, Props’ additional method calls (new_*) may introduce minimal but measurable overhead.
    • Teams Resistant to PHPDoc: Props requires explicit @property-read and @method annotations, which may not align with teams preferring dynamic property access.

Migration Path

  1. Phase 1: Pilot with a Domain-Specific Container

    • Create a new Props-based container (e.g., App\Services\AuthContainer) for a non-critical module (e.g., authentication).
    • Migrate only new features to use this container, keeping existing Laravel bindings intact.
    • Example:
      // Before: Laravel container
      $userRepository = app()->get('App\Repositories\UserRepository');
      
      // After: Props container
      $authContainer = new AuthContainer();
      $userRepository = $authContainer->userRepository;
      
  2. Phase 2: Hybrid Integration

    • Build a decorator class (LaravelPropsContainer) to bridge Props with Laravel’s container:
      class LaravelPropsContainer extends Props\Container {
          public function __construct(private \Illuminate\Container\Container $laravelContainer) {}
      
          public function get($id) {
              return $this->laravelContainer->get($id);
          }
      
          // Translate Laravel's bind() to Props' setFactory()
          public function bind($abstract, $concrete = null, $shared = true) {
              if (is_callable($concrete)) {
                  $this->setFactory($abstract, $concrete);
              } else {
                  $this->{$abstract} = $this->laravelContainer->make($concrete);
              }
          }
      }
      
    • Use this hybrid container gradually in new features.
  3. Phase 3: Full Migration (Optional)

    • Replace all app()->get() calls with Props property access.
    • Update service providers to use setFactory() instead of bind().
    • **Risk Mitigation
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.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium