मैंने इस विषय पर अधिक गहन और अद्यतन ब्लॉग पोस्ट लिखी है: http://elnur.pro/symfony-without-fundun/
नहीं, सब कुछ एक बंडल में नहीं होना चाहिए। आपके पास इस तरह की संरचना हो सकती है:
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
संस्थाओं के नाम - डॉक्ट्रिन रिपॉजिटरी से एक्सेस करने के लिए - Model
इस मामले में शुरू करते हैं , उदाहरण के लिए Model:User
,।
आप समूह से संबंधित संस्थाओं को एक साथ उप-नाम का उपयोग कर सकते हैं, उदाहरण के लिए src/Vendor/User/Group.php
,। इस स्थिति में, इकाई का नाम है Model:User\Group
।
नियंत्रकों को बंडलों से बाहर रखना
सबसे पहले, आपको JMSDiExtraBundle को src
यह कहते हुए सेवाओं के लिए फ़ोल्डर को स्कैन करना होगा 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 का उपयोग कर रहा हूं ।
आखिरी बात यह है कि सिम्फनी को बंडलों के बिना टेम्पलेट्स की तलाश करने के लिए कहना है। मैं टेम्पलेट अनुमानक सेवा को ओवरराइड करके ऐसा करता हूं, लेकिन चूंकि सिम्फनी 2.0 और 2.1 के बीच दृष्टिकोण अलग है, मैं उन दोनों के लिए संस्करण प्रदान कर रहा हूं।
सिम्फनी 2.1+ टेम्प्लेट अनुमानक को ओवरराइड करना
मैंने एक बंडल बनाया है जो आपके लिए करता है।
सिम्फनी 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;
}
}
}
और फिर सिम्फनी को इसे जोड़कर इसका उपयोग करने के लिए कहें config.yml
:
parameters:
jms_di_extra.template_listener.class: Vendor\Listener\TemplateListener
बंडलों के बिना टेम्पलेट्स का उपयोग करना
अब, आप बंडलों में से टेम्पलेट्स का उपयोग कर सकते हैं। उन्हें app/Resources/views
फोल्डर के नीचे रखें । उदाहरण के लिए, ऊपर दिए गए उदाहरण नियंत्रक से उन दो कार्यों के लिए टेम्प्लेट स्थित हैं:
app/Resources/views/User/add.html.twig
app/Resources/views/User/profile.html.twig
एक टेम्पलेट का जिक्र करते समय, बंडल भाग को छोड़ दें:
{% include ':Controller:view.html.twig' %}