Database & Doctrine
Symfony integrates Doctrine, the most powerful PHP ORM. Each database table maps to an entity: a plain PHP class where attributes describe the columns.
You don't even write these classes by hand: the interactive make:entity command generates and updates them, and the migration commands create the SQL to evolve your database schema safely.
To query the database, autowire the entity's repository. The built-in methods cover the common cases, and you add your own methods for complex queries.
When the built-in methods aren't enough, add your own using the QueryBuilder: a fluent API to compose queries in pure PHP. And for edge cases or special needs, you can always drop down to raw SQL.
<?phpnamespace App\Entity;use App\Repository\ArticleRepository;use Doctrine\ORM\Mapping as ORM;#[ORM\Entity(repositoryClass: ArticleRepository::class)]class Article{ #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] private ?string $title = null; #[ORM\Column(type: 'text')] private ?string $content = null; // ... getters and setters}<?phpnamespace App\Controller;use App\Repository\ArticleRepository;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Attribute\Route;class ArticleController extends AbstractController{ #[Route('/articles')] public function list(ArticleRepository $articles): Response { $latest = $articles->findBy([], ['title' => 'ASC'], limit: 10); return $this->render('article/list.html.twig', [ 'articles' => $latest, ]); }}<?phpnamespace App\Repository;use App\Entity\Article;use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;use Doctrine\Persistence\ManagerRegistry;class ArticleRepository extends ServiceEntityRepository{ public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Article::class); } public function findByKeyword(string $keyword): array { return $this->createQueryBuilder('article') ->where('article.title LIKE :keyword') ->setParameter('keyword', '%'.$keyword.'%') ->getQuery() ->getResult(); }}$ php bin/console make:entity Article$ php bin/console make:migration$ php bin/console doctrine:migrations:migrate