doctrine/persistence
Doctrine Persistence provides shared abstractions for persistence and object mappers in the Doctrine ecosystem. It defines common interfaces and utilities used by Doctrine ORM and related libraries to manage mapping, metadata, and repository behavior across storage backends.
To leverage doctrine/persistence in a Laravel project, start by installing the package via Composer:
composer require doctrine/persistence
The package provides core abstractions for object persistence. For a Laravel developer, this is most useful when integrating Doctrine ORM/ODM or building custom persistence layers. Here’s how to initialize a basic EntityManager:
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
// In a Laravel service provider or bootstrap file
$registry = new ManagerRegistry();
$entityManager = $registry->getManager(); // Assumes a configured manager
ObjectManager: Core interface for persisting entities.EntityManager: Concrete implementation for ORM.ClassMetadata: Metadata about entity classes.MappingDriver: Loads metadata from annotations, XML, YAML, or attributes.src/Doctrine/Persistence/: Core classes and interfaces.tests/: Real-world usage examples in test cases.Leverage Laravel’s IoC container to bind Doctrine’s ManagerRegistry and ObjectManager:
// In AppServiceProvider::boot()
$this->app->bind(ManagerRegistry::class, function ($app) {
return new ManagerRegistry([
'default' => $app->make(EntityManager::class), // Your configured EM
]);
});
Use ClassMetadataFactory to dynamically generate metadata for entities:
use Doctrine\Persistence\Mapping\ClassMetadataFactory;
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver;
$driver = new AnnotationDriver(new ClassLocator());
$factory = new ClassMetadataFactory();
$factory->setMetadataDriver($driver, 'App\\Entities');
$metadata = $factory->getMetadataFor('App\\Entities\\User');
Implement custom repositories by extending Doctrine\Persistence\ObjectRepository:
use Doctrine\Persistence\ObjectRepository;
class UserRepository extends ObjectRepository
{
public function findActiveUsers(): array
{
return $this->findBy(['isActive' => true]);
}
}
Attach listeners to ObjectManager events (e.g., prePersist, postUpdate):
use Doctrine\Persistence\Event\LifecycleEventArgs;
$em->getEventManager()->addEventListener(
'prePersist',
function (LifecycleEventArgs $args) {
$entity = $args->getObject();
$entity->setUpdatedAt(new DateTime());
}
);
Use ClassMetadata to inspect or modify entity fields at runtime:
$metadata = $em->getClassMetadata(User::class);
$metadata->mapField([
'fieldName' => 'custom_field',
'type' => 'string',
]);
Leverage Doctrine’s proxy system for lazy-loading:
// Enable proxies in your EntityManager configuration
$config = new \Doctrine\ORM\Configuration();
$config->setProxyDir(__DIR__.'/proxies');
$config->setProxyNamespace('App\\Proxies');
$em = EntityManager::create($connection, $config);
php -v to verify compatibility before integrating.ClassMetadataFactory::setMetadataFor() are deprecated (since 4.1+).
Replace with ClassMetadataFactory::setMetadataForName() or avoid direct usage.ClassMetadataFactory::getMetadataFor() for dynamic metadata loading.ClassLocator is configured:
$driver = new AttributeDriver(new ClassLocator());
ClassLocator via Doctrine\Persistence\Mapping\Driver\ClassLocator.EntityManager configuration:
$config->setProxyNamespace('App\\Generated\\Proxies');
getFieldValue()/setFieldValue() for dynamic enum handling:
$metadata->setFieldValue($entity, 'status', UserStatus::ACTIVE);
EntityManager:
$em->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
$em->getConfiguration()->setMetadataCacheImpl(null); // Disable cache for debugging
composer.json:
"autoload": {
"psr-4": {
"App\\Proxies\\": "storage/proxies/"
}
}
ClassMetadataFactory::getMetadataForName() sparingly and cache results:
$cache = new \Doctrine\Common\Cache\FilesystemCache(__DIR__.'/cache');
$factory->setMetadataCacheImpl($cache);
Doctrine\Persistence\ObjectManager interfaces in tests to avoid ORM dependencies:
$this->mockObjectManager = $this->createMock(ObjectManager::class);
$this->mockObjectManager->method('find')->willReturn(new User());
ObjectManagerObjectManager for custom logic:
use Doctrine\Persistence\ObjectManager;
class CustomObjectManager implements ObjectManager
{
private $decorated;
public function __construct(ObjectManager $decorated)
{
$this->decorated = $decorated;
}
public function find($id, $lockMode = null, $lockVersion = null)
{
$entity = $this->decorated->find($id, $lockMode, $lockVersion);
// Add custom logic here
return $entity;
}
// Delegate all other methods to $this->decorated
}
How can I help you explore Laravel packages today?