PHP code example of julienlinard / doctrine-php

1. Go to this page and download the library: Download julienlinard/doctrine-php library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

julienlinard / doctrine-php example snippets




ulienLinard\Doctrine\EntityManager;
use JulienLinard\Doctrine\Mapping\Entity;
use JulienLinard\Doctrine\Mapping\Column;
use JulienLinard\Doctrine\Mapping\Id;

// Define an entity
#[Entity(table: 'users')]
class User
{
    #[Id]
    #[Column(type: 'integer', autoIncrement: true)]
    public ?int $id = null;
    
    #[Column(type: 'string', length: 255)]
    public string $email;
    
    #[Column(type: 'string', length: 255)]
    public string $name;
}

// Database configuration
$config = [
    'driver' => 'mysql',
    'host' => 'localhost',
    'dbname' => 'mydatabase',
    'user' => 'root',
    'password' => 'password'
];

// Create Entity Manager
$em = new EntityManager($config);

// Create a user
$user = new User();
$user->email = '[email protected]';
$user->name = 'John Doe';
$em->persist($user);
$em->flush();

// Retrieve a user
$user = $em->getRepository(User::class)->find(1);
echo $user->name; // John Doe

use JulienLinard\Doctrine\Mapping\Entity;
use JulienLinard\Doctrine\Mapping\Column;
use JulienLinard\Doctrine\Mapping\Id;
use JulienLinard\Doctrine\Mapping\Index;

#[Entity(table: 'users')]
class User
{
    #[Id]
    #[Column(type: 'integer', autoIncrement: true)]
    public ?int $id = null;
    
    #[Column(type: 'string', length: 255)]
    #[Index(unique: true)]
    public string $email;
    
    #[Column(type: 'string', length: 255, nullable: true)]
    public ?string $name = null;
    
    #[Column(type: 'boolean', default: true)]
    public bool $is_active = true;
    
    #[Column(type: 'datetime', nullable: true)]
    public ?\DateTime $created_at = null;
}

$em = new EntityManager($config);

// Create
$user = new User();
$user->email = '[email protected]';
$user->name = 'Test User';
$em->persist($user);
$em->flush();

// Read
$user = $em->find(User::class, 1);

// Update
$user->name = 'Updated Name';
$em->persist($user); // Re-persist modified entity
$em->flush();

// Delete
$em->remove($user);
$em->flush();

$users = [];
for ($i = 1; $i <= 100; $i++) {
    $user = new User();
    $user->email = "user{$i}@example.com";
    $user->name = "User {$i}";
    $users[] = $user;
}

// Batch insert (optimized - single INSERT query)
$em->persistBatch($users);
$em->flush(); // Executes one INSERT with multiple VALUES

// Method 1: Automatic transaction (recommended)
$result = $em->transaction(function($em) {
    $user = new User();
    $user->email = '[email protected]';
    $em->persist($user);
    
    $post = new Post();
    $post->title = 'My Post';
    $post->user = $user;
    $em->persist($post);
    
    $em->flush();
    return $user; // Return value is preserved
});

// Method 2: Manual transaction
$em->beginTransaction();
try {
    $user = new User();
    $em->persist($user);
    $em->flush();
    $em->commit();
} catch (\Exception $e) {
    $em->rollback();
    throw $e;
}

$repository = $em->getRepository(User::class);

// Find by ID
$user = $repository->find(1);

// Find all
$users = $repository->findAll();

// Find by criteria
$users = $repository->findBy(['is_active' => true]);
$user = $repository->findOneBy(['email' => '[email protected]']);

// Find or fail (throws exception if not found)
$user = $repository->findOrFail(1);
$user = $repository->findOneByOrFail(['email' => '[email protected]']);

// With ordering
$users = $repository->findBy(
    ['is_active' => true],
    ['created_at' => 'DESC']
);

// With pagination
$users = $repository->findBy(
    [],
    ['name' => 'ASC'],
    10,  // limit
    0    // offset
);

// With query cache
$users = $repository->findAll(true, 3600); // Cache for 1 hour
$users = $repository->findBy(
    ['is_active' => true],
    null, null, null,
    true,  // use cache
    3600   // TTL
);

// Load users with their posts (optimized - avoids N+1 queries)
$users = $repository->findAllWith(['posts']);

// Each user now has $user->posts loaded
foreach ($users as $user) {
    foreach ($user->posts as $post) {
        echo $post->title;
    }
}

use JulienLinard\Doctrine\Repository\EntityRepository;

class UserRepository extends EntityRepository
{
    public function findActiveUsers(): array
    {
        return $this->findBy(['is_active' => true]);
    }
    
    public function findByEmailDomain(string $domain): array
    {
        return $this->findBy([], ['email' => 'ASC'])
            ->filter(fn($user) => str_ends_with($user->email, $domain));
    }
}

// Create custom repository
$userRepo = $em->createRepository(UserRepository::class, User::class);
$activeUsers = $userRepo->findActiveUsers();

$qb = $em->createQueryBuilder();

// Basic query
$users = $qb->select('u')
    ->from(User::class, 'u')
    ->where('u.email = :email')
    ->andWhere('u.is_active = :active')
    ->setParameter('email', '[email protected]')
    ->setParameter('active', true)
    ->orderBy('u.created_at', 'DESC')
    ->setMaxResults(10)
    ->getResult();

// Aggregations
$stats = $qb->select('u')
    ->from(User::class, 'u')
    ->count('u.id', 'total')
    ->sum('u.views', 'total_views')
    ->avg('u.rating', 'avg_rating')
    ->groupBy('u.category_id')
    ->having('total > :min')
    ->setParameter('min', 10)
    ->getResult();

// Subqueries
$users = $qb->select('u')
    ->from(User::class, 'u')
    ->whereSubquery('u.id', 'IN', function($subQb) {
        $subQb->from(Post::class, 'p')
              ->select('p.user_id')
              ->where('p.published = ?', true);
    })
    ->getResult();

// EXISTS
$users = $qb->select('u')
    ->from(User::class, 'u')
    ->whereExists(function($subQb) {
        $subQb->from(Post::class, 'p')
              ->where('p.user_id = u.id')
              ->where('p.published = ?', true);
    })
    ->getResult();

// UNION
$qb1 = $em->createQueryBuilder()
    ->from(User::class, 'u')
    ->select('u.id', 'u.name');
    
$qb2 = $em->createQueryBuilder()
    ->from(Admin::class, 'a')
    ->select('a.id', 'a.name');
    
$all = $qb->union($qb1, $qb2)->getResult();

use JulienLinard\Doctrine\Mapping\OneToMany;
use JulienLinard\Doctrine\Mapping\ManyToOne;

#[Entity(table: 'users')]
class User
{
    #[Id]
    #[Column(type: 'integer', autoIncrement: true)]
    public ?int $id = null;
    
    #[OneToMany(targetEntity: Post::class, mappedBy: 'user', cascade: ['persist', 'remove'])]
    public array $posts = [];
}

#[Entity(table: 'posts')]
class Post
{
    #[Id]
    #[Column(type: 'integer', autoIncrement: true)]
    public ?int $id = null;
    
    #[ManyToOne(targetEntity: User::class, inversedBy: 'posts')]
    public ?User $user = null;
    
    #[Column(type: 'string', length: 255)]
    public string $title;
}

// Usage
$user = $em->getRepository(User::class)->find(1);

// Load relations manually
$em->loadRelations($user, 'posts');

// Or use eager loading (optimized)
$users = $repository->findAllWith(['posts']);

use JulienLinard\Doctrine\Mapping\ManyToMany;

#[Entity(table: 'users')]
class User
{
    #[ManyToMany(targetEntity: Role::class)]
    public array $roles = [];
}

#[Entity(table: 'roles')]
class Role
{
    #[Id]
    #[Column(type: 'integer', autoIncrement: true)]
    public ?int $id = null;
    
    #[Column(type: 'string', length: 50)]
    public string $name;
}

$user = $em->transaction(function($em) {
    $user = new User();
    $user->email = '[email protected]';
    $em->persist($user);
    $em->flush();
    return $user;
});
// Automatically commits on success, rolls back on exception

$em->beginTransaction();
try {
    $user = new User();
    $em->persist($user);
    $em->flush();
    $em->commit();
} catch (\Exception $e) {
    $em->rollback();
    throw $e;
}

// Generate for one entity
$sql = $em->generateMigration(User::class);

// Generate for multiple entities
$sql = $em->generateMigrations([User::class, Post::class]);



return [
    'driver' => 'mysql',
    'host' => 'localhost',
    'dbname' => 'mydatabase',
    'user' => 'root',
    'password' => 'password',
    'charset' => 'utf8mb4',
];

// Enable query cache
$queryCache = new \JulienLinard\Doctrine\Cache\QueryCache(
    defaultTtl: 3600,  // 1 hour
    enabled: true
);

$em = new EntityManager($config, $queryCache);

// Use cache in repositories
$users = $repository->findAll(true, 3600); // Cache for 1 hour
$users = $repository->findBy(
    ['is_active' => true],
    null, null, null,
    true,  // use cache
    3600   // TTL
);

// Cache is automatically invalidated on entity updates

$users = [];
for ($i = 1; $i <= 1000; $i++) {
    $user = new User();
    $user->email = "user{$i}@example.com";
    $users[] = $user;
}

// Single INSERT query with multiple VALUES
$em->persistBatch($users);
$em->flush();

// Before: 1 query + N queries (N+1 problem)
// After: 1 query + 1 query (optimized)
$users = $repository->findAllWith(['posts']);

// Enable query logging
$logger = $em->enableQueryLog(
    enabled: true,
    logFile: 'queries.log',  // Optional: log to file
    logToConsole: true       // Optional: log to console
);

// Execute queries
$user = new User();
$em->persist($user);
$em->flush();

// View logs
$logs = $logger->getLogs();
foreach ($logs as $log) {
    echo $log['sql'] . ' (' . ($log['time'] * 1000) . 'ms)' . PHP_EOL;
    echo 'Params: ' . json_encode($log['params']) . PHP_EOL;
}

// Get statistics
echo "Total queries: " . $logger->count() . PHP_EOL;
echo "Total time: " . ($logger->getTotalTime() * 1000) . "ms" . PHP_EOL;

// Clear logs
$logger->clear();

// Disable logging
$em->disableQueryLog();

   $em->persistBatch($entities); // Instead of loop with persist()

   $users = $repository->findAllWith(['posts']); // Optimized

   $users = $repository->findAll(true, 3600);

   $em->transaction(function($em) { /* ... */ });

   $user = $repository->findOrFail(1); // Throws exception if not found

   $userRepo = $em->createRepository(UserRepository::class, User::class);

   $em->enableQueryLog(true, 'queries.log', true);



use JulienLinard\Doctrine\EntityManager;

class UserController
{
    public function __construct(
        private EntityManager $em
    ) {}
    
    public function show(int $id)
    {
        $user = $this->em->getRepository(User::class)->findOrFail($id);
        return ['user' => $user];
    }
    
    public function store(array $data)
    {
        return $this->em->transaction(function($em) use ($data) {
            $user = new User();
            $user->email = $data['email'];
            $user->name = $data['name'];
            $em->persist($user);
            $em->flush();
            return $user;
        });
    }
}
bash
composer 
bash
# Rollback last migration
php bin/doctrine-migrate rollback

# Rollback 3 migrations
php bin/doctrine-migrate rollback --steps=3