Migrare a Symfony 3: Michele ha avuto l’idea di fare questo talk dopo aver partecipato ad un workshop su questo argomento tenuto al phpsummercamp da Nicolas Grekas, sviluppatore proprio del core di Symfony.

Se hai progetti da aggiornare e non sai bene cosa ti aspetta, qui ti aiuteremo a fare un po’ di chiarezza.

Symfony 3: la (non) rivoluzione

Se qualcuno ricorda con un po’ di timore il passaggio da Symfony 1 a Symfony 2 può stare tranquillo: Symfony 3 non sarà una rivoluzione in questo senso. Questa major release è stata infatti un’occasione per fare tesoro di quanto appreso modificando vari aspetti del framework a diversi livelli:

  • architettura/api: alcune scelte si sono rivelate poco chiare e di difficile utilizzo, come ad esempio le api di validazione, la gestione delle form, i synchronized services. Queste parti sono state pesantemente riviste;
  • organizzazione del codice: il layout delle directory è stato razionalizzato, in particolare:
    • tutti i binari, comandi eseguibili da console di un’applicazione Symfony, finiscono dentro la directory bin;
    • tutti i dati generati a runtime dall’applicazione, come file di cache, log, sessioni dell’utente, il file bootstrap.php.cache saranno posizionati dentro una directory var (in style unix-like);
    • il file phpunit.xml.dist viene spostato nella root del progetto. I benefici di questi cambiamenti sono molteplici, ti rimandiamo a questa risposta su stackoverflow per i dettagli.
  • rimozione di librerie non core: assetic, anche se ancora supportato, non sarà più incluso nei pacchetti installati di default.

Molte modifiche e correzioni sono già iniziate nelle ultime versioni di Symfony e per garantire la compatiblità all’indietro il codice vecchio non è stato rimosso ma deprecato, ovvero il suo utilizzo è sconsigliato.
Tutto il codice deprecato in Symfony 3 verrà rimosso, con un piccolo vantaggio anche in termini di performance.

Parlando di modifiche che rompono la compatibilità all’indietro è stato fatto un grande lavoro per rendere la vita il più semplice possibile a chi deve fare l’upgrade delle proprie applicazioni.

Release Process

Dalla versione 2.2 è stato definito il processo per il rilascio delle nuove versioni di Symfony che si basa sul semantic versioning. Ogni versione è contrassegnata da 3 numeri, X.Y.Z, ognuno con un significato preciso:

X è la major release: un cambio di questo numero consente di rompere la compatibilità all’indietro. E’ il caso del passaggio da symfony 1 a 2, o da 2 a 3
Y è la minor release: una nuova minor release può aggiungere funzionalità ma il codice deve essere compatibile con le versioni precedenti
Z è la bugfix release: una nuova versione può sistemare bug o falle di sicurezza, anche in questo caso il codice deve essere compatibile con le versioni precedenti

Usando questa convenzione è molto semplice capire a cosa si va incontro passando da una versione all’altra. Di fatto tutti gli upgrade di una minor o bugfix release all’altra sono sicuri: puoi aggiornare senza paura di rompere qualcosa.

Symfony inoltre prevede due diverse tipologie di versione:

  • standard version: 8 mesi di bugfix e 14 mesi di security fix
  • long term support version (LTS): 3 anni di bugfix e 4 di security fix

Se sei in cerca di stabilità puoi passare da una LTS all’altra beneficiando di bugfix e security fix per un periodo molto lungo. Viceversa se ti piace essere on the edge e provare tutte le ultime feature, le standard version sono quello che fanno per te.

Ad oggi la versione 2.7 è la LTS, al momento del rilascio della versione 3 (standard) verrà anche rilasciata la versione 2.8, anch’essa LTS. La versione 3 di Symfony avrà le stesse feature della versione 2.8 ma tutto il codice deprecato verrà rimosso. Questo significa che puoi migrare alla versione 2.8 ed avere abbastanza tempo per sistemare il tuo codice prima di passare alla versione 3.

A proposito di codice deprecato

Aggiornare il software spesso viene visto come una seccatura: perché dovrei cambiare codice che funziona col rischio di romperlo? Ok, ci sono i file di upgrade ma chi li legge? Il team di Symfony ha lavorato avendo ben chiare le criticità in questo contesto ed ha trovato diverse soluzioni per rendere il più semplice possibile questo percorso. Le citiamo perché oltre ad essere interessanti si prestano ad essere riusate anche in contesti non Symfony:

trigger_error everywhere
In tutti i punti del codice che da deprecare è stata aggiunta una chiamata a trigger_error (con stato E_USER_DEPRECATED). Ogni volta che quel codice verrà utilizzato verrà lanciato un errore

123@trigger_error( ’getDefaultOptions() is deprecated since version 2.2 and will be removed in 2.3. Use setDefaultOptions() instead.’, E_USER_DEPRECATED);

Con questa semplice operazione è possibile identificare l’utilizzo di codice deprecato a runtime! Non resta che raccogliere queste informazioni, scrivendole ad esempio su file

123456set_error_handler(function($type, $msg) {  file_put_contents(    ‘./deprecated.log’,    $msg //debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS  );});

nel caso di Symfony vengono mostrate nella toolbar di sviluppo e una estensione di phpunit permette di avere le stesse informazioni mentre si fanno girare i test (perché tu fai test del codice vero???).

Allo stesso modo è stata aggiunta la possibilità di definire un servizio come deprecato direttamente nella definizione del servizio stesso:

12345<service id=”bar” class=”stdClass”>  <deprecated>    The “%service_id%” service is deprecated!  </deprecated></service>

molto comodo no? In questo caso non è nemmeno necessario mettere mano al codice. Ultima novità, uscita da qualche giorno, è un tool da linea di comando che analizza il codice rilevando le chiamate deprecate.

Ancora una volta il team di Symfony ha dimostrato di saper trovare soluzioni intelligenti che possono essere utilizzate anche al di fuori di Symfony stesso.

Come migrare

Difficile definire un percorso dettagliato su come migrare, ma alcune informazioni di alto livello possiamo fornirle

se hai una versione di Symfony precedente alla 2.3: aggiorna alla 2.3 e poi alla 2.7/2.8
se hai una versione di Symfony tra la 2.3 e la 2.6: aggiorna alla 2.7/2.8

Una volta arrivato alla versione 2.7/2.8 avrai tutti gli strumenti citati in precedenza per aggiornare il tuo codice, in modo da rimuovere l’utilizzo delle api deprecate. Fai sempre riferimento anche ai file di upgrade: si lo so che è noioso da leggere ma le informazioni che contiene sono utili!

Una volta sistemato il tuo codice potrai aggiornare i vendor e di seguito aggiornare la versione di Symfony nel composer.json

123456{ “…”: “…”, “require”: {   “symfony/symfony”: “3.0.*”, },}

forzando anche l’aggiornamento delle dipendenze

$ composer update symfony/symfony –with-dependencies

A proposito di librerie di terze parti

Ci sono bundle e librerie di terze che usiamo praticamente in ogni applicazione Symfony… qual è il loro stato? Difficile fare una lista esaustiva, le cose stanno cambiando di giorno in giorno. Sbirciando nel codice di alcuni bundle si vedono già diverse commit per rimuovere api deprecate e/o supportare le ultime versioni di Symfony: dai un’occhiata ai repository di FosRestBundle, KnpMenuBundle, LiipImagineBundle, NelmioApiDocBundle per citarne solo alcuni.

In uno slancio di ottimismo mi aspetto che per il rilascio di Symfony 2.8 / 3 i bundle più famosi siano stati aggiornati.

Arrivederci e grazie del pesce

Oltre al video allegato qui di seguito, troverai online le slide complete dell’intervento. Se non hai partecipato, ci vediamo il prossimo anno?

Flowing nasce il 19.02.2019 da ideato e extrategy, ecco perché nel video e nelle slide trovi uno di questi brand! Scopri di più sul nostro speciale percorso di co-creazione di Flowing.