16 Controller e Raw query
Vediamo come interrogare il database con delle queries grezze utilizzando la classe facade DB.
Vediamo come selezionare i dati precedentemente inseriti nel database creando un controller e nella vista invece che utilizzare una funzione anonima, usiamo il controller col suo metodo
Creare un controller
Creiamo un nuovo controller per gli album, ricordo di usare –help per la guida
php artisan make:controller AlbumsController -m Album -r
Il nome del controller è uguale al nome della tabella con l’iniziale maiuscola seguita dalla keyword Controller
l’opzione -m lega il controller ad un model, bisogna quindi specificarne il nome.
l’opzione -r genera un resource controller, ovvero tutte quelle funzioni legate alla manipolazione dei dati della tabella.
Struttura di un controller
public function index()
Abbiamo il metodo index() per mostrare l’elenco dei dati, nel nostro caso l’elenco degli album
public function create()
Il metodo create() per mostrare il form
public function store(Request $request)
Il metodo store() per salvare i dati
public function show(Album $album)
Il metodo show() per mostrare un record
public function edit(Album $album)
Il metodo edit() per modificare un record
public function update(Request $request, Album $album)
Il metodo update() per aggiornare, come si vede ignetta la Request e automaticamente passando l’ID ci crea un’istanza dell’oggetto
public function destroy(Album $album)
Il metodo destroy() elimina un record passando il suo ID
Mappare il controller nella rotta
In web.php andiamo a fare un po’ di pulizia, lasciamo solo le 3 rotte / , /users , /albums.
Nell’uso dei modelli e dei controller avevamo:
use App\Http\Controllers\{HomeController, WelcomeController}; use App\Models\User; use \App\Models\Album;
Le ultime 2 le raggruppiamo con le graffe, visto che il percorso è identico
use App\Models\{User, Album};
Per i controllers cancelliamo i precedenti visto ce non servono più e inseriamo solo AlbumsController
use App\Http\Controllers\AlbumsController;
Nella rotta /albums invece della funzione passiamo il controller all’interno di un array che conterrà la classe del controller come primo valore e il metodo da eseguire come secondo
Route::get('/albums', [AlbumsController::class , 'index']);
Nel metodo index() del controller andiamo a restituire il metodo all() che è simile al metodo get(), ma non permette la concatenazione di altri metodi.
public function index() { return Album::all(); }
Proviamo a lanciare l’url e vediamo che tutto funziona correttamente come prima.
Raw query
Supponiamo invece di non avere il model Album e volessimo effettuare un interrogazione del database direttamente dal metodo index utilizzando delle queries grezze, inseriamo il comando SQL in una variabile
public function index() { $sql = 'select * from albums'; }
a questo punto utilizziamo la facade DB utilizzando il suo metodo select()
$sql = 'select * from albums'; return DB::select($sql);
Il metodo select() ci restituisce un array di records e ogni record è la standard class corrispondenti alle proprietà della tabella.
Testiamo e vediamo che la pagina si apre correttamente con tutti i records visualizzati correttamente.
Se volessimo filtrare i record, magari via Get passando come parametro l’ID,
http://127.0.0.1:8000/albums?id=2
possiamo iniettare la Request di DB come parametro del metodo index()
public function index(Request $request) { $sql = 'select * from albums'; return DB::select($sql); }
adesso possiamo andare a mettere un condizione che se $request ha un ID, concateniamo un where alla $sql
$sql = 'select * from albums'; if($request->has('id')) { $sql .= ' where id =' }
aggiungiamo l’id prendendolo da $request->get(), magari facciamo anche un casting a integer
$sql .= ' where id ='. (int)$request->get('id');
Perfetto, ora vediamo solo il record 2.
Filtrare in base al nome
Se volessimo aggiungere la condizione di filtraggio in base anche al nome, la cosa si complica leggermente, perchè non potremmo effettuare il cast a intero come per l’id, l’obiettivo è di ottenere una query SQL così
select * from albumums WHERE id=2 AND album_name="pippo"
inizializziamo una variabile esterna agli if $where vuota. Poi costruiamo un altro if basato sul parametro album_name che popola la query con il frammento di SQL aggiuntivo.
Sommiamo $where a $sql
public function index(Request $request) { $where = ''; $sql = 'select * from albums'; if($request->has('id')) { $sql .= ' where id =' . (int)$request->get('id'); } if($request->has('album_name')) { $where = " AND album_name=".$request->get('album_name')." "; } $sql = $sql . $where; return DB::select($sql); }
La procedura risulta abbastanza contorta, fortunatamente esistono i filtri PDO che ci verranno in contro e che vedremo più avanti.
Abbiamo la possibilità di testare come sta uscendo la query sfruttando la funzione dd() die dump di laravel
dd($sql);