Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Create, read, update, delete

An entity does not save itself. The EntityManager does that: you tell it which objects to write, and it runs the queries. Data is read through a repository — the class created together with the entity.

Creating a record

use App\Entity\Post;
use Doctrine\ORM\EntityManagerInterface;
 
#[Route('/blog/create', name: 'blog_create')]
public function create(EntityManagerInterface $em): Response
{
    $post = new Post();
    $post->setTitle('First post');
    $post->setBody('The text of the post');
 
    $em->persist($post);
    $em->flush();
 
    return new Response('Created post #' . $post->getId());
}

persist() tells Doctrine about a new object, flush() runs the INSERT query. Nothing changes in the database before flush() is called.

Reading

use App\Repository\PostRepository;
 
#[Route('/blog', name: 'blog_index')]
public function index(PostRepository $posts): Response
{
    return $this->render('blog/index.html.twig', [
        'posts' => $posts->findAll(),
    ]);
}
MethodWhat it returns
find($id)A record by its identifier, or null
findAll()All records
findBy([...])Records matching conditions
findOneBy([...])The first matching record, or null
count([...])The number of records
$latest = $posts->findBy(
    ['published' => true],
    ['id' => 'DESC'],
    10,
);

The arguments of findBy(): conditions, ordering, how many records to take.

An entity right in the arguments

If the address has {id} and the method arguments include an entity, Symfony finds the record by itself. If there is none, it returns a 404 error:

#[Route('/blog/{id}', name: 'blog_show')]
public function show(Post $post): Response
{
    return $this->render('blog/show.html.twig', ['post' => $post]);
}

To search by another field, name it in the address: /blog/{slug:post}.

Updating

Doctrine already tracks an object fetched from the database. Just change it and call flush():

#[Route('/blog/{id}/publish', name: 'blog_publish', methods: ['POST'])]
public function publish(Post $post, EntityManagerInterface $em): Response
{
    $post->setPublished(true);
    $em->flush();
 
    return $this->redirectToRoute('blog_show', ['id' => $post->getId()]);
}

persist() is not needed here.

Deleting

$em->remove($post);
$em->flush();

Several changes at once

flush() writes all accumulated changes in one transaction: either every query runs or none does.

$em->persist($post);
$em->persist($comment);
$author->setPostCount($author->getPostCount() + 1);
 
$em->flush();

Common mistake

Without flush() data is not saved: persist() only queues the object. The code runs without errors, and nothing appears in the database. And the other way round — do not call flush() in a loop after every record: one call after the loop is many times faster.

Thanks for reading!

Donate to the site — we work hard for you.