Negli articoli precedenti, nella maggior parte dei casi, abbiamo utilizzato le closure functions per gestire la logica dell’applicazione. In questo articolo scopriremo come utilizzare le classi Controller per gestire la logica dell’applicazione ed accenneremo alle views per la presentazione dei dati in formato html nel browser.
Il vantaggio di utilizzare le classi Controller consiste nella possibilità di riunire richieste correlate in un’unica classe, in modo da gestire con un unico file, contenente la definizione della classe, le parti comuni di un’applicazione.
I controllers, se non diversamente specificato, vengono salvati nella cartella app/Http/Controllers.
Mentre i controllers si occupano della logica dell’applicazione, le viste (views) contengono il codice html di presentazione dei dati all’interno del browser. Se non diversamente specificato, le viste (views) si trovano a partire dalla cartella resources/views.
Per illustrare il funzionamento di views e controllers aiutiamoci con un esempio.
Spostiamoci all’interno della cartella che contiene la nostra applicazione
cd laraapp
ed iniziamo a creare il controller al quale affideremo la gestione dell’archivio articoli di un ipotetico negozio
php artisan make:controller ArticoliController
Il comando appena digitato crea, all’interno della cartella app/Http/Controllers, il file ArticoliController.php contenente quanto viene mostrato nell’immagine seguente
Come si evince dal listato mostrato in figura, nel file viene creata la struttura della classe ArticoliController come discendente della classe Controller; sarà all’interno della classe che definiremo i metodi per la gestione degli articoli trattati dal negozio.
Iniziamo definendo il metodo create, che richiamerà una vista che presenterà all’utente una form con dei campi di input per l’inserimento dell’articolo:
public function create ()
{
return view('articoli.create');
}
Il codice riportato sopra definisce il metodo create, nella classe ArticoliController, che richiama la view contenente il codice html della form. La view si trova all’interno della cartella resources/views/articoli nel file create.blade.php, da notare che va specificata solo la parte di percorso che segue resources/views, separando le cartelle figlie di views e il file utilizzando il carattere ‘.’; inoltre nel nome del file non occorre specificare il suffisso .blade.php.
A questo punto occorre creare la vista create.blade.php e definire nel file routes/web.php l’ url che richiami il metodo create.
Il codice sopra mostra come assegnare la route /articoli/new al metodo create del controller ArticoliController. Osservando il secondo parametro della route, si nota che per richiamare un metodo all’interno di un controller come action della route, occorre semplicemente specificare il nome del controller, seguito dal carattere ‘@’ e infine dal nome del metodo da richiamare.
Per completare è sufficiente creare il file create.blade.php, all’interno di resources/views/articoli, contenente il codice html della form.
Fatto questo, se nella barra dell’indirizzo del browser si digita http://laraapp.webserver/articoli/new, verrà mostrata la form per inserire i dati dell’articolo.
Avrete notato che nel richiamare il controller nella definizione della route non c’è bisogno di specificare App\Http\Controllers come parte del namespace, poiché Laravel lo include automaticamente, avendolo definito nel file app/Providers/RouteServiceProvider.php. In pratica bisogna solo specificare il namespace che segue App\Http\Controllers, così, se io avessi creato la mia classe controller all’interno della sotto cartella articoli di app/Http/Controllers, avrei dovuto definire la route così:
Route::get('articoli/new','articoli\ArticoliController@create');
CONTROLLER AD AZIONE SINGOLA
Se un controller deve svolgere un’unica azione, allora è possibile definire un unico metodo __invoke contenente il codice necessario per l’azione richiesta:
public function __invoke()
{
//scrivere qui il codice necessario
}
per richiamare il controller, da una route, basta solo indicare il suo nome senza indicare alcun metodo:
Route::get('percorso-route','nome-controller');
Per creare un controller invocabile è sufficiente usare il comando php artisan make:controller nome-controller –invokable.
CONTROLLER E MIDDLEWARE
Per assegnare un middleware alle route di un controller si può operare in due modi:
- Specificarlo utilizzando il metodo middleware della classe Route
- Specificarlo all’interno del metodo costruttore del controller
Il secondo metodo è più flessibile rispetto al primo, ma vediamo come funzionano entrambi:
METODO 1
Route::get('/articoli/new','ArticoliController@create')->middleware('nome-middleware-da-assegnare');
METODO 2
class ArticoliController extends Controller
{
public function __construct()
{
$this->middleware('nome-middleware-da-assegnare');
}
public function create()
{
return view('articoli.create');
}
}
Se volessi collegare il middleware non a tutti i metodi della classe, ma solo ad alcuni, potrei farlo così:
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('create');
$this->middleware('subscribed')->except('store');
}
}
Il middleware auth sarà applicato a tutti i metodi della classe, il middleware log solo al metodo create e il middleware subscribe solo al metodo store.
In realtà vi è anche la possibilità di registrare un middleware all’interno della classe stessa utilizzando una closure, evitando così di creare una classe middleware:
public function __construct()
{
this->middleware(function($request,$next){
//codice middleware
return $next($request);
});
}
RESOURCE LARAVEL
Quando si lavora con gli archivi, le tipiche operazioni che si fanno sono:
creazione (create), aggiornamento(update) e cancellazione(delete). Quest’insieme di azioni viene indicato con l’acronimo CRUD (Create-Update-Delete).
Laravel dà la possibilità di definire un controller che preveda già la definizione dei metodi necessari per gestire un archivio al suo interno, per farlo basta definire il controller utilizzando la riga di comando e la sintassi seguente:
php artisan make:controller ArticoliController --resource
Di seguito ciò che verrà generato da Laravel in app\Http\Controllers\ArticoliController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ArticoliController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
Non resta che inserire all’interno dei metodi il codice per creare, salvare cancellare, visualizzare ecc.
Fatto questo, occorre registrare all’interno del file routes/web.php, che gestisce le route della nostra applicazione, la resource route utilizzando la seguente sintassi:
Route::resources('/articoli','ArticoliController');
Questa singola linea di codice registra, in maniera trasparente all’utente, una serie di routes collegate alle azioni(metodi) del controller.
Metodo Richiesta | URI | Metodo classe controller | Nome Route |
---|---|---|---|
GET | /articoli | index | articoli.index |
GET | /articoli/create | create | articoli.create |
POST | /articoli | store | articoli.store |
GET | /articoli/{id} | show | articoli.show |
GET | /articoli/{id}/edit | edit | articoli.edit |
PUT/PATCH | /articoli/{id} | update | articoli.update |
DELETE | /articoli/{id} | destroy | articoli.destroy |
Analizziamo il significato della tabella:
La prima riga suggerisce che, alla richiesta di tipo GET dell’url http://laraapp.webserver/articoli viene associato il metodo index del controller e che a questa route si può fare riferimento utilizzando il nome articoli.index
La seconda riga suggerisce che, alla richiesta di tipo GET dell’url http://laraapp.webserver/articoli/create viene associato il metodo create del controller (che mostrerà una form di input) e che a questa route si può fare riferimento utilizzando il nome articoli.create
La terza riga suggerisce che, alla richiesta di tipo POST dell’url http://laraapp.webserver/articoli viene associato il metodo store (provvederà al salvataggio dei dati inviati dalla form di creazione) del controller e che a questa route si può fare riferimento utilizzando il nome articoli.store
La quarta riga suggerisce che, alla richiesta di tipo GET dell’url http://laraapp.webserver/articoli/{articolo} viene associato il metodo show (visualizza il record relativo all’articolo con id pari al valore passato nel parametro articolo ) del controller e che a questa route si può fare riferimento utilizzando il nome articoli.show
La quinta riga suggerisce che, alla richiesta di tipo GET dell’url http://laraapp.webserver/articoli/{articolo}/edit viene associato il metodo edit(mostra una form con i campi precompilati con i valori dell’articolo con id corrispondente a quello del parametro passato ) del controller e che a questa route si può fare riferimento utilizzando il nome articoli.edit
La sesta riga suggerisce che, alla richiesta di tipo PUT dell’url http://laraapp.webserver/articoli/{articolo} viene associato il metodo update (aggiorna il record in base ai valori inviati dal form di edit ) del controller e che a questa route si può fare riferimento utilizzando il nome articoli.update
L’ultima riga suggerisce che, alla richiesta di tipo DELETE dell’url http://laraapp.webserver/articoli/{articolo} viene associato il metodo destroy (elimina il record relativo all’articolo con id pari al valore passato nel parametro articolo ) del controller e che a questa route si può fare riferimento utilizzando il nome articoli.destroy
Se si desidera registrare più routes di risorse, lo si può fare utilizzando gli array nel modo suggerito dall’esempio seguente:
Route::resources([
"/articoli" => "ArticoliController",
"/clienti" => "ClientiController"
]);
Per ulteriori approfondimenti si rimanda alla documentazione ufficiale