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

Phpstan Symfony Laravel Package

phpstan/phpstan-symfony

PHPStan extension for Symfony that improves static analysis with precise return types and framework-specific rules. Understands container/services, parameters, controllers, request/headers, serializer, forms, messenger handlers, cache callbacks, config tree builders, and more.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require --dev phpstan/phpstan-symfony

Use phpstan/extension-installer for automatic configuration or manually include:

includes:
    - vendor/phpstan/phpstan-symfony/extension.neon
    - vendor/phpstan/phpstan-symfony/rules.neon
  1. Configure Container Path: Add your Symfony container XML path to phpstan.neon:

    parameters:
        symfony:
            containerXmlPath: var/cache/dev/App_KernelDevDebugContainer.xml
    
  2. First Use Case: Run PHPStan on a Symfony controller:

    vendor/bin/phpstan analyse src/Controller/
    

    The extension will now provide accurate return types for ContainerInterface::get(), Request::getContent(), etc.


Implementation Patterns

1. Service Container Type Resolution

  • Pattern: Use ContainerInterface::get() with precise return types.

    $userRepository = $this->container->get(UserRepositoryInterface::class);
    // PHPStan now knows $userRepository is UserRepositoryInterface
    
  • Workflow:

    1. Define services in services.yaml with proper types.
    2. Run PHPStan to validate container access.
    3. Fix errors by ensuring services are registered or adjusting autowiring.

2. Messenger HandleTrait Integration

  • Pattern: Configure HandleTrait wrappers for Query Buses.

    parameters:
        symfony:
            messenger:
                handleTraitWrappers:
                    - App\Bus\QueryBus::dispatch
    
    class QueryBus {
        use HandleTrait;
        public function dispatch(object $query): mixed { /* ... */ }
    }
    // PHPStan infers return types for $queryBus->dispatch(new GetProductQuery())
    
  • Workflow:

    1. Annotate message handlers with #[AsMessageHandler].
    2. Configure handleTraitWrappers in phpstan.neon.
    3. Use dispatch() methods with type-safe return values.

3. Console Command Analysis

  • Pattern: Enable console command argument/option type checking.

    parameters:
        symfony:
            consoleApplicationLoader: tests/ConsoleApplication.php
    
    // tests/ConsoleApplication.php
    use App\Kernel;
    use Symfony\Bundle\FrameworkBundle\Console\Application;
    return new Application(new Kernel('test', true));
    
  • Workflow:

    1. Create a console-application.php file.
    2. Configure consoleApplicationLoader in phpstan.neon.
    3. Run PHPStan to validate $input->getArgument() and $input->getOption().

4. Form and Serializer Type Safety

  • Pattern: Leverage type hints for FormInterface::getErrors() and SerializerInterface::deserialize().

    $form = $this->createForm(UserType::class);
    $errors = $form->getErrors(true, false); // PHPStan knows return type is FormErrorIterator
    
  • Workflow:

    1. Use Symfony’s typed form components.
    2. Run PHPStan to catch mismatched error handling.

5. Dependency Injection Validation

  • Pattern: Detect unregistered or private services.

    $this->container->get('unregistered_service'); // Error: Service not found
    $this->container->get('private_service');      // Error: Service is private
    
  • Workflow:

    1. Run PHPStan with the extension.
    2. Fix errors by registering missing services or adjusting visibility.

Gotchas and Tips

1. Container XML Path Pitfalls

  • Gotcha: Incorrect containerXmlPath leads to no type resolution.
    • Fix: Verify the path matches your Symfony version:
      • Symfony 5+: var/cache/dev/App_KernelDevDebugContainer.xml
      • Symfony 4.2+: var/cache/dev/srcApp_KernelDevDebugContainer.xml
    • Tip: Use bin/console debug:container --dump to regenerate the file.

2. Constant Hassers and Optional Dependencies

  • Gotcha: ::has() methods may cause false positives for optional dependencies.
    if ($this->container->has('optional_service')) { // Always true/false
        // ...
    }
    
    • Fix: Disable constantHassers in phpstan.neon:
      parameters:
          symfony:
              constantHassers: false
      
    • Tip: Use try-catch with get() instead of has() for optional services.

3. Messenger HandleTrait Limitations

  • Gotcha: Unconfigured wrappers default to mixed return types.
    • Fix: Explicitly configure all HandleTrait wrappers:
      parameters:
          symfony:
              messenger:
                  handleTraitWrappers:
                      - App\Bus\CommandBus::handle
                      - App\Bus\QueryBus::dispatch
      
    • Tip: Test with a single wrapper first to validate setup.

4. Console Application Configuration

  • Gotcha: PhpParser conflicts when using consoleApplicationLoader.
    • Fix: Disable inlining in Symfony’s container dumper:
      # config/packages/phpstan_env/parameters.yaml
      parameters:
          container.dumper.inline_class_loader: false
      
    • Tip: Use a dedicated phpstan_env kernel for console analysis.

5. Performance with Large Projects

  • Gotcha: Parsing container XML slows down analysis.
    • Fix: Enable lazy loading (built into v2.0.17+).
    • Tip: Exclude non-critical paths from PHPStan runs:
      vendor/bin/phpstan analyse src/ --exclude tests/
      

6. Form and Serializer Stub Files

  • Gotcha: Missing stubs for custom form types or serializers.
    • Fix: Ensure scanDirectories includes cache paths for PHP config files (Symfony 5.3+):
      parameters:
          scanDirectories:
              - var/cache/dev/Symfony/Config
      
    • Tip: Use phpstan diagnose to identify missing stubs.

7. Debugging False Positives

  • Gotcha: Overly strict type checks for dynamic methods (e.g., InputBag::get()).
    • Fix: Adjust level in phpstan.neon for specific rules:
      rules:
          Symfony\Container\ContainerInterface:
              level: 3
      
    • Tip: Use // @phpstan-ignore-next-line sparingly for known edge cases.

8. Extension-Installer Quirks

  • Gotcha: Manual installation may miss updates.
    • Fix: Prefer phpstan/extension-installer for automatic updates:
      composer require --dev phpstan/extension-installer
      
    • Tip: Pin the extension version in composer.json for stability:
      "extra": {
          "phpstan-extensions": ["phpstan/phpstan-symfony:^2.0"]
      }
      

9. Symfony 6+ Compatibility

  • Gotcha: New Symfony versions may require updated stubs.
    • Fix: Check the release notes for breaking changes.
    • Tip: Test with --strict flag:
      vendor/bin/phpstan analyse --strict
      

10. IDE Integration

  • Tip: Configure your IDE (PHPStorm, VSCode) to use PHPStan’s cache for faster feedback:
    • PHPStorm: Enable "Use PHPStan" in Inspections settings.
    • VSCode: Use the phpstan extension with phpstan.neon path.

---
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.
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
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope