PHPPamokos.lt


5. Controllers

Praeitoje pamokoje detaliai išnagrinėję Routes, turbūt pamatėme, kad nėra labai patogu aprašinėti kiekvieną URL adresą ir jo veiksmą routes/web.php faile. Būtent čia ateina į pagalbą Controllers (viena iš MVC dedamųjų), į kuriuos ir sudėsime visą adresų apdorojimų logiką.

 

Controller: konkrečios funkcijos kvietimas

Paprasčiausias panaudojimo pavyzdys - vietoje Closure funkcijos perkeliame logiką į Controllerį, kad nebūtų per daug užkimštas mūsų routes/web.php failas ir kad būtų lengviau atskirti logiką. Priskirkime prie Routes kelio savo sugalvotą Controllerį ir jo funkciją:

Route::get('catalog', 'CatalogController@showIndex');
Ši eilutė traktuojama taip: "jeigu URL adresas yra /catalog, tada kreipiamasi į CatalogController klasę ir kviečiama jo funkcija pavadinimu showIndex()".

Taigi, kataloge app/Http/Controllers sukuriame failą su atitinkamu pavadinimu - CatalogController.php. Štai jo turinys:
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class CatalogController extends Controller
{

  public function showIndex()
  {
    return view('catalog');
  }

}
Kaip matote, Controlleris yra PHP klasė, paveldėta nuo Controller ir turinti įvairias funkcijas, kurias galima priskirti prie Routes.

Išnagrinėkime atskirai - į ką reikia atkreipti dėmesį:
  • Namespace: Laravel rūpinasi tuo, kad kiekvienas failas būtų priskirtas savo namespace erdvei, tai Controlleriams yra būtent App\Http\Controllers. Tiesa, galima Controllers kataloge kurti ir gilesnius katalogus, tada ir prie namespace prisideda to sub-katalogo pavadinimas.
  • use Controller: kadangi mūsų Controlleris paveldėtas nuo bendros Laravel Controller klasės, tai reikia ją panaudoti.
  • Klasės pavadinimas: jis turi sutapti su failo pavadinimu (didžiosios ar mažosios raidės - nesvarbu, tiesiog patogiau skaityti). Nėra privaloma, kad žodyje būtų Controller dalis, pavadinti galite bet kaip - bet vėlgi patogumo dėlei patartina laikytis tokio formato, tada pagal failo pavadinimą iškart galima bus suprasti jo paskirtį, net jei jį atidarysite po metų ar perleisite projektą kitam programuotojui.
  • Extends Controller - privaloma sąlyga. Tiesa, pats failas Controller.php nėra paslėptas toli: jei kada prireiks, galėsite jį lengvai paredaguoti, jis yra tame pačiame app/Http/Controllers kataloge.
  • Funkcijos: klasės viduje galite kurti funkcijas savo nuožiūra - vėliau jas priskirsite prie Routes kelių. Tiesa, yra nerašyta taisyklė - vadinti funkcijas iš dviejų dalių: ką daryti ir su kuo. Antroji dalis atskiriama didžiąja raide, kad būtų lengviau skaityti: pvz - function showIndex(), updateUser(), deleteRow(). Tiesa toks dviejų dalių pavadinimas turi ir gilesnę prasmę, apie tai kiek žemiau.
Kiekviena funkcija turėtų grąžinti tą patį, ką praeitoje pamokoje darėme routes/web.php faile - tekstą, View failą, Response arba Redirect.
 

Resource RESTful Controllers: generavimas su Artisan

Yra dar vienas Controllerių tipas, vadinamas RESTful Resource Controllers. Jie skirti informacijos valdymui, t.y. administravimui: peržiūrai, įvedimui, redagavimui ir trynimui. Arba, kaip anglai mėgsta sakyti, Create Read Update Delete, sutrumpintai CRUD. Iš tokių Controllerių turėtų susidaryti jūsų administravimo panelė. Nors tai nebūtina, galite naudoti ir paprastus GET-POST metodus, tiesiog Laravel siūlo tokį pagalbininką.

Jau kažkada minėjau, kad Laravel turi komandinės eilutės pagalbininką Artisan. Štai čia ir pasinaudosime jo pagalba - jis gali sugeneruoti Resource Controllerio griaučius automatiškai ir sutaupyti mums laiko.

Komandinėje eilutėje nueiname į mūsų projekto pagrindinį katalogą, ir ten įrašome:
php artisan make:controller BooksController --resource
Ši komanda sukuria failą app/Http/Controllers/BooksController.php - tiesiog imkite ir naudokite. Pažiūrėkime į jo turinį:
class BooksController extends Controller {

public function index()
{
//
}

public function create()
{
//
}

public function store(Request $request)
{
//
}

public function show($id)
{
//
}

public function edit($id)
{
//
}

public function update(Request $request, $id)
{
//
}

public function destroy($id)
{
//
}

}
Kiekviena funkcija atstoja vieną iš metodų:
  • Funkcija index - GET metodas /books (knygų sąrašas)
  • Funkcija create - GET metodas /books/create (naujos eilutės forma)
  • Funkcija store - POST metodas /books/create (naujos eilutės įterpimui)
  • Funkcija show - GET metodas /books/[ID] (konkrečios eilutės vaizdavimas)
  • Funkcija edit - GET metodas /resource/[ID]/edit (eilutės redagavimas)
  • Funkcija update - PUT/PATCH metodas /resource/[ID] (eilutės išsaugojimas)
  • Funkcija destroy - DELETE metodas /resource/[ID] (eilutės trynimas)
Tiesa, ne visos funkcijas gali bus reikalingos, tad galite pratrinti ko nereikia. Sukūrus tokį Controllerį, prie Route jį priskirti reikia atskira komanda:
Route::resource('books', 'BooksController');
Tai tiek apie Controllers galimybes. Vienintelis dalykas, kurį reikia pridurti - kad paties puslapio logikos per daug nereikėtų kišti į Controllers, jie skirti labiau URL surišimui su Views failais. Logiką geriau saugoti į Models failus - būtent apie juos kalbėsime kitame skyrelyje.
 

Praktika ir namų darbai

Šįkart praktikai skirsime daugiau dėmesio. Tęsiame ir toliau mūsų krepšinio aikštelių duomenų bazės kūrimą. Pats laikas faile routes/web.php vietoje buvusių Route::get() komandų priskirti Controller'ius bei juos sukurti.

Kokius būtent Controllerius kurti ir kaip juos priskyrinėti prie Routes - čia nėra vieno sprendimo, yra bent keli būdai viską suskirstyti. Teoriškai netgi galima kurti vieną Controllerį ir viską "kabinti ant jo", bet tai nebūtų patogu, žvelgiant į ateities projekto plėtrą. Bendra nerašyta taisyklė yra vienas puslapis ar projekto skiltis - vienas Controller'is. Štai kaip tai atrodys mūsų atveju:

  • Pagrindinis puslapis - HomeController
  • Aikštelių sąrašas - SearchController
  • Konkreti aikštelė - CourtController
  • Puslapis "Apie mus" - AboutController
  • Puslapis "Kontaktai" - ContactController
  • Administravimas: aikštelės - AdminCourtsController
  • Administravimas: miestai - AdminCitiesController
  • Administravimas: aikštelių tipai - AdminTypesController

Kaip jau sakiau, galite skirstyti ir kitaip, jei jums atrodo prasmingiau - sakykim, tekstinius puslapius "Apie mus" ir "Kontaktai" galbūt prasminga vienyti po vienu TextsController su skirtingomis funkcijomis.

Controllerius galima kurti keliais būdais, bet aš visada pasitelkiu Artisan pagalbininką, net jei man reikia paprasto controller'io - nereikalingas funkcijas pratrinti lengviau negu viską rašyti ranka. Taigi:

php artisan make:controller HomeController

Tada sukurtame faile app/Http/controllers/HomeController.php sukuriame tik vieną paprastą funkciją - tiksliau, paredaguojame jau automatiškai sukurtą:

public function showWelcome()
{
  return view('home');
}

Ir paskutinis žingsnis - routes/web.php faile darome priskyrimo eilutę.

Buvo:

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

Keičiame į:

Route::get('/', 'HomeController@showWelcome');

Ir taip su kitais controller'iais, tik administravimo failams galios kiek kitokia logika - priskyrimas vyks per komandą Route::resource().

Štai jums ir namų darbai - priskirti sukurtus controller'ius. Pabandykite tai padaryti patys, o pasitikrinimui naują routes/web.php failą ir Controllerius galite parsisiųsti iš čia.

Nekreipkite dėmesio, kad kol kas Controlleriai ir Views failai gali būti tušti ir neveikti - juos užpildysime vėliau, kai išmoksime dirbti su duomenų baze. Šiame etape svarbiausia teisingai nukreipti Routes į teisingus Controllerius.

Šiame etape atkreipkite dėmesį į tokius dalykus:

  • Angliški pavadinimai - visų kontrukcijų vardus patartina rašyti angliškai, o lietuviškus adresus /apie ir panašius galima priskirti per routes/web.php failą
  • Administravimui kursime taip vadinamus Resource controller'ius - su funkcijomis index(), create(), store(), show(), edit(), update() ir destroy()
  • Po šio pakeitimo routes/web.php faile turi nebelikti Closure funkcijų - viskas nukreipiama į controller'ius



(c) 2015-2018. Visais klausimais kreipkitės povilas@laraveldaily.com