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
, 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 .
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
.
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.
Ho creato un pacchetto che lo fa per te.
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
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.
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.
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.