이 안내서를 읽은 후 다음을 수행 할 수 있습니다.
https://buddy.works/guides/symfony
GitHub 계정에서 이 안내서에 사용 된 프로젝트를 포크 할 수 있습니다 : github.com/buddy-works/symfony-first-steps
Symfony 프로젝트 작성
Symfony 설치부터 시작하겠습니다 :
$ wget https://get.symfony.com/cli/installer -O - | bash
https://buddy.works/guides/images/symfony/symfony-1.mp4
다음으로 새 프로젝트를 작성하고 이름을 symfony-first-steps로 지정하십시오.
$ symfony new symfony-first-steps
https://buddy.works/guides/images/symfony/symfony-2.mp4
프로젝트의 폴더로 가서 dev 서버를 설정하여 모든 것이 잘되었는지 확인하십시오.
$ cd symfony-first-steps
$ symfony serve
https://buddy.works/guides/images/symfony/symfony-3.mp4
프로젝트는 기본 주소 127.0.1 : 8000에서 시작해야 합니다.
심포니 시작 화면
비즈니스 로직
프로젝트가 준비되었으므로 작성할 애플리케이션의 스펙을 살펴 보자. 애플리케이션은 텍스트를 승인하고 수신 된 단락에서 각 단어의 발생 횟수를 리턴해야 합니다.
PHPUnit installation
테스트 중심 개발의 명백한 부분 인 PHPUnit 설치부터 시작하십시오.
$ composer require --dev phpunit/phpunit
https://buddy.works/guides/images/symfony/symfony-4.mp4
그것이 작동하는지 확인하는 것도 분명해야 합니다.
$ bin/phpunit
https://buddy.works/guides/images/symfony/symfony-5.mp4
Writing tests
일부 설치 처리 후 테스트가 감지되지 않았다는 경고가 나타납니다. 테스트를 작성해 봅시다 :
<?php
declare(strict_types=1);
namespace App\Tests\Unit\Service;
use App\Service\WordCounter;
use PHPUnit\Framework\TestCase;
final class WordCounterTest extends TestCase
{
/**
* @dataProvider textDataProvider
*/
public function testWordCounter(string $text, array $result): void
{
self::assertEquals($result, (new WordCounter())->count($text));
}
public function textDataProvider(): \Generator
{
yield 'basic text' => ['Lorem ipsum dolor sit amet, ipsum dolor sit.', [
'Lorem' => 1,
'ipsum' => 2,
'dolor' => 2,
'sit' => 2,
'amet' => 1,
]];
yield 'leetspeak text' => ['l0r3m 1p5um d0l0r 517 4m37, 1p5um d0l0r 517.', [
'l0r3m' => 1,
'1p5um' => 2,
'd0l0r' => 2,
'517' => 2,
'4m37' => 1,
]];
yield 'ignore spaces' => ['Some text with tabs and spaces', [
'Some' => 1,
'text' => 1,
'with' => 1,
'tabs' => 1,
'and' => 1,
'spaces' => 1,
]];
}
}
현재 bin / phpunit을 실행하면 테스트가 실패하고 콘솔이 빨간색으로 표시됩니다. 당신이 해야 할 일은 단어를 세는 새로운 서비스의 구현을 추가하는 것입니다.
<?php
declare(strict_types=1);
namespace App\Service;
final class WordCounter
{
/**
* @return array<string,int>
*/
public function count(string $text): array
{
$words = explode(' ', preg_replace('/[^A-Za-z0-9?![:space:]]/', '', $text));
return array_reduce($words, function (array $counts, string $word): array {
if (trim($word) !== '') {
$counts[$word] = isset($counts[$word]) ? ++$counts[$word] : 1;
}
return $counts;
}, []);
}
}
bin/phpunit을 다시 실행하십시오. 이제 다음을 얻어야 합니다.
https://buddy.works/guides/images/symfony/symfony-6.mp4
Form development
테스트가 작동하면 이제 텍스트를 수신하고 초기 유효성 검사 후 서비스로 전송 한 다음 템플릿으로 반환하여 사용자에게 표시 할 양식을 만들 수 있습니다.
이 모든 것은 제공된 URL에서 작동하는 컨트롤러에 의해 처리됩니다 (이 경우에는 / 만). 다시 말해, 컨트롤러가 애플리케이션의 진입 점이 될 것입니다. 컨트롤러 생성부터 시작하겠습니다.
Controller
기본적으로 각 URL은 config / routes.yaml 파일에서 구성됩니다. 그러나 이 가이드의 필요에 따라 주석을 사용하면 좀 더 편리합니다. 이를 위해 추가 패키지가 필요합니다.
$ composer require annotations
https://buddy.works/guides/images/symfony/symfony-7.mp4
다음 내용으로 src/Controller/HomeController.php 파일을 새로 만듭니다 :
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
final class HomeController
{
/**
* @Route("/")
*/
public function index(): Response
{
return new Response('Word Counter');
}
}
브라우저를 새로 고치면 (http://127.0.0.1:8000/) 다음이 표시됩니다.
공식 Symfony 문서에서 컨트롤러 작성에 대한 자세한 내용을 읽을 수 있습니다.
첫 번째 비즈니스 가치가 전달되었습니다. 이제 뷰로 이동할 수 있습니다.
View
컨트롤러에서 반환 된 텍스트는 매우 간단했습니다. 그러나 실제로는 웹 사이트를 HTML로 렌더링 하는 것이 목적입니다. HTML과 PHP의 혼합을 피하기 위해 템플릿 엔진을 사용합니다. Symfony의 기본 템플릿 엔진은 Twig입니다.
콘솔에서 다음을 입력하십시오.
$ composer require twig
https://buddy.works/guides/images/symfony/symfony-8.mp4
그런 다음 템플릿 폴더에 새보기를 만듭니다 (Twig에서 자동으로 생성 함). 다음 내용으로 새로운 파일 templates / home.html.twig를 추가하십시오.
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col">
<h1>Word Counter</h1>
<p>Count unique words in given text.</p>
</div>
</div>
</div>
{% endblock %}
준비된 부트 스트랩 구성 요소를 사용하고 있습니다. 양식을 작성하는 동안 나중에 부트 스트랩을 추가해야 합니다.
지금은 컨트롤러를 약간 수정해야 합니다. 전체 프로세스를 보다 쉽게 하기 위해 AbstractController 클래스를 상속하고 render 메소드를 사용하여 뷰를 생성합니다. 변경 후 전체 내용은 다음과 같습니다.
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
final class HomeController extends AbstractController
{
/**
* @Route("/")
*/
public function index(): Response
{
return $this->render('home.html.twig');
}
}
웹 사이트는 다음과 같습니다 :
Form
이제 사용자 데이터를 수신하고 유효성을 검사 한 후 워드 카운팅 서비스에 전달할 수 있는 양식을 추가합니다.
Symfony 양식 작업시 권장되는 워크 플로우는 다음과 같습니다.
폼으로 패키지를 가져 오는 것으로 시작해 봅시다 :
composer require symfony/form
https://buddy.works/guides/images/symfony/symfony-8.mp4
Symfony는 컨트롤러에 가능한 한 적은 로직을 넣을 것을 권장합니다. 따라서 컨트롤러 양식에서 복잡한 양식을 정의하는 대신 복잡한 양식을 전용 클래스로 옮기는 것이 좋습니다. 또한 클래스에 정의 된 양식을 여러 작업 및 서비스에서 재사용 할 수 있습니다.
따라서 src/Form/Type/CountWordType.php 파일에서 다음 형식을 작성해야 합니다.
<?php
declare(strict_types=1);
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
final class CountWordType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('text', TextareaType::class, ['label' => 'Text to count'])
->add('submit', SubmitType::class, ['label' => 'Count words'])
;
}
}
이제 부트 스트랩을 추가하여 폼을 멋지게 렌더링 할 수 있으며, 예전처럼 벽돌로 애플리케이션 브릭을 구축 할 수 있습니다.
templates / home.html.twig 파일에서 Bootstrap에 필요한 스타일과 JavaScript를 추가하십시오.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
{% endblock %}
</body>
</html>
이제 새로 만든 양식 CountWordType을 기본 사이트의 템플릿에 삽입 할 차례입니다. 먼저 컨트롤러에서 생성해야 합니다. 인덱스 작업은 다음과 같습니다.
public function index(): Response
{
$form = $this->createForm(CountWordType::class);
return $this->render('home.html.twig', [
'form' => $form->createView(),
]);
}
양식을 템플릿에 삽입하려면 첫 번째 단락 바로 아래에 {{form (form)}}을 추가하면 됩니다.
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col">
<h1>Word Counter</h1>
<p>Count unique words in given text.</p>
{{ form(form) }}
</div>
</div>
</div>
{% endblock %}
이제 웹 사이트는 다음과 같아야 합니다.
다음 단계는 컨트롤러에 폼 지원을 추가하는 것입니다. 샘플 양식을 텍스트로 채우고 단어 개수 버튼을 클릭하면 새로운 요청이 응용 프로그램으로 전송됩니다. Symfony 양식을 사용하면 간단한 handleRequest 메소드로 처리 할 수 있습니다.
public function index(Request $request): Response
{
$form = $this->createForm(CountWordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->render('home.html.twig', [
'results' => $this->wordCounter->count($form->get('text')->getData()),
'form' => $form->createView(),
]);
}
return $this->render('home.html.twig', [
'form' => $form->createView(),
]);
}
보시다시피, 양식이 제출되었고 $ form-> isSubmitted() && $ form-> isValid () 인 경우 서비스 결과는 보기로 반환됩니다.
'results' => $this->wordCounter->count($form->get('text')->getData())
이제 이전에 만든 템플릿을 사용하여 결과 만 표시하면 됩니다.
{% block body %}
<div class="container">
<div class="row">
<div class="col">
<h1>Word Counter</h1>
<p>Count unique words in given text.</p>
{% if results is defined %}
<h2>Results:</h2>
<ul style="column-count: 4;">
{% for word, count in results|sort|reverse %}
<li>{{ word }}: {{ count }}</li>
{% endfor %}
</ul>
{% endif %}
{{ form(form) }}
</div>
</div>
</div>
{% endblock %}
Continuous Integration
이 섹션에서는 프로세스에 지속적인 통합을 구현할 수 있는 파이프 라인을 준비합니다.
파이프 라인 자체는 Continuous Integration이 아니라는 점을 상기 할 가치가 있습니다. 지속적인 통합은 여러 개발자가 수행 한 작업 결과를 가능한 한 자주 공유 된 주요 코드 라인에 병합하는 기술입니다.
결과를 병합하려면 일련의 요소가 충족되어야 합니다.
올바르게 구성된 파이프 라인을 통해 이러한 모든 사항을 보장 할 수 있습니다.
Composer script
파이프 라인을 구성하기 전에 몇 가지 Composer 스크립트를 준비하겠습니다. composer.json 파일의“스크립트”섹션에서 다음을 추가하십시오.
"phpunit": [
"bin/phpunit --colors=always"
],
"tests": [
"@phpunit"
]
이런 식으로 테스트 스크립트를 변경하지 않고 추가 도구 (예 : PHPStan 또는 PHP CS Fixer)를위한 공간을 남겨 둡니다.
composer tests
Testing pipeline
이 단계에서 코드를 커밋하고 리포지토리로 푸시 할 수 있습니다. Buddy에서 새 프로젝트를 만들고 Symfony 웹 사이트에서 repo를 첨부하십시오.
버디에 새로운 Symfony 프로젝트 추가
프로젝트가 없다면 GitHub 계정에서 작동하는 응용 프로그램을 사용할 수 있습니다.
새 파이프 라인 추가를 클릭하고 이름 (예 : "test")을 입력 한 후 트리거 모드를 On push로 설정하십시오. 드롭 다운에서 지점 별 와일드 카드 옵션을 선택하고 옆에 refs / *를 입력하십시오. 이러한 방식으로 새로 푸시 된 모든 변경에 대해 파이프 라인이 트리거됩니다.
Pipeline configuration
파이프 라인이 정의되면 PHP 액션을 추가 할 수 있습니다.
PHP in the action roster
PHP 액션은 사전 설치된 PHP와 Buddy가 코드에서 작업과 명령을 실행하는 종속성이 있는 격리 된 컨테이너입니다.
명령 상자에 다음을 추가하십시오.
composer validate
composer install
composer tests
PHP action configuration
이러한 방식으로 준비된 파이프 라인은 Continuous Integration 원칙에 따라 리포지토리에 대한 모든 푸시에 대해 코드를 테스트합니다. 응용 프로그램을 프로덕션에 출시 할 시간입니다! ?
Continuous Delivery
이 안내서의 목적 상 AWS Elastic Beanstalk를 사용하여 고객에게 애플리케이션을 제공합니다. 원하는 경우 작업을 Google App Engine, Heroku 또는 Azure App Service와 같은 다른 호스팅 서비스와 교체 할 수 있습니다.
Deployment pipeline
배포에 중점을 둔 다른 파이프 라인을 추가하겠습니다. 이름을 "배포"로 설정하고 소스 분기로 마스터를 선택하십시오. 예기치 않은 문제가 발생하지 않도록 트리거 모드를 수동으로 설정하십시오.
Deployment pipeline configuration
이제 Amazon 작업 명단에서 Elastic Beanstalk 작업을 찾습니다.
AWS action roster
통합을 정의하라는 메시지가 표시됩니다. Buddy를 신뢰할 수 있는 타사로 만들거나 역할을 가정하여 키를 사용하여 수행 할 수 있습니다.
AWS integration config
AWS 리전을 선택하고 애플리케이션 목록에서 애플리케이션 생성을 선택하십시오.
Creating new application from the AWS EB action
AWS 콘솔에서 새 EBS 애플리케이션을 생성하고 이름을 "word counter"로 지정하십시오.
Creating a new EBS app in the the AWS console
버디로 돌아가서 응용 프로그램 목록을 새로 고칩니다. 배포 대상으로 "워드 카운터"를 선택하십시오.
Selecting deployment destination in the EB action
버디의 멋진 기능은 워크 플로와 관련된 작업을 제안한다는 것입니다. 다시 말해 Elastic Beanstalk에 배포를 추가하면 Buddy는 EB 서비스에 대한 모니터링 작업 추가를 제안합니다.
Pipeline action suggestion
다시 한 번, 지역, 응용 프로그램 및 환경을 선택해야 합니다.
배포 후 응용 프로그램이 제대로 작동하고 실행 중인지 100 % 확신 할 수 있도록 노란색으로 실패한 경우 옵션을 확인하십시오. 또한 5 분 이상 준비 될 때까지 대기를 설정하는 것이 좋습니다. 이렇게 하면 전체 배포가 완료된 후에 만 상태 확인이 수행됩니다.
배포 파이프 라인은 다음과 같습니다.
AWS EB deployment pipeline
파이프 라인을 실행하려면 실행 버튼을 클릭하십시오. 버디는 최신 버전의 애플리케이션을 가져 와서 Elastic Beanstalk에 배포하고 배포 후 상태 확인을 실행합니다.
Post-deployment execution screen
이제 AWS 보드에서 애플리케이션을 사용할 수 있습니다.
EBS environment
첫 번째 배포 후 앱이 아직 제대로 작동하지 않습니다. 웹 서버의 기본 위치를 표시하여 EBS 환경을 구성해야 합니다. 애플리케이션 환경 설정의 소프트웨어 섹션을 수정하여 AWS 콘솔에서 이를 수행 할 수 있습니다. 문서 루트 필드에 / public을 값으로 입력하십시오.
EBS configuration
이제 AWS가 구성을 서버에 업로드 할 때까지 약간 기다려야 하며 완전히 작동하는 애플리케이션을 즐길 수 있습니다! ?
A fully deployed Word Counter application
파이프 라인 설정에 웹 사이트 주소를 입력하여 Buddy에서 직접 열 수 있습니다.
Towards Continuous Deployment
마지막 단계는 두 파이프 라인을 하나의 CI / CD 에코 시스템으로 결합하는 것입니다. 이를 위해 테스트 파이프 라인에서 배포를 트리거 하는 추가 작업을 사용합니다. PHP로 파이프 라인으로 이동하고 끝에 다른 파이프 라인 실행 조치를 추가하십시오.
Run next pipeline action
기억 하듯이 테스트는 프로젝트의 모든 분기에 대해 실행됩니다. 그러나 배포는 마스터 브랜치로만 제한되므로 다른 브랜치에 대한 푸시를 위해 트리거를 트리거 할 필요가 없습니다. 따라서 테스트가 마스터 브랜치에서 성공적으로 실행 된 경우에만 작업을 실행하는 트리거 조건을 적용해야 합니다.
Trigger condition configuration
이러한 방식으로 완전 자동 배포 파이프 라인을 구축 할 수 있었습니다. 코드가 마스터 분기로 푸시 될 때마다 (예 : 병합 요청을 수락 한 결과) 테스트 됩니다. 모든 테스트가 올바르게 통과하면 응용 프로그램을 프로덕션에 배포하는 다른 파이프 라인이 시작됩니다. 보시다시피 코드를 푸시하는 순간부터 모든 것이 자동으로 발생합니다. 이런 종류의 배달 프로세스를 사용하는 것을 연속 배포라고 합니다.
지속적인 배포와 달리 연속 배포의 프로덕션 배포는 완전 자동입니다. 모든 개발 단계에서 단위, 통합 및 엔드 투 엔드 테스트로 철저히 다루어 진 100 % 안정적인 DEV> STAGE> PRODUCTION 환경을 실행하지 않는 한 대규모 프로젝트에는 이러한 종류의 워크 플로를 권장하지 않습니다.
보너스 : 조건부 알림
버디의 또 다른 멋진 기능은 조건부 알림입니다. 예를 들어, 테스트가 실패한 경우 QA 팀에 메시지를 보내거나 배포 중에 문제가 있음을 DevOps 팀에 알리는 Slack 또는 Discord와 같은 메시징 서비스를 추가 할 수 있습니다. 이러한 접근 방식을 통해 관련 없는 정보가 넘치지 않도록 보호하고 필요한 경우 팀이 신속하게 조치를 취할 수 있습니다.
파이프 라인이 실패 할 때마다 알림을 보내려면 기본 작업 바로 아래에서 실패시 실행되는 작업에 알림을 추가하십시오.
Pipeline with conditional notification
요약
가이드를 읽어 주셔서 감사합니다. 모든 것이 예상대로 작동하기를 바랍니다. ? 의견이나 의견이 있으면 언제든지 의견을 남기거나 라이브 채팅을 통해 문의하십시오. 지원 팀은 배포 문제를 해결하거나 배포 문제를 디버깅 할 때 항상 매우 반응이 좋습니다. 아래에는 PHP 워크 플로우를 최적화 하는 데 도움이 되는 추가 리소스가 있습니다 (버디에 대해 조금 더 배우십시오).
등록된 댓글이 없습니다.