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

Doctrine Doctor Laravel Package

ahmed-bhs/doctrine-doctor

Doctrine Doctor is a runtime analysis tool for Doctrine ORM integrated into the Symfony Web Profiler. It detects real-world issues like N+1 queries, slow queries, missing indexes, hydration overhead, and injection risks, with actionable backtraces and suggestions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require --dev ahmed-bhs/doctrine-doctor
    
    • Auto-configures via Symfony Flex (no manual setup needed for basic usage).
  2. Enable Backtraces (recommended for debugging):

    # config/packages/dev/doctrine.yaml
    doctrine:
        dbal:
            profiling_collect_backtrace: true
    
  3. First Use Case:

    • Navigate to any page in your Symfony app (in dev environment).
    • Open the Symfony Web Profiler (bottom toolbar).
    • Click the "Doctrine Doctor" panel to review runtime issues.

Implementation Patterns

Daily Workflow

  1. Development Phase:

    • Write code as usual, then check the Doctrine Doctor panel after each significant change.
    • Prioritize Critical and Warning issues before committing.
  2. Code Review:

    • Use the backtrace feature to pinpoint exact lines in templates or controllers causing issues.
    • Example: Fix an N+1 query by replacing:
      $users = $repository->findAll();
      
      with:
      $users = $repository
          ->createQueryBuilder('u')
          ->leftJoin('u.profile', 'p')
          ->addSelect('p')
          ->getResult();
      
  3. Team Collaboration:

    • Share custom thresholds (e.g., stricter n_plus_one detection) via config/packages/dev/doctrine_doctor.yaml.
    • Example:
      doctrine_doctor:
          analyzers:
              n_plus_one:
                  threshold: 2  # Detect even minor N+1 issues
              slow_query:
                  threshold: 50  # Flag queries over 50ms
      
  4. Pre-Deployment Checklist:

    • Run tests to ensure fixes don’t break functionality.
    • Review the staging environment with production-like data.
    • Disable Doctrine Doctor in production (it’s auto-disabled in prod environment).

Integration Tips

  • Custom Analyzers: Extend the package by creating custom analyzers. Refer to the Architecture Guide for details on how to hook into the analysis pipeline.

  • CI/CD Pipeline: Add a static analysis step (e.g., PHPStan) to catch issues early, then use Doctrine Doctor for runtime validation in your dev/staging environments.

  • Symfony Events: Listen to kernel.request or kernel.controller events to trigger analysis for specific routes:

    use Symfony\Component\HttpKernel\Event\RequestEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    $eventDispatcher->addListener(KernelEvents::REQUEST, function (RequestEvent $event) {
        if ($event->isMainRequest() && $event->getRequest()->getPathInfo() === '/admin') {
            // Force analysis for admin routes
            $this->doctrineDoctor->analyze();
        }
    });
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • Doctrine Doctor adds minimal overhead (typically <5ms per request) but should never be enabled in production.
    • If analysis slows down development, adjust thresholds (e.g., increase slow_query.threshold).
  2. Missing Backtraces:

    • If backtraces don’t show, ensure profiling_collect_backtrace is enabled in Doctrine DBAL config.
    • Debug with:
      php bin/console debug:config doctrine
      
  3. False Positives:

    • Some analyzers (e.g., missing_index) may flag queries that are intentionally optimized for your specific database schema.
    • Use the ignore configuration to exclude specific queries:
      doctrine_doctor:
          ignored_queries:
              - "SELECT u.*, p.* FROM user u JOIN profile p ON u.id = p.user_id WHERE u.active = :active"
      
  4. Database Permissions:

    • The Missing Index Analyzer requires EXPLAIN permissions. If you see permission errors, grant:
      GRANT EXECUTE ON PROCEDURE `sys`.`pt_show_grants` TO 'your_user';
      

Debugging Tips

  1. Disable Specific Analyzers: Temporarily disable noisy analyzers (e.g., excessive_hydration) in doctrine_doctor.yaml:

    doctrine_doctor:
        analyzers:
            excessive_hydration:
                enabled: false
    
  2. Log Raw Analysis Data: Enable debug logging to inspect raw analyzer output:

    # config/packages/dev/monolog.yaml
    monolog:
        handlers:
            main:
                level: debug
                channels: ["doctrine_doctor"]
    
  3. Reset Cache: If issues persist after configuration changes, clear the Symfony cache:

    php bin/console cache:clear
    

Extension Points

  1. Custom Analyzers: Create a class implementing AhmedBhs\DoctrineDoctor\Analyzer\AnalyzerInterface:

    use AhmedBhs\DoctrineDoctor\Analyzer\AnalyzerInterface;
    use AhmedBhs\DoctrineDoctor\Analyzer\Issue;
    
    class CustomAnalyzer implements AnalyzerInterface {
        public function analyze(array $queries): array {
            foreach ($queries as $query) {
                if (str_contains($query['sql'], 'SELECT *')) {
                    yield new Issue(
                        'Performance',
                        'Avoid SELECT * queries',
                        $query['backtrace'],
                        Issue::SEVERITY_WARNING
                    );
                }
            }
        }
    }
    

    Register it in config/packages/dev/doctrine_doctor.yaml:

    doctrine_doctor:
        analyzers:
            custom:
                class: App\Analyzer\CustomAnalyzer
                enabled: true
    
  2. Modify Issue Severity: Override severity levels for specific analyzers:

    doctrine_doctor:
        analyzers:
            n_plus_one:
                severity: critical  # Default is warning
    
  3. Post-Analysis Hooks: Listen to the doctrine_doctor.analysis.complete event to process results:

    use AhmedBhs\DoctrineDoctor\Event\AnalysisCompleteEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class DoctrineDoctorSubscriber implements EventSubscriberInterface {
        public static function getSubscribedEvents() {
            return [
                'doctrine_doctor.analysis.complete' => 'onAnalysisComplete',
            ];
        }
    
        public function onAnalysisComplete(AnalysisCompleteEvent $event) {
            $issues = $event->getIssues();
            // Custom logic (e.g., log to Slack, trigger alerts)
        }
    }
    
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
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