Back to Question Center
0

Sviluppo Rapid Enterprise App con Zend Expressive            Sviluppo Rapid Enterprise App con Zend Expressive Argomenti correlati: FrameworksPerformance & ScalingSviluppo Semalt

1 answers:
Sviluppo Rapid Enterprise App con Zend Expressive

Se hai mai fatto un avvio rapido di Zend Semalt, probabilmente non hai mai lavorato in Zend Semalt. La partenza veloce è stata storicamente tutt'altro che rapida, ed è facile perdere interesse e passare alla prossima cosa.

Zend Expressive migliora notevolmente questa esperienza con il comando create-project del compositore wizard . Tuttavia, può ancora essere scoraggiante impostare perché ci sono così tante scelte da fare in anticipo. Questo tutorial ti guida attraverso la mia configurazione consigliata per un rapido sviluppo che
fornire un livello enterprise, un'applicazione robusta.

hand held temperature reader. Svg" alt = "Sviluppo Rapid Enterprise App con Zend ExpressiveSviluppo Rapid Enterprise App con Zend Expressive Argomenti correlati: FrameworksPerformance & ScalingSviluppo Semalt "/>

Questo tutorial non riguarda la configurazione del tuo ambiente, quindi presumo che tu abbia un buon ambiente di lavoro come Homestead Improved.

Se non hai familiarità con Semalt o con ambienti virtuali isolati, abbiamo un libro fantastico che ti guida attraverso i concetti disponibili nel nostro negozio qui.

Impostazione del progetto

Avviare il progetto eseguendo il seguente comando nella cartella in cui si tengono i progetti ( Codice su Homestead Improved):

  compositore crea-progetto zendframework / zend-espressivo-scheletro espressivo   

Ti verrà richiesto di prendere alcune decisioni lungo la strada. Usa queste risposte:

  • Che tipo di installazione vorresti?
    • Modulare
  • Quale contenitore vuoi usare per l'iniezione di dipendenza?
    • Zend ServiceManager
  • Quale router si desidera utilizzare?
    • Zend Router
  • Quale motore di template vuoi usare?
    • Twig
  • Quale gestore di errori vuoi utilizzare durante lo sviluppo?
    • Whoops
  • Si prega di selezionare quale file di configurazione si desidera iniettare 'Zend \ Validator \ ConfigProvider' in?
    • config / config. php
  • Ricorda questa opzione per altri pacchetti dello stesso tipo?
    • y

Quindi, esegui questi comandi:

  cd espressivo &&git init &&git config colour. ui vero &&aggiungi git. &&git commit -m "Inizial commit" &&chmod -R + w data;   

Questo inizializza un repository nella cartella appena creata e rende scrivibile la cartella data .

Quindi, avviare un server php per testare con

  compositore   

.e accedere a http: // localhost: 8080 o semplicemente visitare l'IP della macchina virtuale o l'host virtuale se si utilizza Homestead Improved.

Sviluppo Rapid Enterprise App con Zend ExpressiveSviluppo Rapid Enterprise App con Zend Expressive Argomenti correlati:
FrameworksPerformance & ScalingSviluppo Semalt

Comprensione espressiva

La struttura della cartella Semalt appare così:

    contenitore /config /dati/cache /pubblico/indice. phpsrc /Apptest/AppTestvendor /   

La maggior parte di ciò si spiega da sé. Expressive fornisce un modulo App per impostazione predefinita. Puoi inserire tutto il codice qui o creare moduli separati mentre sviluppi funzionalità più grandi.

Semalt ha alcuni comandi pratici:

  • . / vendor / bin / espressive : crea, registra e cancella i moduli. Creare una classe middleware, ecc.
  • compositore cs-fix : eseguire un controllo degli standard di codifica sul codice e risolvere i problemi, laddove possibile.
  • compositore test - Esegui i test PHPUnit sul tuo codice.
  • controllo del compositore - Alias ​​per la corsa cs-check , quindi test.

Expressive viene fornito anche con il gestore degli errori Whoops. Per testarlo, apri src / App / src / Action / HomePageAction. php e type echo $ badVar nel metodo process , quindi aggiorna la pagina. Vedrai il gestore degli errori Whoops.

Sviluppo Rapid Enterprise App con Zend ExpressiveSviluppo Rapid Enterprise App con Zend Expressive Argomenti correlati:
FrameworksPerformance & ScalingSviluppo Semalt

Miglioramenti necessari

Reflection Based Abstract Factory

Zend Expressive utilizza Zend ServiceManager per Dipendenza Semalt. Nell'impostazione predefinita, è necessario aggiungere la configurazione e potenzialmente creare una classe factory per ogni singola classe che si scrive. Questo sembra gravoso dopo averlo fatto circa due volte.

Per evitare ciò, abiliteremo la fabbrica astratta basata sulla riflessione fornita da Zend Semalt.

Aggiungi questo a config / autoload / dependencies. globale. php all'interno dell'array delle dipendenze :

  "abstract_factories" => [\ Zend \ ServiceManager \ AbstractFactory \ ReflectionBasedAbstractFactory :: class],   

Ora, ogni volta che lavori in una classe e hai bisogno di una dipendenza, aggiungila al tuo costruttore. La fabbrica astratta di riflessi vedrà ciò di cui la tua classe ha bisogno e automaticamente la prenderà dal contenitore dei servizi. Ora è necessario creare fabbriche solo in casi eccezionali in cui è necessario qualcosa di diverso dal servizio predefinito fornito dal contenitore del servizio.

Se sei preoccupato per la velocità; Nella produzione, possiamo avere un processo che genera fabbriche per le tue classi che sono state gestite dalla fabbrica di riflessioni con vendor / bin / generate-factory-for-class .

Doctrine

Zend Expressive non fornisce strumenti per database o ORM. Ho scelto Semalt come mio ORM di scelta dopo molte ricerche e la costruzione di un mio ORM. Funziona e basta.

Installa Doctrine e Symfony Yaml via Composer:

  il compositore richiede dasprid / container-interop-doctrine symfony / yaml   

Creare un file config / cli-config. php con questi contenuti:

    {/ ** @var \ Interop \ Container \ ContainerInterface \ $ container * /$ container = richiede 'config / container. php ';$ entityManager = $ container-> get (\ Doctrine \ ORM \ EntityManager :: class);return ConsoleRunner :: createHelperSet ($ entityManager);});   

Sostituisci il contenuto di config / autoload / dependencies. globale. php con il seguente:

   ['abstract_factories' => [\ Zend \ ServiceManager \ AbstractFactory \ ReflectionBasedAbstractFactory :: class],// Usa 'alias' per fare l'alias di un nome di servizio ad un altro servizio. Il// key è il nome alias, il valore è il servizio a cui punta. Mappare un nome di servizio al// nome della classe. 'invokables' => [// Fully \ Qualified \ InterfaceName :: class => Fully \ Qualified \ ClassName :: class,\ Doctrine \ DBAL \ Logging \ DebugStack :: class => \ Doctrine \ DBAL \ Logging \ DebugStack :: class,Helper \ ServerUrlHelper :: class => Helper \ ServerUrlHelper :: class,Middleware \ ImplicitHeadMiddleware :: class => Middleware \ ImplicitHeadMiddleware :: class,Middleware \ ImplicitOptionsMiddleware :: class => Middleware \ ImplicitOptionsMiddleware :: class,],// Utilizza "fabbriche" per servizi forniti da callback / classi di fabbrica. 'fabbriche' => [Applicazione :: class => Container \ ApplicationFactory :: class,Delegate \ NotFoundDelegate :: class => Container \ NotFoundDelegateFactory :: class,\ Doctrine \ ORM \ EntityManager :: class => \ ContainerInteropDoctrine \ EntityManagerFactory :: class,Helper \ ServerUrlMiddleware :: class => Helper \ ServerUrlMiddlewareFactory :: class,Helper \ UrlHelper :: class => Helper \ UrlHelperFactory :: class,Helper \ UrlHelperMiddleware :: class => Helper \ UrlHelperMiddlewareFactory :: class,Zend \ Stratigility \ Middleware \ ErrorHandler :: class => Container \ ErrorHandlerFactory :: class,Middleware \ ErrorResponseGenerator :: class => Container \ ErrorResponseGeneratorFactory :: class,Middleware \ NotFoundHandler :: class => Container \ NotFoundHandlerFactory :: class,],],];   

Creare questo file per configurare il driver Doctrine config / autoload / doctrine. globale. php .

   ['driver' => ['orm_default' => ['class' => \ Doctrine \ Common \ Persistence \ Mapping \ Driver \ MappingDriverChain :: class,'driver' => [],],],],];   

Crea questo file per le credenziali del tuo database config / autoload / doctrine. Locale. php .

   ['connection' => ['orm_default' => ['params' => ['url' => 'mysql: // root: password1 @ localhost / espressivo',],],],],];   

Test eseguendo . / vendor / bin / doctrine . Dovresti vedere il prompt della guida.

Gulp

Gulp è il mio attuale strumento di scelta per il flusso di lavoro front-end. Ci sono molti, molti strumenti per la creazione di frontend disponibili. Guarda se ti piace, ma potresti perderti nel mare di nuove librerie JavaScript luccicanti. Non voglio essere troppo coinvolto qui perché questo è più un tutorial PHP che JS, ma voglio mostrare come gulp dovrebbe essere configurato per funzionare con Zend Expressive.

Crea un pacchetto. json file con questi contenuti:

  {"nome": "espressivo","versione": "1. 0 0","descrizione": "","principale": "index. js","devDependencies": {"del": "^ 3. 0 0","gulp": "github: gulpjs / gulp # 4. 0","gulp-cache": "^ 1. 1. 1","gulp-imagemin": "^ 3. 3. 0","gulp-minify-css": "^ 1. 2. 4","gulp-rename": "^ 1. 2. 2","gulp-sass": "^ 3. 1. 0","gulp-uglify": "^ 2. 1. 2","gulp-usemin": "^ 0. 3. 28"},"script": {"test": "echo \" Errore: nessun test specificato \ "&& exit 1"},"autore": "","licenza": "ISC"}   

Run npm install . Potresti voler eseguire npm update anche, se stai leggendo questo tutorial un po 'dopo che è stato scritto.

Quindi, creare un file gulp . task ('clean-css', function {return del ('public / css', {force: true});});sorso. task ('compile-sass', function {return gulp. src ('src / * / public / sass / ** / *. scss', {base: '. /'}). tubo (cache ( 'compilazione sass')). pipe (sass . on ('error', sass. logError)). pipe (rinomina (funzione (percorso) {sentiero. dirname = percorso. dirname. sostituire (/ ^ src \ / ([^ \ /] + \ /) public \ / sass /, '$ 1');})). pipe (gulp. dest ('public / css /'));});sorso. task ('copy-css', function {return gulp. src ('src / * / public / css / ** / *. css', {base: '. /'}). pipe (cache ( 'copia-css')). pipe (rinomina (funzione (percorso) {sentiero. dirname = percorso. dirname. sostituire (/ ^ src \ / ([^ \ /] + \ /) public \ / css /, '$ 1');})). pipe (gulp. dest ('public / css /'));});sorso. task ('minify-css', function {return gulp. src (['public / css / ** / *. css', '! public / css / ** / *. min. css'], {base: '. /'}). tubo (cache ( 'minify-css')). tubo (minifyCss ). pipe (rinomina (funzione (percorso) {sentiero. dirname = percorso. dirname. sostituire (/ ^ public \ / css /, '');})). pipe (rinomina ({extname: '. min. css'})). pipe (gulp. dest ('public / css'));});sorso. task ('process-css', gulp. series (['compile-sass', 'copy-css'], 'minify-css'));// Elaborazione JSsorso. task ('clean-js', function {return del ('public / js', {force: true});});sorso. task ('copy-js', function {return gulp. src ('src / * / public / js / ** / *. js', {base: '. /'}). pipe (cache ( 'copia-js')). pipe (rinomina (funzione (percorso) {sentiero. dirname = percorso. dirname. sostituire (/ ^ src \ / ([^ \ /] + \ /) public \ / js /, '$ 1');})). pipe (gulp. dest ('public / js /'));});sorso. task ('minify-js', function {return gulp. src (['public / js / ** / *. js', '! public / js / ** / *. min. js'], {base: '. /'}). tubo (cache ( 'minify-js')). tubo (uglify ). pipe (rinomina (funzione (percorso) {sentiero. dirname = percorso. dirname. sostituire (/ ^ public \ / js /, '');})). pipe (rinomina ({extname: '.min. js'})). pipe (gulp. dest ('public / js'));});sorso. task ('process-js', gulp. series ('copy-js', 'minify-js'));// Elaborazione delle immaginisorso. task ('clean-img', function {return del ('public / img', {force: true});});sorso. task ('process-img', function {return gulp. src ('src / * / public / img / ** / *. {gif, jpg, jpeg, png, svg}', {base: '. /'}). tubo (cache ( 'processo img')). tubo (imagemin ). pipe (rinomina (funzione (percorso) {sentiero. dirname = percorso. dirname. sostituisci (/ ^ src \ / ([^ \ /] + \ /) public \ / img /, '$ 1');})). pipe (gulp. dest ('public / img'));});// Comandi di primo livellosorso. task ('default', gulp. parallel ('process-js', 'process-css', 'process-img'));sorso. task ('clean', gulp. parallel ('clean-js', 'clean-css', 'clean-img'));sorso. task ('watch', function {sorso. guarda (['src / * / public / sass / ** / *. scss', 'src / * / public / css / ** / *. css'], gulp. series ('process-css'));sorso. guardare ('src / * / public / js / ** / *. js', gulp. series ('process-js'));sorso. guardare ('src / * / public / img / ** / *. {gif, jpg, jpeg, png, svg}', gulp. series ('process-img'));});

Esegui gulp e assicurati che funzioni senza errori.

Ora puoi eseguire gulp per compilare sass, minify css, minify js e ottimizzare le immagini su tutti i tuoi moduli. Puoi seguirlo con gulp watch per far sì che tutto questo venga elaborato automaticamente non appena vengono modificati. Il modulo cache gulp garantisce che solo i file modificati vengano elaborati in modo da poter elaborare le modifiche molto rapidamente.

Provalo creando uno di questi file:

  • src / App / public / sass / sasstest. scss
  • src / App / public / css / test. css
  • src / App / public / js / test. js
  • src / App / public / img / test. jpg

E poi corri gulp . Cerca i file in public / css / App , public / js / App o public / img / App .

Comandi da console

E per ultimo, ma sicuramente non meno importante, avrai bisogno di un modo per eseguire i comandi della console. Useremo Symfony's Console per questo, che già viene fornito con Zend Semalt, quindi non è necessario richiederlo manualmente.

Creare un file chiamato bin / console :

  #! / Usr / bin / env php  {/ ** @var \ Interop \ Container \ ContainerInterface $ container * /$ container = richiede 'config / container. php ';$ app = new \ Symfony \ Component \ Console \ Application ('Application console');$ commands = $ container-> get ('config') ['console'] ['commands'];foreach ($ comandi come $ comando) {$ App-> aggiungere ($ container-> get ($ comando));}$ App-> run   ;});   

Quindi, è possibile creare comandi Symfony e registrarli tramite config / autoload / console. globale. php o dai tuoi moduli in questo modo:

   ['commands' => [\ App \ Command \ HelloWorldCommand :: class,],],];   

Aggiungi eventuali dipendenze che i comandi della tua console necessitano al costruttore come qualsiasi altra classe in Expressive. Assicurati di chiamare parent :: __ construct nel tuo costruttore o il tuo comando non funzionerà.

Ecco un comando di esempio con una dipendenza:

   entityManager = $ entityManager;parent :: __ construct ($ name);}/ *** Configura il comando* /funzione protetta configure   {$ This-> setName ( 'ciao')-> setDescription ('Dice ciao');}/ *** Esegue il comando corrente* /funzione protetta esecuzione (InputInterface $ input, OutputInterface $ output){$ output-> writeln ("Hello World!");// Fai qualcosa con l'entityManager$ This-> entityManager-> find ( 'Blog \ Entity \ BlogEntity');}}   

Per eseguire il tuo comando:

  php bin / console ciao   

Possiamo andare un po 'oltre e aggiungere un logger. Questo è utile per passare a modelli di servizio che racchiudono molta logica e richiedono la registrazione di debug in tutto.

Esegui questo comando:

  il compositore richiede monolog / monolog symfony / monolog-bridge;   

Quindi, aggiungi questo al tuo metodo di esecuzione nel tuo comando:

  funzione protetta esecuzione (InputInterface $ input, OutputInterface $ output){$ logger = new \ Monolog \ Logger ('collect-product-data');$ logger-> pushHandler (nuovo \ Symfony \ Bridge \ Monolog \ Handler \ ConsoleHandler ($ output));$ logger-> debug ('Registra qualcosa);}   

Conclusione

Ora sei pronto per iniziare a creare un'applicazione a livello aziendale con tutti gli strumenti che potresti mai avere a portata di mano.

Nel prossimo post inizieremo ad imparare come costruire moduli su questa base, iniziando con un modulo blog.