Symfony 입문

PHP 프레임워크 Symfony에 대한 번들입니다. 국내에선 아직 자료도 많이 없고 인지도 또한 없지만 외국에선 항상 상위에 랭크되어 있으며 phpBB, 드루팔 등 대규모 프로젝트에서도 사용된 검증된 프레임워크 입니다. 강좌는 Symfony 2.8을 기준으로 작성되었습니다.
공개
2016.05.20 00:59:59
조회수 33.8k 등록일 2016.05.30 21:44:47

저번 강좌에서는 Symfony의 디렉토리 구조에 대해서 배웠습니다.

이번 강좌는 프로젝트를 준비하는 단계로 DB 설정, PHP 엔진 활성화, Route 구성 등등 설정을 변경하여 "Hello Dolgo!!"를 출력하는  첫번째 페이지를 생성해 보겠습니다.


DB 설정

DB 설정은 기본적으로 app/config/parameters.yml 에서 관리합니다.

  1. #app/config/parameters
  2. # This file is auto-generated during the composer install
  3. parameters:
  4.     database_host: 127.0.0.1
  5.     database_port: 3306
  6.     database_name: my_database
  7.     database_user: ~~~~
  8.     database_password: ~~~~
  9.     ~~

app/config 파일을 보면 parameters.yml 파일을 import하여 아래 doctrine ORM에서 연동하고 있는걸 볼 수 있습니다.

  1. #app/config/config.yml
  2. imports:
  3.     - { resource: parameters.yml }
  4.     - { resource: security.yml }
  5.     - { resource: services.yml }
  6. ~~~~
  7. # Doctrine Configuration
  8. doctrine:
  9.     dbal:
  10.         driver:   pdo_mysql
  11.         host:     "%database_host%"
  12.         port:     "%database_port%"
  13.         dbname:   "%database_name%"
  14.         user:     "%database_user%"
  15.         password: "%database_password%"
  16.         charset:  UTF8
  17. ~~~~

다른  파일에서 관리하고 싶다면 해당 파일을 import 해주면 다른 디렉토리, 파일에서도 유연하게 관리 할 수  있습니다. 


PHP 템플릿 엔진 활성화

Symfony에선 템플릿 엔진으로 twig 을 기본적으로 지원해주고 있습니다. twig은 Symfony와 마찬가지로 SensioLabs에서 지원 및 개발하고 있는 템플릿 엔진으로 빠르고, 유연하고, 보안이 뛰어나고, 간결하다고 하나 아직 사용하기엔 정보가 많이 부족한게 사실이기에 우리는 PHP으로 템플릿 엔진을 사용합니다. Twig에 대해 궁금하신 분들은 공식 사이트(http://twig.sensiolabs.org )을 참고해 주세요.


config.yml파일에 PHP 엔진을 활성화 해줍니다. 간단합니다. app/config.yml 에 templateing 엔진으로 php를 작성하기만 하면 됩니다.

  1. #app/config.yml
  2. framework:
  3.    ~~~
  4.     templating:
  5.         engines: ['twig','php']
  6.     default_locale:  "%locale%"
  7.    ~~~

자, 이제 PHP 템플릿 엔진, DB연동이 완료 되었습니다. 전에도 말씀드렸듯이, 수정한 config 정보를 prod 환경에 적용하기 위해선 cache 를 clear 해야 합니다. cache를 clear 합니다.

  1. $php app/console cache:clear --env=prod

불필요한  파일 정리

불필요한 파일 정리는 깨끗한 상태에서 프로젝트를 시작함을 위한거니 굳이 하지 않으셔도 됩니다.

Symfony를 설치하면 기본적으로 설치되는 src/AppBundle, app/Resource/views/* 를 삭제합니다. 삭제를 하고 cache를 clear하면 PHP 에러가 출력됩니다. AppKernel에서 방금 삭제한 AppBundle을 찾을 수 없다는 거니 AppKernel을 열어 AppBundle을 주석 또는 삭제합니다. 그리고 routing.yml에서도  AppBundle 삭제합니다.

  1. #app/AppKernel.php
  2. $bundles = array(
  3.     new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
  4.     new Symfony\Bundle\SecurityBundle\SecurityBundle(),
  5.     new Symfony\Bundle\TwigBundle\TwigBundle(),
  6.     new Symfony\Bundle\MonologBundle\MonologBundle(),
  7.     new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
  8.     new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
  9.     new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
  10.     #new AppBundle\AppBundle(),
  11. );
  1. #app/routing.yml
  2. #app:
  3.    #resource: "@AppBundle/Controller/"
  4.    #type:     annotation

자, 다시 cache clear를 다시 진행합니다. 아무 문제 없이 clear되는걸 볼 수 있습니다.

이제 Bundle과 Controller을 생성하여 해당 Controller에  http://localhost/dolgo URL을 매칭하여 "Hello Dolgo!!"를 출력하도록 하겠습니다.


그  전에, route에 대해 간단히 설명드리자면, route는 URL과 Controller를 매칭시켜 주는 것으로 route로  URL을 구성하면 다양하고 유연하게 URL을 구성 할 수 있다는 장점이 있습니다. route 포맷으로는 Annotations, YAML, XML, PHP 를 지원하고 있으며 자세한 사항은 여기 를 참고하세요.


Bundle 생성

이제 우리가 테스트로 사용할 Bundle을 생성하도록 합니다. Symfony에서 제공하는 Console 명령을 이용하여 번들을 생성합니다.

  1. $php app/console generate:bundle

위의 명령어를 실행하면 몇가지 질문을 합니다.


1. Are you planning on sharing this bundle across multiple applications?[no] : enter

    - 2.8버전부터 추가된  것으로 생성할 번들이 다른곳에 배포 될 예정인지 질의하는 것입니다. no를 입력하면 src/밑에 Bundle이 바로 생성되고 yes로 하        게되면 src/과 Bundle 사이에 배포하는 업체? 디렉토리로 관리 할 수 있습니다. 기본인 no로 합니다.


2. Bundle Name: DolgoBundle 

    - 번들의  이름을 입력합니다.


3. Target Directory[src/]: enter

    - 번들이 생성될 디렉토리를 정의합니다. 


4 .Configuration format (annotation, yml, xml, php) [annotation]: php

    - 번들 내 config 파일의 포맷을 정의합니다. 강좌에서는 config 포맷은 모두 php이기에 php로 정의해 줍니다.


Bundle 생성이 완료되었습니다. Symfony2.8 이전 버전에서는 생성될 Bundle에 대해서 Kernel과 Routing에 자동으로 추가 할것인지에 대해서도 질의하니 yes를 입력해 주시면 됩니다. 자, src/ 하위 디렉토리를 봅시다. 우리가 테스트로 가지고 놀 DolgoBundle이 생성되어 있는걸 알 수 있습니다. Symfony에서 Bundle을 생성하면 기본적으로 Default Controller, Default Template가 설치돕니다. 하지만 우리는 하나하나 다시 재작성할 것이기에 과감히 삭제합시다.


Controller 생성

Index라는 Controller를 DolgoBundle에 생성해 보겠습니다. Bundle과 마찬가지로 Console을 이용하여 생성합니다.

  1. $php app/console generate:controller

1. Controller name: DolgoBundle:Index

    - Controller 이름을 정의합니다. Controller가 종속될 Bundle도 잊지 말고 입력해 주세요.


2. Routing format (php, xml, yml, annotation) [annotation]: php

    - route 포맷을 정의합니다. 


3. Template format (twig, php) [twig]: php

    - 템플릿 엔진을 정의합니다.


Controller 생성이 완료되었습니다. 

이제 Index Controller에  /dolgo URL을 매칭시켜줘야 합니다. 

  1. #DolgoBundle/Resources/config/routing.php
  2.  
  3. use Symfony\Component\Routing\RouteCollection;
  4. use Symfony\Component\Routing\Route;
  5.  
  6. $collection = new RouteCollection();
  7.  
  8. $collection->add('dolgo_homepage', new Route('/dolgo', array(
  9.     '_controller' => 'DolgoBundle:Index:index',
  10. )));
  11.  
  12. return $collection;

다음으로 Index Controller에 IndexAction 코드를 작성해 봅시다.

  1. #DolgoBundle/Controller/IndexController.php
  2. php
  3.  
  4. namespace DolgoBundle\Controller;
  5.  
  6. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  7. use Symfony\Component\HttpFoundation\Response;
  8.  
  9. class IndexController extends Controller
  10. {
  11.     public function indexAction()
  12.     {
  13.         echo 'Hello Dolgo!!';
  14.         return new response();
  15.     }
  16. } 

위 코드 작성 후 cache를 clear하고 http://localhost/dolgo URL로 액세스하면 "Hello Dolgo!!"가 출력되는 걸 볼 수 있습니다.

하지만, 우리가 원하는 건 Template에 렌더링 된 "Hello Dolgo!!" 를 출력시키려는 것입니다. Controller에서 정의하는 코드들은 서버단 코드인 PHP만 작성하고 html은 Template에서 정의해 봅시다.


다시, IndexAction을 재정의 합니다.

  1. #DolgoBundle/Controller/IndexController.php
  2. php
  3.  
  4. namespace DolgoBundle\Controller;
  5.  
  6. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  7. use Symfony\Component\HttpFoundation\Response;
  8.  
  9. class IndexController extends Controller
  10. {
  11.     public function indexAction()
  12.     {
  13.         return $this->render('DolgoBundle:Index:index.html.php', array());
  14.     }
  15. }

크게 달라진 건 없습니다. echo 문이 삭제되고 DolgoBundle:Index:index.html.php  파일로 렌더링한다는 게 전부입니다. Controller명 뒤의 Action은 웹에서 액세스 하는 함수라는 것으로 내부적으로 쓰신다면 굳이 Action을 쓰지 않으셔도 됩니다. 또한, Template의 파일 형식은 마지막에 꼭 엔진을 적어 주셔야 합니다. 그래야지만 Symfony에서 인식하여 에러를 토해내지 않습니다.


Template .. Template은 Resource/views/ 에 위치해야 합니다. 

Resource/views/Index/index.html.php 로 파일을 생성 후 아래 "Hello Dolgo ~ Template!!" 을 작성해 줍니다.

  1. #Resource/views/Index/index.html.php
  2. "Hello Dolgo ~ Template!!"

다시 http://localhost/dolgo에  엑세스 해봅시다

이제 템플릿 까지 렌더링 된 Hello Dolgo가 출력되어 졌습니다.!


후.. 수고 많으셨습니다.. 작성하다 보니 조금 길어졌네요.. 


감사합니다.

조회수 33.9k 등록일 2016.05.26 00:39:31

Symfony의 기본 디렉토리 구조에 대한 강좌입니다. Symfony 에서 추구하는 유연함은 디렉토리 구조에도 반영되어있습니다. 개발자는 자신이 원하는 디렉토리 구조를 설계하여 아주 쉽게 반영 할 수 있습니다. 본 강의에서는 Symfony에서 권장하는 기본 디렉토리에 대한 구조를 살펴봅니다.


아래 이미지는 Symfony에서 제공하는 권장 디렉토리 구조입니다. 크게 4개의 구조로 되어 있으며 각 디렉토리별 간단한 설명입니다.



  app/ 

    프로그램 설정과 전역에서 사용될 템플릿을 정의하는 디렉토리입니다.


  src/

    프로그램의 PHP, HTML 코드를 입력하는 디렉토리입니다.


  vendor/

     third-party에 종속되는 component들을 관리하는 디렉토리입니다. composer로        component를 설치하면 해당 디렉토리에 설치됩니다.


  web/

    웹서버 root 디렉토리이며 스크립트, css 등도 web 디렉토리에서 관리합니다.

    



app/


프로그램이 실행되면 AppKernel은 main entry point로 app/ 디렉토리에 저장되어 있는 config 파일을 불러옵니다. 

Symfony에서 기본으로 제공하는 config파일은 config_dev.yml(개발  환경), config_prod.yml(배포 환경), config_test.yml (테스트환경)을 제공하고 있으며, 개발자가 자신이 원하는 환경에 맞춘 config 파일을 만들어 load 할 수 있습니다. 각각의 환경은 url에서  액세스 합니다. 간단히 설명드리자면 http://localhost/app_dev.php 로 액세스 시에는 개발 환경, http://localhost 으로 액세스 시에는 배포 환경의 config 파일을 load하게 되며 서로 다른 환경으로 관리, 설계 할 수 있습니다. Symfony에서는 이를 프런트 컨트롤러라 망명하고 있으며 뒤에 기회가 된다면 자세히 설명드리도록 하겠습니다~ 

또한, config/ 디렉토리에는 DB 정보, framework, 클래스와 비슷하지만 조금 다른 Service, URL과 Controller를 매핑하는 routing을 정의 하고 있습니다. config/에 있는 service, routing은 전역 설정 파일이며 각각의 service, routing 은 Bundle 내에서 다시 관리 할 수 있습니다. 즉, AppKernel 에서 config/routing을 import하고 다시 config/routing에서 bundle의 routing을 import하게 됩니다. 너무 두서 없이 적었나요..? 간단하게 app/ 디렉토리는 프로그램의 설정들을 관리하는 디렉토리라고 생각하시면 됩니다.



src/


프로그램의 PHP, HTML의 코드들을 작성하는 디렉토리 입니다. src/ 디렉토리를 보시면 AppBundle이 기본적으로 설치되어 있을 것입니다. Bundle이라 하면 프로그램의 주제? 뭉치? 라고 생각하시면 됩니다. 프로젝트의 기초가 되는 스켈레톤을 설계하실 때에는 하나의 번들에서 여러 컨트롤러로 분기하도록 설계할지.. 아니면 여러개의 번들로 설계할지에 대해 고민하셔야 합니다. 소규모 프로젝트의 경우에는 하나의 번들로 구조를 잡아도 상관없겠지만 대규모 프로젝트에서는 하나의 번들보단 여러개의 번들로 설계하심을 권장드립니다. 

그리고 자체적으로 component를 작성하여 배포하실때에도 Bundle 단위로 움직이고 배포하도록 권장하고 있습니다.



vendor/


third-party 의존성 component(라이브러리)들이 설치되어 있는 디렉토리입니다. 

Symfony 프레임워크 또한 component 의 일부이기 떄문에 Symfony의 코어도 해당 디렉토리에 설치되어 있는걸 알 수 있고 그  외 SwiftMailer, Doctrine ORM, Twig 등이 기본 설치되어 있습니다. 

composer로 third-party component를 설치하시면 vendor 디렉토리에 자동 설치되며, composer에서 관리하는 디렉토리임으로 그냥 냅두시면 됩니다.



web/


웹서버의 root 디렉토리로 자바스크립트, css, image 등 정적인 파일들을 관리하는 디렉토리 입니다. 

또한 위에서 언급한 프런트 컨트롤러 파일인 app.php, app_dev.php도 web 디렉토리에서 관리합니다.

app.php

  1. #app.php
  2. php
  3. use Symfony\Component\HttpFoundation\Request;
  4.  
  5. /**
  6.  * @var Composer\Autoload\ClassLoader
  7.  */
  8. $loader = require __DIR__.'/../app/autoload.php';
  9. include_once __DIR__.'/../app/bootstrap.php.cache';
  10.  
  11. $kernel = new AppKernel('prod', false);
  12. $kernel->loadClassCache();
  13. //$kernel = new AppCache($kernel);
  14.  
  15. // When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
  16. //Request::enableHttpMethodParameterOverride();
  17. $request = Request::createFromGlobals();
  18. $response = $kernel->handle($request);
  19. $response->send();
  20. $kernel->terminate($request, $response);

웹에서 prod 환경인 app.php 프런트 컨트롤러로 액세스를 하게 되면 app.php는 AppKernel에 prod 환경으로 요청을 하게 되고 Kernel에서 응답 받은 컨텐츠를 다시 사용자에게 보여주게 됩니다.


app_dev.php


  1. #app_dev.php
  2. php
  3. use Symfony\Component\HttpFoundation\Request;
  4. use Symfony\Component\Debug\Debug;
  5.  
  6. // If you don't want to setup permissions the proper way, just uncomment the following PHP line
  7. // read http://symfony.com/doc/current/book/installation.html#checking-symfony-application-configuration-and-setup
  8. // for more information
  9. //umask(0000);
  10.  
  11. // This check prevents access to debug front controllers that are deployed by accident to production servers.
  12. // Feel free to remove this, extend it, or make something more sophisticated.
  13. if (isset($_SERVER['HTTP_CLIENT_IP'])
  14.     || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
  15.     || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
  16. ) {
  17.     header('HTTP/1.0 403 Forbidden');
  18.     exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
  19. }
  20.  
  21. /**
  22.  * @var Composer\Autoload\ClassLoader $loader
  23.  */
  24. $loader = require __DIR__.'/../app/autoload.php';
  25. Debug::enable();
  26.  
  27. $kernel = new AppKernel('dev', true);
  28. $kernel->loadClassCache();
  29. $request = Request::createFromGlobals();
  30. $response = $kernel->handle($request);
  31. $response->send();
  32. $kernel->terminate($request, $response);

웹에서 app_dev.php 프런트 컨트롤러로 요청하게 되면 dev환경으로 액세스 됩니다.  

prod와 다른 점은 debug를 namespace로 정의하여 디버깅을  위한 Debug 클래스를 사용한다는 점과 AppKernel에 dev 환경으로 요청한다는 점입니다. 그리고 dev 환경에서는 보안상의 이유로 특정 IP에 대해서만 액세스 가능하도록 설정 할 수 있다는 점입니다.



cache clear


Symfony는 프로그램의 설정을 최초 요청과 동시에 app/cache 디렉토리에 PHP 코드로 캐싱 처리하고 있습니다. dev 환경에서는 설정 정보를 변경할때마다 즉시 반영하지만 prod 환경에서는 퍼포먼스를 위해 즉시 반영해 주지 않기에 cache를 clear 해주어야 합니다. 

즉, prod 환경에서 설정을 변경하면 아래 명령어를 실행해야 반영됩니다.

  1. $php app/console cache:clear --env=prod



app/console


Symfony는 bundle, controller 생성, cache:clear 등 반복적인 작업들에 대한 생산성 향상을 위해 커맨드 툴인 console를 제공하고 있습니다.

  1. $php app/console

옵션 뒤에 --help 사용하면 각 옵션들에 대한 도움말을 볼 수 있습니다.


Symfony의 디렉토리 구조에 대한 강의가 모두 끝났습니다. 

다음 강좌는 초기 Symfony 설정과 번들, 컨트롤러를 생성하여 "Hello Dolgo!!"를 출력하는 강좌를 진행하도록 하겠습니다.

감사합니다. 

조회수 34.8k 등록일 2016.05.24 00:33:38

안녕하세요

이번 강좌는 Symfony를 각 운영체제에 설치하여 "Welcome to Symfony" 화면을 목표로 시작합니다.

Symfony 3.0 버전이 릴리즈 되었지만 본 강좌는 2019년까지 장기적으로 지원하는 Symfony2.8 버전을 기준으로 작성되었습니다.



준비 사항


  • 웹서버(Apache, Nginx 등)
  • PHP 5.3 이상
  • Mysql

Symfony2를 사용하기 위해서는 PHP 5.3 이상이 꼭 필요로 합니다.

Symfony 2.5 버전 이하에는 Composr* 를 이용하여 설치하였지만. Symfony2.5 이상 부터는 새로운 프로젝트를 구축하고 관리함에 있어 단순화 하기 위해 Symfony라는 자체 응용 프로그램을 제공하게 되었고 간단한 명령어로 Symfony를 설치 할 수 있게 되었습니다. 다만 PHP 버전 5.4 이상부터 지원하고 있으며 그 이하 버전은 Composer를 이용하여 Symfony를 설치해야 합니다.


* Composer : PHP 의존성 관리도구



Lunix 및 Max OS X에 Symfony 설치


콘솔에 아래와 같이 입력합니다.

  1. $ sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
  2. $ sudo chmod a+/usr/local/bin/symfony



Window에 Symfony 설치


  1. c:\> php -"readfile('https://symfony.com/installer');" > symfony

설치 후 프로젝트 디렉토리에 Symfony를 이동시킵니다.

  1. c:\> move symfony c:\projects
  2. c:\projects\> php symfony


위의 명령어 2~3 줄로 시스템 내 Symfony 프레임워크를 사용할 모든 준비가 끝났습니다. 

다음은 Symfony를 가지고 새로운 프로젝트를 생성해 보겠습니다.



프로젝트 생성


기본적인 프로젝트 생성 명렁어 입니다.

  1. # Linux, Mac OS X
  2. $ symfony new my_project_name
  3.  
  4. # Windows
  5. c:\> cd projects/
  6. c:\projects\> php symfony new my_project_name

위의 명령어는 my_project_name 이라는 폴더로 최근 릴리즈 버전을  기준으로 프로젝트가 생성되게 됩니다.


특정 버전으로 프로젝트를 생성하려면 아래와 같이 입력해 주세요

단지 명령어 맨 뒤 버전을 입력해 주면 됩니다.

  1. $ symfony new my_project 2.8

앞으로의 강좌는 Symofny2.8 버전으로 작성될 예정이기에 2.8 버전으로 프로젝트를 생성해 주세요.


위의 언급했듯이 PHP5.4 이하 버전에서는 Composer로 Symfony를 설치해야 합니다.

먼저 Composer가 설치되어 있어야 하며 Composer 설치는 구글링해보면 금방 나옵니다.

  1. $ composer create-project symfony/framework-standard-edition my_project_name "2.8.*"


아파치의 Document Root에 my_project_name/web 으로 경로를  잡아주시고 아파치 재시작 후 

URL에 액세스하면 Symfony의 "Hello World!!" 개념인 "Welcome to Symfony" 화면을 볼 수 있습니다.!



Symfony 설치가 완료되었습니다.

다음 강좌는 Symfony의 디렉토리 구조에 대한 강좌를 진행하겠습니다


조회수 32.9k 등록일 2016.05.22 20:38:30

안녕하세요 여러분

Symfony 프레임워크에 대해 간간히 팁을 올리려고 합니다.


Symfony는 드루팔, phpBB 등 대규모 프로젝트에 이미 사용되어 졌으며 요즘 뜨고  있는 laravel 프레임워크의 코어도 심포니로 작성되어 있습니다. 그리고 돌고넷의 서버측 언어도 Symfony로 작성된 걸로 알고 있습니다. 

즉, 이미 검증된 프레임워크로 버그 픽스 및 보안 이슈 등 지속적인 버전 릴리즈가 되고 있다는 점이 가장 큰 매력인거 같습니다. 


그리고 Symfony에 대해 궁금하신게 있으시면 Symfony 태그 게시판에 질문해 주세요~ 

항상 모니터링하고 있습니다!