Symfony 2.x에서 모든 것이 실제로 번들이어야합니까?
사람들이 일반적인 Symfony 2 번들 개념에 대해 토론하는 경향 이 있는 이와 같은 질문을 알고 있습니다.
예를 들어 트위터와 같은 응용 프로그램과 같은 특정 응용 프로그램에서는 공식 문서 와 같이 모든 것이 일반 번들 안에 있어야 합니까?
내가 묻는 이유는 일반적으로 응용 프로그램을 개발할 때 코드를 풀 스택 접착제 프레임 워크에 강력하게 연결하고 싶지 않기 때문입니다.
Symfony 2 기반 응용 프로그램을 개발하고 어느 시점에서 Symfony 2가 개발 을 계속 진행 하는 최선의 선택이 아니라고 결정 하면 문제가 될까요?
일반적인 질문은 왜 모든 것이 번들이되는 것입니까?
편집 # 1
이 질문을 한 지 거의 1 년이 지난 지금 이 주제에 대한 지식을 공유 하는 기사 를 썼습니다 .
이 주제에 대해 더 철저하고 업데이트 된 블로그 게시물을 작성했습니다 : http://elnur.pro/symfony-without-bundles/
아니요, 모든 것이 번들로 제공 될 필요는 없습니다. 다음과 같은 구조를 가질 수 있습니다.
src/Vendor/Model
— 모델의 경우src/Vendor/Controller
— 컨트롤러 용src/Vendor/Service
— 서비스,src/Vendor/Bundle
—와 같은 번들의src/Vendor/Bundle/AppBundle
경우- 기타
이런 식으로, 당신 AppBundle
은 실제로 Symfony2에만 해당되는 것들을 넣을 것입니다. 나중에 다른 프레임 워크로 전환하기로 결정한 경우 Bundle
네임 스페이스를 제거 하고 선택한 프레임 워크로 바꿉니다.
여기서 제안하는 것은 앱 특정 코드를 위한 것 입니다. 재사용 가능한 번들의 경우 여전히 모범 사례를 사용 하는 것이 좋습니다 .
엔티티를 번들에서 제외
엔티티를 src/Vendor/Model
번들 외부에 유지하기 위해 doctrine
섹션 config.yml
을
doctrine:
# ...
orm:
# ...
auto_mapping: true
에
doctrine:
# ...
orm:
# ...
mappings:
model:
type: annotation
dir: %kernel.root_dir%/../src/Vendor/Model
prefix: Vendor\Model
alias: Model
is_bundle: false
Doctrine 리포지토리에서 액세스 할 수있는 엔터티 이름 Model
은이 경우로 시작 합니다 (예 :) Model:User
.
하위 네임 스페이스를 사용하여 관련 엔터티를 함께 그룹화 할 수 있습니다 (예 :) src/Vendor/User/Group.php
. 이 경우 엔터티 이름은 Model:User\Group
입니다.
컨트롤러를 번들에서 제외
먼저 다음을 추가하여 JMSDiExtraBundlesrc
에 서비스 의 폴더 를 스캔하도록 지시 해야 합니다 config.yml
.
jms_di_extra:
locations:
directories: %kernel.root_dir%/../src
그런 다음 컨트롤러를 서비스로 정의 하고 Controller
네임 스페이스 아래에 배치하십시오 .
<?php
namespace Vendor\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\SecurityExtraBundle\Annotation\Secure;
use Elnur\AbstractControllerBundle\AbstractController;
use Vendor\Service\UserService;
use Vendor\Model\User;
/**
* @Service("user_controller", parent="elnur.controller.abstract")
* @Route(service="user_controller")
*/
class UserController extends AbstractController
{
/**
* @var UserService
*/
private $userService;
/**
* @InjectParams
*
* @param UserService $userService
*/
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
/**
* @Route("/user/add", name="user.add")
* @Template
* @Secure("ROLE_ADMIN")
*
* @param Request $request
* @return array
*/
public function addAction(Request $request)
{
$user = new User;
$form = $this->formFactory->create('user', $user);
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$this->userService->save($user);
$request->getSession()->getFlashBag()->add('success', 'user.add.success');
return new RedirectResponse($this->router->generate('user.list'));
}
}
return ['form' => $form->createView()];
}
/**
* @Route("/user/profile", name="user.profile")
* @Template
* @Secure("ROLE_USER")
*
* @param Request $request
* @return array
*/
public function profileAction(Request $request)
{
$user = $this->getCurrentUser();
$form = $this->formFactory->create('user_profile', $user);
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$this->userService->save($user);
$request->getSession()->getFlashBag()->add('success', 'user.profile.edit.success');
return new RedirectResponse($this->router->generate('user.view', [
'username' => $user->getUsername()
]));
}
}
return [
'form' => $form->createView(),
'user' => $user
];
}
}
컨트롤러를 서비스로 정의하는 것을 단순화하기 위해 ElnurAbstractControllerBundle 을 사용 하고 있습니다.
마지막으로 남은 것은 번들없이 템플릿을 찾도록 Symfony에 알리는 것입니다. 템플릿 추측 서비스를 재정 의하여이 작업을 수행하지만 Symfony 2.0과 2.1의 접근 방식이 다르므로 두 가지 버전을 모두 제공하고 있습니다.
Symfony 2.1 이상 템플릿 추측 자 재정의
나는 당신을 위해 번들 을 만들었습니다 .
Symfony 2.0 템플리트 리스너 대체
먼저 클래스를 정의하십시오.
<?php
namespace Vendor\Listener;
use InvalidArgumentException;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener as FrameworkExtraTemplateListener;
use JMS\DiExtraBundle\Annotation\Service;
class TemplateListener extends FrameworkExtraTemplateListener
{
/**
* @param array $controller
* @param Request $request
* @param string $engine
* @throws InvalidArgumentException
* @return TemplateReference
*/
public function guessTemplateName($controller, Request $request, $engine = 'twig')
{
if (!preg_match('/Controller\\\(.+)Controller$/', get_class($controller[0]), $matchController)) {
throw new InvalidArgumentException(sprintf('The "%s" class does not look like a controller class (it must be in a "Controller" sub-namespace and the class name must end with "Controller")', get_class($controller[0])));
}
if (!preg_match('/^(.+)Action$/', $controller[1], $matchAction)) {
throw new InvalidArgumentException(sprintf('The "%s" method does not look like an action method (it does not end with Action)', $controller[1]));
}
$bundle = $this->getBundleForClass(get_class($controller[0]));
return new TemplateReference(
$bundle ? $bundle->getName() : null,
$matchController[1],
$matchAction[1],
$request->getRequestFormat(),
$engine
);
}
/**
* @param string $class
* @return Bundle
*/
protected function getBundleForClass($class)
{
try {
return parent::getBundleForClass($class);
} catch (InvalidArgumentException $e) {
return null;
}
}
}
그리고 Symfony에게 다음을 추가하여 사용하도록 지시하십시오 config.yml
.
parameters:
jms_di_extra.template_listener.class: Vendor\Listener\TemplateListener
번들없이 템플릿 사용
Now, you can use templates out of bundles. Keep them under the app/Resources/views
folder. For example, templates for those two actions from the example controller above are located in:
app/Resources/views/User/add.html.twig
app/Resources/views/User/profile.html.twig
When referring to a template, just omit the bundle part:
{% include ':Controller:view.html.twig' %}
Of course you can decouple your application. Just develop it as a library and integrate it into symfony vendor/
-folder (either by using the deps
or composer.json
, depending wether you use Symfony2.0 or Symfony2.1). However, you need at least one bundle, that acts as the "frontend" of your library, where Symfony2 finds the controller (and such).
A usual symfony distribution can work without any extra (application) bundle, depending on how much functionalities you want to use from the full stack framework.
For example, your controllers can be any callable that can be put anywhere in your project structure, as soon as they are autoloaded.
In a routing definition file, you can use:
test:
pattern: /test
defaults: { _controller: Controller\Test::test }
It can be any plain old php object, only tied to the framework by the fact it has to return a Symfony\Component\HttpFoundation\Response
object.
Your twig templates (or others) can be put like app/Resources/views/template.html.twig
and can be rendered using the ::template.html.twig
logical name.
All DI services can be defined in app/config/config.yml (or imported from app/config/services.yml
for example, and all service classes can be any plain old php objects too. not tied to the framework at all.
All of this is provided by default by the symfony full stack framework.
Where you will have problems is when you will want to use translation files (like xliff), because they are discovered through bundles only.
The symfony-light distribution aims to solve these kind of problems by discovering everything that would be usually discovered only through bundles.
You could use KnpRadBundle, which tries to simplify the project structure.
Another approach is to use src/Company/Bundle/FrontendBundle
for example for the bundles and src/Company/Stuff/Class.php
for the classes that are symfony independent and that could be reused outside of the framework
Since it's 5 years already passed, here are few more articles about Symfony Bundles.
- What are Bundles in Symfony? by Iltar van der Berg.
TLDR:
Do you need multiple bundles in your application directly? Most likely not. You're better off writing an AppBundle to prevent a spaghetti of dependencies. You can simply follow the best practices and it will work fine.
- Symfony: How to Bundle by Toni Uebernickel.
TLDR:
Create only one bundle called AppBundle for your application logic. One AppBundle - but please do not put your application logic in there!
Symfony framework is very good for quickly launch a proof of concept and all the code can enter within the default bundle application in src/
In this bundle you can structure your code as you want.
After if you want to use other technology for develop your POC you can easily translate that because you don't structure all your code in bundle conception.
For all of concept you don't extremismed this. Bundle is good but bundle everything and everyday is not good.
Perhaps you can use a Silex (Symfony micro framework) for develop your Proof of Concept for reduce impact of bundle third-party.
참고URL : https://stackoverflow.com/questions/9999433/should-everything-really-be-a-bundle-in-symfony-2-x
'Programing' 카테고리의 다른 글
Optional.ofNullable보다 Optional.of를 사용하는 이유는 무엇입니까? (0) | 2020.05.08 |
---|---|
Java에서 객체의 메모리 소비는 얼마입니까? (0) | 2020.05.07 |
자식 요소에 영향을주지 않고 배경 이미지의 불투명도 설정 (0) | 2020.05.07 |
여러 자식 리포지토리 결합 (0) | 2020.05.07 |
Visual Basic 6.0과 VBA의 차이점 (0) | 2020.05.07 |