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 Bridge Laravel Package

symfony/doctrine-bridge

Symfony Doctrine Bridge integrates Doctrine ORM and related libraries with Symfony components, providing seamless wiring for services, repositories, persistence, and tooling. Ideal for projects using Doctrine alongside Symfony’s DI container, validator, and other features.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/doctrine-bridge
    

    This package is typically included as a dependency of symfony/framework-bundle, so explicit installation is rare unless extending functionality.

  2. First Use Case:

    • Entity Validation: Annotate a Doctrine entity with Symfony’s validation constraints (e.g., @Assert\Email, @Assert\Length) and leverage the bridge to auto-validate during form submission or API requests.
      use Symfony\Component\Validator\Constraints as Assert;
      
      #[ORM\Entity]
      class User
      {
          #[ORM\Id, ORM\GeneratedValue]
          #[Assert\NotBlank]
          private ?int $id = null;
      
          #[Assert\Email]
          private string $email;
      }
      
    • Form Integration: Use Symfony\Bridge\Doctrine\Form\Type\EntityType to bind Doctrine entities to Symfony forms:
      use Symfony\Bridge\Doctrine\Form\Type\EntityType;
      
      $builder->add('user', EntityType::class, [
          'class' => User::class,
          'choice_label' => 'email',
      ]);
      
  3. Where to Look First:

    • Symfony Docs: Doctrine Integration for core features.
    • Bridge Source: Symfony\Bridge\Doctrine for advanced use cases (e.g., custom types, event listeners).
    • Dependency Injection: Check config/packages/doctrine.yaml for Doctrine configuration and services.yaml for custom Doctrine services.

Implementation Patterns

Usage Patterns

  1. Entity-Driven Development:

    • Pattern: Use Doctrine entities as the single source of truth for data and validation. Annotate entities with:
      • ORM Metadata (@ORM\*) for database mapping.
      • Validation Constraints (@Assert\*) for business rules.
      • Symfony Serializer Groups (@Groups) for API payloads.
    • Example:
      #[ORM\Entity(repositoryClass: UserRepository::class)]
      #[UniqueEntity('email')]
      #[ApiResource(
          collectionOperations: ['get', 'post'],
          itemOperations: ['get', 'put', 'delete']
      )]
      class User { ... }
      
  2. Form-Entity Binding:

    • Pattern: Bind Symfony forms directly to Doctrine entities using EntityType or Form\Type\FormType with data_class.
    • Workflow:
      1. Create a form type extending AbstractType.
      2. Use EntityType for entity fields or FormType for custom logic.
      3. Submit the form; the bridge auto-persists/updates entities.
    • Example:
      $form = $this->createFormBuilder($user)
          ->add('email', EmailType::class)
          ->add('save', SubmitType::class)
          ->getForm();
      
  3. Security Integration:

    • Pattern: Use Doctrine entities as UserProvider for Symfony’s security system.
    • Steps:
      1. Implement UserInterface and PasswordAuthenticatedUserInterface in your entity.
      2. Configure the security.yaml to use doctrine as the user provider.
      3. Leverage PersistentToken for "remember me" functionality.
    • Example:
      # config/packages/security.yaml
      security:
          providers:
              app_user_provider:
                  entity:
                      class: App\Entity\User
                      property: email
      
  4. Event Listeners and Subscribers:

    • Pattern: Hook into Doctrine lifecycle events (e.g., prePersist, postUpdate) via Symfony’s event dispatcher.
    • Example:
      use Doctrine\ORM\Event\LifecycleEventArgs;
      use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
      
      #[AsEventListener(event: 'prePersist', method: 'onPrePersist')]
      public function onPrePersist(User $user, LifecycleEventArgs $args): void
      {
          $user->setCreatedAt(new \DateTime());
      }
      
  5. Custom Doctrine Types:

    • Pattern: Extend Doctrine’s type system for domain-specific fields (e.g., DayPointType, TimePointType).
    • Steps:
      1. Create a custom type class extending AbstractPlatformSpecificType.
      2. Register it in doctrine.yaml:
      doctrine:
          dbal:
              types:
                  day_point: App\Doctrine\DBAL\Types\DayPointType
      
      1. Use it in entities:
      #[ORM\Column(type: 'day_point')]
      private DayPoint $startDate;
      
  6. API Platform Integration:

    • Pattern: Use api-platform/core with Doctrine for auto-generated REST/GraphQL APIs.
    • Example:
      #[ApiResource(
          normalizationContext: ['groups' => ['user:read']],
          denormalizationContext: ['groups' => ['user:write']]
      )]
      class User { ... }
      

Workflows

  1. CRUD Operations:

    • Read: Use EntityRepository or Doctrine\ORM\EntityManager:
      $user = $entityManager->getRepository(User::class)->find($id);
      
    • Create/Update: Bind forms to entities and persist:
      $form->handleRequest($request);
      if ($form->isSubmitted() && $form->isValid()) {
          $entityManager->persist($user);
          $entityManager->flush();
      }
      
    • Delete: Use EntityManager::remove():
      $entityManager->remove($user);
      $entityManager->flush();
      
  2. Validation Workflow:

    • Form Submission:
      $form->submit($data);
      if ($form->isSubmitted() && $form->isValid()) {
          // Proceed with persistence
      }
      
    • Manual Validation:
      $validator = $this->container->get('validator');
      $errors = $validator->validate($entity);
      if (count($errors) > 0) {
          // Handle errors
      }
      
  3. Database Migrations:

    • Use doctrine:migrations:diff and doctrine:migrations:migrate:
      php bin/console make:migration
      php bin/console doctrine:migrations:migrate
      

Integration Tips

  1. Symfony Flex Recipes:

    • Use symfony/recipe to auto-configure Doctrine with Symfony’s ecosystem (e.g., api-platform, maker-bundle).
    • Example:
      composer require api
      
  2. Dependency Injection:

    • Tag services for Doctrine events or use autoconfigure: true in services.yaml:
      services:
          App\EventSubscriber\UserSubscriber:
              tags: ['doctrine.event_subscriber']
      
  3. Testing:

    • Use Doctrine\ORM\EntityManagerInterface in tests with in-memory databases:
      $entityManager = $this->getEntityManager();
      $entityManager->persist($user);
      $entityManager->flush();
      
    • Mock the EntityManager for unit tests:
      $entityManager = $this->createMock(EntityManagerInterface::class);
      
  4. Performance:

    • Enable Doctrine’s second-level cache for read-heavy apps:
      # config/packages/doctrine.yaml
      doctrine:
          orm:
              second_level_cache:
                  enabled: true
                  region_directory: '%kernel.cache_dir%/doctrine'
      

Gotchas and Tips

Pitfalls

  1. Deprecations in Symfony 8+:

    • AbstractDoctrineExtension is removed in Symfony 8.0. Replace with custom form types or extensions.
    • PersistentToken::getClass() and RememberMeDetails::getUserFqcn() are deprecated. Use getUserIdentifier() instead.
  2. Schema Subscriber Check:

    • The _schema_subscriber_check table may conflict with Oracle. Rename it via schema_subscriber_check_ (fixed in v8.0.7+).
    • Workaround: Manually rename the table if using an older version.
  3. UniqueEntity Validator:

    • Issue: UniqueEntity validator may fail with Stringable identifiers (e.g., Uuid).
    • Fix: Ensure the fields option uses scalar types or implement __toString() in your entity.
  4. Same-Database Check:

    • The SameDatabaseChecker may throw exceptions if the database driver is misconfigured. Catch all driver exceptions (fixed in v8.0.9).
  5. Custom Types and UID:

    • Issue: Custom types based on Uid may fail if not
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle