Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Entities and migrations

Symfony works with the database through Doctrine. Each table has an entity — a plain PHP class — and each row is its object. Unlike Laravel models, an entity knows nothing about the database: a separate object does the saving.

Connecting

The database address is set in the .env file:

DATABASE_URL="mysql://root:secret@127.0.0.1:3306/blog?serverVersion=8.0.32&charset=utf8mb4"

A command creates the database itself:

php bin/console doctrine:database:create

Creating an entity

php bin/console make:entity Post

The command asks about each field: name, type, length, whether it may be empty. Two files appear as a result — the entity and its repository.

What an entity looks like

// src/Entity/Post.php
namespace App\Entity;
 
use App\Repository\PostRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
 
#[ORM\Entity(repositoryClass: PostRepository::class)]
class Post
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;
 
    #[ORM\Column(length: 255)]
    private ?string $title = null;
 
    #[ORM\Column(type: Types::TEXT)]
    private ?string $body = null;
 
    #[ORM\Column]
    private bool $published = false;
 
    public function getId(): ?int
    {
        return $this->id;
    }
 
    public function getTitle(): ?string
    {
        return $this->title;
    }
 
    public function setTitle(string $title): static
    {
        $this->title = $title;
 
        return $this;
    }
 
    // the remaining get and set methods
}

The #[ORM\Column] attributes describe the columns. Properties are private and accessed through methods.

Column parameters

FormMeaning
#[ORM\Column(length: 100)]A string of up to 100 characters
#[ORM\Column(nullable: true)]May be empty
#[ORM\Column(unique: true)]Values do not repeat
#[ORM\Column(type: Types::TEXT)]Long text
#[ORM\Column(options: ['default' => 0])]A default value

Doctrine usually works out the column type from the property type: int, string, bool, float, \DateTimeImmutable.

The migration

An entity is only a description. A migration creates the table:

php bin/console make:migration
php bin/console doctrine:migrations:migrate

The first command compares the entities with the database and writes the difference to a file in the migrations folder. The second one runs it.

Changing the structure

To add a field, run make:entity Post again and answer the questions — or add the property by hand. Then create and run a new migration. The database structure changes step by step this way, and every step is kept in the project repository.

Common mistake

The doctrine:schema:update --force command changes the database at once, without a migration file. That is handy on your own machine, but on a server such changes cannot be repeated or undone. Change a production database only with migrations, and read the generated file before running it: Doctrine may propose dropping a column together with its data.

Thanks for reading!

Donate to the site — we work hard for you.