사전 Symfony
구현체

Symfony

gabury1

Symfony 는 PHP 로 웹 애플리케이션을 만들 때 쓰는 프레임워크입니다. 동시에 그 프레임워크를 이루는 부품을 하나씩 따로 떼어 쓸 수 있게 나눠 둔 패키지 모음이기도 합니다. 둘 다 Composer 로 받아서 프로젝트에 얹습니다.

상세

Symfony 는 PHP(PHP: Hypertext Preprocessor) 애플리케이션을 만드는 데 쓰는 배포물입니다. 공식 사이트는 스스로를 "a set of PHP Packages, a Web Application framework, a Philosophy, and a Community" 라고 적습니다. 이 넷 가운데 받아서 설치하는 물건은 앞의 둘입니다.

패키지 쪽은 "decoupled and reusable packages", 곧 서로 떨어져 있고 다시 쓸 수 있는 라이브러리 묶음입니다. 프레임워크 쪽은 그 패키지들 위에 얹혀 있습니다("Built on top of the Symfony Packages"). 그래서 들어가는 길이 둘로 갈립니다.

flowchart TD
    P["Symfony 패키지"] --> F["Symfony 프레임워크"]
    F --> A["Symfony 애플리케이션"]
    P --> O["패키지만 골라 쓰는 다른 프로젝트"]

패키지 하나만 필요하면 그것만 받습니다. 공식 사이트가 안내하는 설치 수단은 Composer 이고, composer require symfony/console 처럼 패키지 이름을 하나씩 적습니다. 프레임워크로 시작하려면 프로젝트 골격을 통째로 받습니다.

터미널
$ composer create-project symfony/skeleton:"8.1.*" my_project_directory

Symfony 바이너리가 있으면 symfony new my_project_directory --version="8.1.*" 로도 같은 일을 합니다. 어느 명령을 쓰든 디렉토리 하나가 만들어지고, 의존성이 그 안에 받아지고, 시작에 필요한 기본 디렉토리와 파일이 생깁니다.

버전이 붙는 물건입니다. 안정판은 8.1.4 이고 PHP 8.4.0 이상을 요구합니다. 장기 지원판(Long-Term Support, LTS)은 7.4.16 이고 PHP 8.2.0 이상을 요구합니다.

포기한 것

Symfony 가 안 하기로 한 자리는 공식 문서가 대부분 스스로 적어 둡니다. 넷을 짚습니다.

하위호환 약속 밖에 두는 것

Symfony 는 마이너 릴리스에 하위호환을 약속합니다. 메이저 릴리스(5.0 · 6.0 같은 판)만 하위호환을 깰 수 있고, 마이너 릴리스(5.1 · 5.2 같은 판)는 새 기능을 넣되 그 릴리스 브랜치의 기존 API(Application Programming Interface)를 깨지 않아야 합니다.

그 약속이 안 미치는 자리를 문서가 못박아 둡니다. 실험 기능(Experimental Features)과 @internal 태그가 붙은 코드는 하위호환 약속에서 빠집니다. 인터페이스를 구현한 코드는 "we promise that we won't ever break your code" 로 보호받지만, @internal 이 붙은 인터페이스는 예외입니다 — 쓰지도 구현하지도 말라고 적습니다. 보안 문제를 고치는 데 필요하면 하위호환이 깨지는 것도 용인된다고 ("tolerated") 적습니다.

대신 얻은 것은 마이너 릴리스에서 새 기능을 계속 넣을 수 있는 자리입니다. 실험 기능은 마이너 판 하나 동안만 실험 상태로 둘 수 있고, LTS 판에는 실험 기능을 들이지 않습니다. 코어 팀이 사안별로 마이너 판 하나를 더 줄 수는 있습니다. 실험 상태인 동안에는 CHANGELOG 가 비호환 변경과 업그레이드 방법을 적어야 합니다.

업그레이드에 주어지는 시간

Symfony 는 판을 무기한 붙들고 있지 않습니다. 두 갈래 유지보수를 두고 각각에 정해진 시간만 줍니다.

표준판 장기 지원판
지금 판 8.1.4 7.4.16
처음 나온 때 2026년 5월 2025년 11월
요구하는 PHP 8.4.0 이상 8.2.0 이상
새 판이 나오는 주기 6개월 2년
업그레이드에 주어지는 기간 2개월 1년

6개월을 고른 이유를 문서가 적습니다. 한 해에 두 판이 들어가고, 새 기능을 다듬을 시간이 넉넉하고, 준비가 덜 된 기능을 다음 주기까지 오래 기다리지 않고 미룰 수 있다는 것입니다. 그 대신 표준판을 쓰는 쪽에는 두 달이라는 업그레이드 창만 주어집니다.

장기 지원판은 버그와 보안 수정을 3년간 받습니다. 그 대가로 최신 기능이 들어 있지 않고, 새 판으로 올라가기가 더 어렵다고 공식 사이트가 적습니다. 버그는 그 버그를 담고 있는 가장 오래된 유지보수 브랜치에서 고칩니다.

기본 골격에 안 들어가는 것

composer create-project symfony/skeleton 이 만드는 골격은 최소한만 받습니다. 웹 애플리케이션을 만들려면 한 번 더 칩니다.

터미널
$ composer create-project symfony/skeleton:"8.1.*" my_project_directory
$ cd my_project_directory
$ composer require webapp

Symfony 바이너리를 쓰는 쪽에는 같은 일을 하는 명령이 따로 있습니다. --webapp 옵션을 붙이느냐 마느냐로 갈립니다.

# 전통적인 웹 애플리케이션을 만들 때
$ symfony new my_project_directory --version="8.1.*" --webapp
# 마이크로서비스나 콘솔 애플리케이션, API 를 만들 때
$ symfony new my_project_directory --version="8.1.*"

이 두 명령의 차이는 기본으로 설치되는 패키지 개수뿐입니다. --webapp 옵션은 웹 애플리케이션을 만드는 데 필요한 것을 다 주는 추가 패키지를 설치합니다. 그 옵션을 안 붙이면 골격만 남고, 마이크로서비스나 콘솔 애플리케이션, API 를 만들 때는 그쪽을 고릅니다. 안 하기로 한 것은 골격 하나로 모든 용도를 덮는 일이고, 얻은 것은 안 쓸 패키지를 처음부터 안 들이는 것입니다.

실행 중 바꿀 수 없는 것

서비스 컨테이너의 파라미터는 컨테이너가 컴파일되기 전에만 설정할 수 있습니다. 실행 중에는 못 바꿉니다. 컨테이너를 실행 전에 컴파일해 두기로 한 결정이고, 그래서 실행에 들어가는 순간 컨테이너는 이미 확정돼 있습니다. 안 하기로 한 것은 돌아가는 중에 파라미터를 갈아 끼우는 길이고, 얻은 것은 실행 전에 한 번 확정되는 컨테이너입니다.

예시

config/services.yaml

YAML
# config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'

새 프로젝트의 기본 서비스 설정입니다. autowire: true 는 서비스에 의존성을 자동으로 주입합니다. autoconfigure: true 는 클래스를 커맨드나 이벤트 구독자 같은 자리에 자동으로 등록합니다. App\: 아래의 resource: '../src/' 는 src/ 안의 클래스를 서비스로 만들고, 서비스 id 는 정규화된 클래스 이름 전체가 됩니다. 이 파일 안에서는 순서가 중요합니다 — 뒤에 온 서비스 정의가 앞의 정의를 대체합니다.

src/Controller/BlogController.php

PHP
// src/Controller/BlogController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class BlogController extends AbstractController
{
    #[Route('/blog', name: 'blog_list')]
    public function list(): Response
    {
        // ...
    }
}

/blog URL(Uniform Resource Locator)에 라우트를 붙이는 최소 형태입니다. #[Route('/blog', name: 'blog_list')] 는 blog_list 라는 이름의 라우트를 정의합니다. 사용자가 /blog 를 요청하면 이 라우트가 맞고, 그때 BlogController 클래스의 list() 메서드가 돕니다. 라우트가 설정 파일이 아니라 메서드 바로 위의 PHP 애트리뷰트로 붙어 있습니다.

사용처

Symfony 공식 사이트가 패키지 위에 지어졌다고 드는 이름은 Drupal · PrestaShop · Laravel 입니다. 아래 셋은 채택한 쪽 저장소의 composer.json 에서 어느 패키지를 요구하는지까지 확인되는 자리입니다.

Drupal

drupal/core 의 composer.json 이 symfony/console · symfony/dependency-injection · symfony/event-dispatcher · symfony/http-foundation · symfony/http-kernel · symfony/routing · symfony/serializer · symfony/validator · symfony/yaml 등을 ^7.4 대로 요구합니다. 서비스 컨테이너와 이벤트, 요청과 응답, 라우팅처럼 프레임워크 뼈대에 해당하는 자리를 Symfony 패키지로 채운 것입니다.

Laravel

laravel/framework 의 composer.json 이 symfony/console · symfony/error-handler · symfony/finder · symfony/http-foundation · symfony/http-kernel · symfony/mailer · symfony/mime · symfony/process · symfony/routing · symfony/uid · symfony/var-dumper 를 요구합니다. PHP 프레임워크가 다른 PHP 프레임워크의 패키지를 부품으로 쓰는 자리입니다. 패키지가 프레임워크와 떨어져 있어서 성립하는 조합입니다.

Composer

Symfony 를 받는 데 쓰는 composer/composer 자신이 symfony/console · symfony/filesystem · symfony/finder · symfony/process 넷을 요구합니다. 프레임워크는 안 들이고 명령줄과 파일, 프로세스를 다루는 패키지만 골라 쓴 자리입니다. 요구 범위도 ^5.4.47 || ^6.4.25 || ^7.1.10 || ^8.0 처럼 메이저 판 넷에 걸쳐 있습니다.

관련 항목

프레임워크를 이루는 패키지

Console · Routing · DependencyInjection · EventDispatcher · HttpFoundation · HttpKernel · HttpClient · Messenger · Serializer · Validator · Form · Cache · Lock · Semaphore · Workflow · Yaml · Finder · Filesystem · Process · Mailer · Mime · Notifier · Translation · Uid · VarDumper · String · RateLimiter · ExpressionLanguage · PropertyAccess · OptionsResolver · Runtime · Flex · Dotenv · ErrorHandler · Intl · Clock · Config · CssSelector · DomCrawler · BrowserKit · PasswordHasher · HtmlSanitizer · Panther · Ldap · Mercure · Asset · DoctrineBridge · MonologBridge · PhpunitBridge · PropertyInfo · SecurityCore · SecurityCsrf

공식 문서 목차가 다루는 개념

라우팅 · 컨트롤러 · Twig · 환경 변수 · 커널 · 서비스 컨테이너 · 의존성 주입 · 이벤트 · 번들 · Doctrine · 폼 · 세션 · 캐시 · 로그 · 콘솔 · 검증 · 메시지 큐 · 스케줄러 · 직렬화 · 국제화

보안 문서가 다루는 개념

인증 · 인가 · 방화벽 · Voter · 비밀번호 해싱 · 크로스 사이트 요청 위조 · LDAP(Lightweight Directory Access Protocol)

프론트엔드를 함께 이루는 도구

AssetMapper · Symfony UX · Stimulus · Webpack Encore · WebLink

이것을 실제로 구현·채택한 제품

Drupal · PrestaShop · Laravel

Symfony 를 설치·실행하는 도구·언어

PHP · Composer · Symfony 바이너리

릴리스·버전 관리에서 쓰는 용어

브랜치 · API · 태그 · CHANGELOG · 표준판 · LTS