Home / Blog / -

Laravel: cos’è, a cosa serve e perché usarlo?

di Matteo Merlotti

Laravel è un web application framework attivo dal 2011 basato su PHP, open-source, attivamente supportato da una grande community e arrivato ormai alla versione 10 nel momento in cui questo articolo viene scritto. Ma partiamo dalle basi: cos’è un framework?

Generalmente parlando, un web framework è un insieme di librerie che vanno a definire un flusso di sviluppo (più o meno vincolato in base al framework di riferimento) per le principali funzionalità web come routing, database, template, gestione delle sessioni, ecc.

Perché utilizzare un framework?

All’inizio della carriera della maggior parte degli sviluppatori (me compreso), una volta raggiunto un certo livello di esperienza con un linguaggio, non è atipico ritrovarsi a pensare:

Che senso ha “vincolarsi” ad un framework e spendere tempo a studiarne le funzionalità quando posso scrivere codice da zero? Dopotutto ho raggiunto un certo livello di esperienza e posso riprodurre tutte le funzionalità che mi servono.

Scrivere un framework da zero per capire di più quelli che si usano? Ottimo!
Farlo per un progetto in produzione di un cliente? Sconsigliatissimo. Vediamo perché.

Senza un framework, iniziando un nuovo progetto bisogna scrivere TUTTO. Da come gestire le route, alle funzioni di CRUD per il database, alla gestione delle sessioni e decine di altre cose. Certo, c’è la possibilità che abbiate già qualcosa in piedi da un progetto precedente da riutilizzare ma molto probabilmente è verticalizzato alle necessita del vecchio progetto e non è stato pensato per essere facilmente estendibile.

Nel caso invece pensiate di utilizzare delle librerie, dovete preoccuparvi della loro compatibilità e delle eventuali funzioni deprecate nelle versioni future.

Un framework invece pensa a tutto questo per voi. Vi fornisce delle funzioni e un flusso che andrete ad utilizzare indipendentemente dalle modifiche che gli sviluppatori faranno al codice sorgente per risolvere bug o problemi di compatibilità. Senza contare che tutte le funzionalità sono state testate da buona parte della community in una fase alpha prima che il framework venga rilasciato in produzione, così da essere sicuri di non ricevere sorprese.

Inoltre, andando ad utilizzare un framework per come è stato pensato, la necessità di scrivere commenti per rendere agevole la lettura del vostro codice ad altri sviluppatori si riduce il minimo, andando a concentrarsi solo nelle funzioni specifiche dell’architettura del vostro progetto. Tutto il resto è già presente nella documentazione del framework.

» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «

Perché proprio Laravel

La scelta di quale framework scegliere è soggettiva. Tuttavia, posso portarvi la mia esperienza personale. Avendone provati una gran parte e sopratutto utilizzando Laravel attivamente ogni giorno anche per progetti di grandi dimensioni, posso dire che sia il migliore per quanto riguarda curva d’apprendimento, supporto degli sviluppatori, community, estensioni e performance.

Inoltre, ho perso il conto di quante volte davanti ad una funzionalità richiesta all’ultimo momento dal cliente ho poi scoperto che Laravel aveva un modo per gestirla o esisteva una libreria dedicata compatibile.

È un progressive framework

Gli stessi sviluppatori lo definiscono tale e intendono che Laravel cresce con voi.

Serve pochissima esperienza per costruire un sito web base e potrete inserire funzionalità complesse solo quando ne avrete bisogno. Per questo Laravel è pieno di guide ufficiali e documentazioni per supportarvi al bisogno

È un framework scalabile

Laravel è incredibilmente scalabile. Grazie alla natura di php che aiuta questo aspetto e al supporto nativo di Laravel per una un sistema di cacheing veloce e distribuito come Redis, lo scaling orizzontale di Laravel è facilissimo.
Infatti, ci sono applicazioni scritte in Laravel che gestiscono centinaia di milioni di richieste mensili.

È un community Framework

Laravel combina le migliori librerie PHP nell’ecosistema per offrire il framework più robusto e developer-friendly in circolazione. Oltre a questo, migliaia di sviluppatori nel mondo hanno contribuito a migliorarlo o a scrivere librerie

» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «

Sì, ma come funziona Laravel?

Per spiegare nel dettaglio questa parte servirebbero conoscenze che esulano dallo scopo di questo articolo, ma possiamo riassumere le funzionalità generali nei seguenti macro punti.

Facilmente installabile

Anche Laravel come moltissimi altri framework utilizza composer per gestire l’installazione, l’upgrade e l’aggiunta di librerie. Una volta scelto dove installare il vostro progetto, vi basterà lanciare da terminale composer create-project laravel/laravel nomeprogetto e avrete dopo pochi istanti tutto pronto dentro la cartella “nomeprogetto” creata da composer.

Avete bisogno di aggiungere una libreria? vi basterà lanciare da terminale il comando composer require nomelibreria per trovarla installata e subito utilizzabile.

Unico entry point

Uno dei punti fondamentali del funzionamento della maggior parte dei framework si basa sul fatto che tutte le richieste fatte al server sono convogliate in unico punto dove vengono poi smistate in base alla necessità.
In pratica, ogni richiesta viene convogliata in un’unica pagina index.php dove viene elaborata. Successivamente vengono poi chiamate le funzioni specifiche in base al tipo di richiesta.

Prendiamo come esempio queste 3 pagine di un sito:

  • sitoweb.com/home
  • sitoweb.com/contatti
  • sitoweb.com/chi-siamo

in una struttura classica, avremo la root del nostro dominio con 3 cartelle (home, contatti, chi-siamo) con all’interno di ognuna un file denominato index.php, il quale includerà eventualmente altri file necessari e avrà i dati che ci servono per mostrare la grafica della pagina richiesta.

In un framework come Laravel invece, non serve creare ogni cartella ma basta specificare nell’elenco delle routes la risposta che volgiamo restituire, che sia una pagina, un file, o una struttura JSON di un’API. Ad esempio, la struttura per le pagine sopra sarebbe:

// file routes/web.php

Route::get('home', function(){
	return view('home');
});

Route::get('contatti', function(){
	return view('contatti');
});

Route::get('chi-siamo', function(){
	return view('chi-siamo');
});

In sostanza quando Laravel riceverà una richiesta dal browser, ad esempio *sitoweb.com/contatti*, guarderà nel file sopra, troverà che l’url richiesto corrisponde alla seconda route e chiamerà quindi la funzione corrispondente. Per il momento vi basta sapere che la funzione view non fa altro che recuperare un file di template nella cartella resources/views.

Questo sistema agevolerà tantissimi casi di integrazioni di funzionalità, alcuni dei quali vedremo meglio nel punto legato ai vantaggi.

Struttura

Lo scheletro di Laravel è basato sullo schema Model-View-Controller (MVC):

  • Model, dove vengono recuperati, convertiti e/o formattati i dati.
    Ad esempio una classe Prodotto che si occupa di recuperare i dati in una tabella di un database e formattare il prezzo con le migliaia separate da apici
  • View, dove è contenuto il layout delle pagine che saranno visualizzate
  • Controller, il quale si occupa di far comunicare le due parti precedenti elaborando eventualmente i dati ricevuti da una prima di passarli all’altra.

Questa struttura serve per delegare diverse responsabilità a componenti diversi così da avere una struttura logica definita ed evitare di riempire un unico file di codice. Ad esempio, è concettualmente sbagliato inserire nella view di una pagina delle funzioni per il calcolo di qualcosa. Questo deve essere fatto nel controller o nel model in base alla tipologia.

» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «

Perchè Laravel?

Sicurezza

Uno dei punti focali di Laravel è la sicurezza.

Utilizza di Bcrypt come algoritmo di hashing per salvare password nel database non in chiaro.
Ha una gestione nativa contro il cross-site scripting attraverso un token richiesto in ogni richiesta POST.
Attraverso Eloquent protegge da possibili SQL Injection

Gestione di exception ed errori

Ogni exception non gestita manualmente, viene comunque presa in carico da Laravel
Attraverso questo si può impedire la visualizzazione da parte degli utenti degli errori o della classica pagina bianca senza informazioni. Impostando Laravel in modalità produzione e creando una pagina dedicata, possiamo usare quest’ultima come ultima spiaggia nel caso qualcosa non funzioni.

Inoltre, di default Laravel salva gli errori in un file di log ma è già predisposto per poter aggiungere facilmente altre modalità in caso di exception specifiche, come ad esempio l’invio di una mail o l’invio di un messaggio ad un canale Slack ad esempio.

Ottima gestione del database

Le operazioni nel database con Laravel sono eccezionali. Sfrutta Eloquent, uno degli ORM (Object-Relational Mapping) migliori.

Come esempio, prendiamo la necessità di effetturare operazioni di lettura, scrittura, aggiornamento ed eliminazione (classico CRUD) su una tabella chiamata articoli.

Tutto quello che dobbiamo fare sarà creare un classe specifica (denominata in gergo model) la quale estende una classe di Eloquent chiamata Model

class Articolo extends Database/Eloquent/Model
{
	protected $primaryKey = 'id';

	protected $table = 'articoli';
}

Tutto qui. Vi serve indicare solo il nome la tabella e il nome della chiave primaria. Tutto il resto delle funzioni sono gestite dalla classe padre Model.

Ora, quando vi serve effettuare delle operazioni su quella tabella vi basterà usare i seguenti metodi:

// recuperare tutti gli articoli del 2022
// "created_at" è la colonna con la data di creazione dell'articolo
$articoli = Articolo::whereYear('created_at', 2022)->get();

// recuperare un singolo articolo con id 42
$articolo = Articolo::find(42);

// creare un articolo
// author_id, title, content sono colonne della tabella "articoli" nel db
$nuovoArticolo = Articolo::create([
	'author_id' => 123,
	'title' => "Titolo dell'articolo",
	'content' => "Contenuto dell'articolo",
]);

// recuperare l'id del nuovo articolo appena creato
$id = $nuovoArticolo->id;

// aggiornare il titolo dell'articolo con id 42
Articolo::where('id', 42)->update([
	'title' => "Titolo dell'articolo modficato",
]);

// eliminare l'articolo con id 42
Articolo::where('id', 42)->delete();
» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «

Vantaggi

Un buon framework si vede anche dalla facilità in cui le funzionalità possono essere introdotte mano a mano che la complessità del progetto le richiede. Vediamo le principali.

Middlewares

I middleware sono funzioni che vengono eseguite prima che la funzione della vostra route venga chiamata. In questo modo potete effettuare dei controlli prima di consentire l’accesso all’utente. Ad esempio potete verificare che sia loggato, che sia un utente premium, ecc.

Prendiamo il caso iniziale con le 3 pagine (home, chi-siamo, contatti) e poniamo il caso di voler consentire l’accesso solo ad utenti che si sono loggati.

Nella gestione classica dovremmo andare ad inserire le funzioni che controllano se un utente è loggato in ogni file index.php delle cartelle. Con Laravel, basta mettere quelle route dentro ad un middleware, così

Route::middleware('auth', function(){

	Route::get('home', function(){
		return view('home');
	});
	
	
	Route::get('contatti', function(){
		return view('contatti');
	});
	
	
	Route::get('chi-siamo', function(){
		return view('chi-siamo');
	});

});

Nella prima riga indichiamo a Laravel di utilizzare il middleware auth per ognuna delle route contenute all’interno. Questo middleware esce nativo con Laravel ma possiamo crearne altri facilmente in modo molto simile a quando abbiamo esteso la classe Model per il database.

Mi è capitato ad esempio che in una piattaforma gestionale con dozzine e dozzine di pagine, il cliente volesse integrare nella maggior parte di esse la possibilità di far accettare delle clausole agli utenti se non l’avessero ancora fatto.

Mi è bastato creare un middleware che controllasse se l’utente loggato abbia o meno nel database la voce flaggata e aggiungere tutte le route che mi servivano sotto quel middleware.

Relazioni ORM

Precedentemente abbiamo visto come sia facile interrogare il database con Eloquent.
Tuttavia una sola tabella non rappresenta i casi reali. Vediamo come Eloquent ci viene in aiuto anche in questi casi.

Poniamo di avere oltre alla tabella articoli anche una tabella autori ovviamente interconnesse tra loro tramite le colonne author_id nella tabella prima e id nella seconda.

L’associazione nel model Articolo sarà il seguente

class Articolo extends Database/Eloquent/Model
{
	protected $primaryKey = 'id';

	protected $table = 'articoli';

	public function autore()
	{
		return $this->belongsTo(Autore::class, 'author_id', 'id');
	}
}

Abbiamo indicato nella funzione autore() che la nostra classe Articolo è relazionata a quella Autore tramite i campi indicati. belongsTo è una funziona della classe Model che abbiamo estesa e fa tutto il collegamento al posto nostro.

Nel model Autore invece

class Autore extends Database/Eloquent/Model
{
	protected $primaryKey = 'id';

	protected $table = 'autori';

	public function articoli()
	{
		return $this->hasMany(Articolo::class, 'author_id', 'id');
	}
}

Stessa cosa della classe precedente. L’unica differenza sta nell’utilizzo di hasMany che si comporta come belongsTo solo che ritorna più record invece che uno solo, proprio perché un autore può avere più articoli, mentre un articolo può avere solo un autore.

Ora, quando avremo bisogno di queste relazioni potremo recuperarle facilmente:

$articolo = Articolo::find(42);

$articolo->autore; // oggetto dell'autore
$articolo->autore->id; // id dell'autore nella tabella autori
$articolo->autore->nome; // nome dell'autore nella tabella autori

$autore = Autore::find(123);
$autore->articoli // collection contente tutti gli articoli dell'autore
$autore->articoli->count(); // numero totale degli articoli
$autore->articoli[0]->titolo; // titolo del primo articolo in quelli recuperati

// possiamo anche sfruttare la relazione nelle query, ad esempio:

// recuperare tutti gli articoli con autori che iniziano con la "D"
Articolo::whereHas('autore', function($query){
	return $query->where('nome', 'like', "D%")
})->get();

// Recuperare autori che hanno almeno un articolo
Autori::whereHas('articoli')->get();

// Recuperare autori che hanno articoli scritti nel 2021
Autori::whereHas('articoli', function($query){
	return $query->whereYear('created_at', 2021)
})->get();
» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «

Accessors e Mutators

Restando sempre in tema model, troviamo due strumenti utilissimi per modificare dei dati prima di recuperarli o assegnarli.

Nel primo caso si chiamano acessors.
Un esempio pratico può essere quello di recuperare il nome completo di un utente loggato unendo i valori di nome e cognome. Potremo ottenere il risultato facilmente con

class User extends Model
{
	// definizione accessor
	public function getNomeCompletoAttribute()
	{
		return "$this->nome $this->cognome";
	}
}

// utilizzo acessors fuori dalla classe
$nomeCompleto = $user->nomeCompleto;

per definire un accessor basta creare una funzione con il nome dell’attributo che vogliamo creare inserito tra get e Attribute
Quando vogliamo utilizzarlo basta utilizzare il nome dell’attributo senza get e Attribute, come nell’esempio.

Per quanto riguarda i mutators invece funzionano similmente ai precedenti, con la differenza che hanno lo scopo di modificare un valore prima di assegnarlo al model. Vediamo un esempio pratico per capirci meglio.
Nel database MySql le date vengono utilizzate con il formato YYYY-MM-DD mentre in Italia utilizziamo il formato DD-MM-YYYY.
Ora, la nostra applicazione permette tramite un form in fase di creazione dell’utente di indicare la propria data di nascita. Dato che non è buon design far compilare all’utente la data nel formato del database dobbiamo quindi convertirla prima di assegnarla al model. Ovvero, una data di nascita 01-02-1990 inserita dall’utente, deve essere convertita in 1990-02-01.

Possiamo quindi sfruttare i Mutators in questo modo:

class User extends Model
{
	// definizione mutator
	public function setDataNascitaAttribute( $data )
	{
		$dataCorretta = DateTime::createFromFormat('dd-mm-yyyy', $data);

		$this->attributes['dataNascita'] = $dataCorretta->format('yyyy-mm-dd');
	}
}

Ora non dovremo più preoccuparci di convertire la data prima di assegnarla:

// Recupero data nascita dal form inviato (in formato gg-mm-aaaa)
$dataNascita = request()->get('dataNascita');
// assegnazione a model. Il mutator farà il lavoro per noi
$user->dataNascita = $dataNascita;

Se ad esempio la piattaforma avrà anche un pannello admin dove gli amministratori possono creare utenti autonomamente, non dovremo aggiungere altro codice per convertire la data perché passeremo comunque dal mutator già creato.

Ovviamente eccessors e mutators possono essere anche più complessi, come ad esempio controllare che la data non sia già in formato corretto prima di convertirla.

In un caso reale, un uso praticamente costante lo faccio nei valori di costi/prezzi.
Premessa: a causa di possibili problemi di arrotondamento è buona norma salvare i prezzi nel database in centesimi e non i euro (quindi 18,99 viene salvato come 1899).
Ogni volta che un prezzo di un prodotto viene assegnato/recuperato deve quindi subire una trasformazione.

Questo, come gli esempi precedenti viene soddisfatto velocemente in questo modo:

class Product extends Model
{

	public function getPriceAttribute()
	{
		return $this->price / 100;
	}

	public function setPriceAttribute( $price )
	{
		$this->attributes['price'] = $price * 100;
	}
}

Fatto ciò, non devo più preoccuparmi in nessun altro punto dell’applicazione di effettuare la conversione quando chiamo $product→price per il recupero o per l’assegnazione di un valore

Utenti loggati

Quante volte dobbiamo verificare nella nostra piattaforma che l’utente sia loggato e/o che rispetti determinate caratteristiche? Con Laravel abbiamo moltissime funzioni che ci vengono in supporto:

// Logghiamo l'utente con id 42
auth()->login(User::find(42));

// verfichiamo se l'utente corrente è loggato
auth()->guest() // ritorna true se non è loggato

// recuperare l'utente corrente
$user = auth()->user();
$user->email; // email dell'utente
$user->id; // id dell'utente

// logout utente, cancellazione sessione ed invalidamento cookies
auth()->logout();
» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «

Dove iniziare e requisiti

Se stai pensando di iniziare a studiare Laravel da zero ti consigliamo di dare uno sguardo al nostro percorso professionale “Back-end Developer con Laravel“. All’interno troverai sia i corsi su Laravel che quelli propedeutici sugli argomenti che dovresti conoscere prima di avventurarti con questo framework.

Dovrai necessariamente avere infatti una:

  • Buona conoscenza di HTML, CSS
  • Buona conoscenza di PHP OOP

È consigliata inoltre la conoscenza base di JS (nel caso avessi bisogno trovi qui il nostro Percorso per Programmatori Javascript). Non è direttamente legato al funzionamento di Laravel, ma sapere come funziona JS e dove inserire gli script aiuterà sicuramente.

Risorse ufficiali

» VUOI SAPERNE DI PIU’? SCOPRI IL NOSTRO PERCORSO BACK-END DEVELOPER CON LARAVEL «