Tutto dovrebbe essere davvero un pacchetto in Symfony 2.x?

Sono a conoscenza di domande come questa , in cui le persone tendono a discutere del concetto generale di bundle di Symfony 2.

Il fatto è che, in un’applicazione specifica, ad esempio un’applicazione simile a Twitter, tutto dovrebbe essere veramente all’interno di un pacchetto generico, come dicono i documenti ufficiali ?

Il motivo per cui sto chiedendo questo è perché quando sviluppiamo applicazioni, in generale, non vogliamo accoppiare il nostro codice ad un framework di colla full stack.

Se sviluppo un’applicazione basata su Symfony 2 e, a un certo punto, decido che Symfony 2 non sia la scelta migliore per continuare lo sviluppo , sarà un problema per me?

Quindi la domanda generale è: perché tutto ciò che è un pacchetto è una buona cosa?

EDIT # 1

A quasi un anno da quando ho fatto questa domanda, ho scritto un articolo per condividere le mie conoscenze su questo argomento.

Ho scritto un post più completo e aggiornato su questo argomento: http://elnur.pro/symfony-without-bundles/


No, non tutto deve essere in un pacchetto. Potresti avere una struttura come questa:

  • src/Vendor/Model – per i modelli,
  • src/Vendor/Controller – per i controller,
  • src/Vendor/Service – per servizi,
  • src/Vendor/Bundle – per bundle, come src/Vendor/Bundle/AppBundle ,
  • eccetera.

In questo modo, inseriresti in AppBundle solo le cose che sono specifiche di Symfony2. Se si decide di passare a un altro framework in un secondo momento, si Bundle spazio dei nomi del Bundle e lo si sostituirà con il materiale di framework scelto.

Si prega di notare che quello che sto suggerendo qui è per codice specifico app . Per i pacchetti riutilizzabili, suggerisco comunque di utilizzare le migliori pratiche .

Mantenere le quadro fuori dai pacchetti

Per mantenere le quadro in src/Vendor/Model fuori da qualsiasi bundle, ho cambiato la sezione doctrine in config.yml da

 doctrine: # ... orm: # ... auto_mapping: true 

a

 doctrine: # ... orm: # ... mappings: model: type: annotation dir: %kernel.root_dir%/../src/Vendor/Model prefix: Vendor\Model alias: Model is_bundle: false 

I nomi delle quadro – per accedere dai repository Doctrine – iniziano con Model in questo caso, ad esempio Model:User .

È ansible utilizzare gli spazi secondari per raggruppare le quadro correlate, ad esempio, src/Vendor/User/Group.php . In questo caso, il nome dell’ quadro è Model:User\Group .

Mantenere i controller fuori dai bundle

Innanzitutto, devi dire a JMSDiExtraBundle di analizzare la cartella src per i servizi aggiungendo questo a config.yml :

 jms_di_extra: locations: directories: %kernel.root_dir%/../src 

Quindi definisci i controller come servizi e li metti sotto lo spazio dei nomi Controller :

 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 ]; } } 

Si noti che sto utilizzando il mio ElnurAbstractControllerBundle per semplificare la definizione dei controller come servizi.

L’ultima cosa che rimane è dire a Symfony di cercare modelli senza bundle. Lo faccio sovrascrivendo il servizio di ricerca dei modelli, ma poiché l’approccio è diverso tra Symfony 2.0 e 2.1, sto fornendo versioni per entrambi.

Sovrascrivere il modello indovinato di Symfony 2.1+

Ho creato un pacchetto che lo fa per te.

Override del listener di template di Symfony 2.0

Per prima cosa, definisci la class:

 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; } } } 

E poi di dire a Symfony di usarlo aggiungendo questo a config.yml :

 parameters: jms_di_extra.template_listener.class: Vendor\Listener\TemplateListener 

Utilizzo di modelli senza bundle

Ora puoi usare i modelli fuori dai pacchetti. Tenerli sotto la cartella app/Resources/views . Ad esempio, i modelli per queste due azioni dal controller di esempio sopra si trovano in:

  • app/Resources/views/User/add.html.twig
  • app/Resources/views/User/profile.html.twig

Quando fai riferimento a un modello, ometti la parte del pacchetto:

 {% include ':Controller:view.html.twig' %} 

Ovviamente puoi disaccoppiare la tua domanda. Basta svilupparlo come una libreria e integrarlo in symfony vendor/ -folder (usando i deps o il composer.json , a seconda che si usi Symfony2.0 o Symfony2.1). Tuttavia, è necessario almeno un bundle, che funge da “frontend” della libreria, in cui Symfony2 trova il controller (e così via).

Una normale distribuzione di symfony può funzionare senza bundle (applicazioni) extra, a seconda di quante funzionalità si desidera utilizzare dallo stack completo.

Ad esempio, i controller possono essere un qualsiasi chiamabile che può essere inserito in qualsiasi punto della struttura del progetto, non appena vengono caricati automaticamente.

In un file di definizione del routing, è ansible utilizzare:

 test: pattern: /test defaults: { _controller: Controller\Test::test } 

Può essere un semplice object php vecchio, solo legato al framework dal fatto che deve restituire un object Symfony\Component\HttpFoundation\Response .

I tuoi modelli di twig (o altri) possono essere messi come app/Resources/views/template.html.twig e possono essere resi utilizzando il nome logico ::template.html.twig .

Tutti i servizi DI possono essere definiti in app / config / config.yml (o importati da app/config/services.yml per esempio, e tutte le classi di servizio possono essere anche semplici oggetti php vecchi e non legati al framework.

Tutto questo è fornito di default dal framework full stack di symfony.

Dove avrai problemi è quando vorrai usare i file di traduzione (come xliff), perché vengono scoperti solo attraverso i pacchetti.

La distribuzione di symfony-light ha lo scopo di risolvere questo tipo di problemi scoprendo tutto ciò che di solito sarebbe scoperto solo attraverso i bundle.

È ansible utilizzare KnpRadBundle , che tenta di semplificare la struttura del progetto.

Un altro approccio è usare src/Company/Bundle/FrontendBundle per esempio per i bundle e src/Company/Stuff/Class.php per le classi che sono indipendenti da symfony e che potrebbero essere riutilizzate al di fuori del framework

Poiché sono già trascorsi 5 anni, ecco alcuni altri articoli su Symfony Bundles.

  1. Cosa sono i bundle in Symfony? di Iltar van der Berg.

TLDR:

Avete bisogno di più bundle nella vostra applicazione direttamente? Molto probabilmente no. Stai meglio scrivendo un AppBundle per evitare una serie di dipendenze. Puoi semplicemente seguire le migliori pratiche e funzionerà correttamente.

  1. Symfony: How to Bundle di Toni Uebernickel.

TLDR:

Crea un solo bundle chiamato AppBundle per la logica dell’applicazione. One AppBundle – ma per favore non mettere la logica dell’applicazione lì!

Il framework Symfony è molto buono per lanciare rapidamente una proof of concept e tutto il codice può entrare all’interno dell’applicazione bundle di default in src /

In questo pacchetto è ansible strutturare il codice come si desidera.

Dopo, se vuoi usare un’altra tecnologia per sviluppare il tuo POC, puoi facilmente tradurlo perché non strutturi tutto il tuo codice nella concezione del bundle.

Per tutto il concetto non lo si estremizza. Il pacchetto è buono ma raggruppa tutto e ogni giorno non va bene.

Forse puoi usare un Silex (Symfony micro framework) per sviluppare la tua Prova di Concetto per ridurre l’impatto del bundle di terze parti.