PHPPamokos.lt


7. Commands ir Events

Laravel 5 versioje buvo nuspręsta atskirti atskirą sluoksnį veiksmų į taip vadinamas komandas (Commands). Iš principo, tai yra funkcijos, kurias paprasta iškviesti tiek iš Controllerių, tiek iš Artisan pagalbininko, o taip pat jas galima įdėti į eilę (Queue).

Populiariausias pritaikymo pavyzdys - kai po kažkokio Controllerio veiksmo reikia atlikti šalutinį, foninį veiksmą, kurio vartotojas naršyklėje laukti neturėtų. Sakykime, įvykdžius kažkokį pirkimą - išsiųsti laišką. O galbūt ir patį pirkimo apdorojimo procesą galima vykdyti fone.

Parodysiu, kaip reikia sukurti komandą, iš ko ji susideda ir kaip po to ją panaudoti. Sakykime, kad panaudosime komandą el.pašto laiškui išsiųsti.

Kaip sukurti komandą

Prasideda viskas nuo Artisan komandinės eilutės veiksmo:

php artisan make:command EmailConfirmation

Tada susikuria komandos failas app/Commands/EmailConfirmation.php:

namespace App\Commands;

use App\Commands\Command;

use Illuminate\Contracts\Bus\SelfHandling;

class EmailConfirmation extends Command implements SelfHandling {

	public function __construct()
	{
		// čia galime perduoti parametrus
	}

	public function handle()
	{
		// čia išsiųsime laišką el.paštu pagal parametrus
	}

}

Kaip matote, sukurta komanda paveldima iš Command klasės, ir tuo pačiu vykdo SelfHandling interfeisą. Į tų pagrindinių klasių funkcionalumą nesigilinkime, o pažiūrėkime geriau - kaip aprašyti mūsų komandos veiksmus.

Yra du metodai - konstruktorius ir pagrindinė funkcija handle(). Konstruktorius naudojamas labiau parametrų perdavimui, jei tokių yra, o pagrindinis veiksmas visgi atliekamas per handle().

Kaip panaudoti komandą

Kai komanda yra sukurta, ją galima iškviesti - pavyzdžiui, iš Controllerio:

public function store()
{
    // $user = User::create(...);
    $this->dispatch(new EmailConfirmation());
}

Kaip matome, yra kviečiamas metodas dispatch(), kurio parametras yra mūsų sukurtos komandos naujas objektas. Galima skliausteliuose perduoti ir parametrus, kuriuos po to panaudosime konstruktoriuje.

Kad toks komandų iškvietimas įvyktų, pagrindiniame Laravel controlleryje app/Http/Controllers/Controller.php yra tokia eilutė:

use DispatchesCommands;

Taigi, jeigu norėsite komandas naudoti kažkur kitur ne Controlleriuose, tada turėsite šią eilutę įrašyti ir ten.

Kaip įdėti komandą į Queue

Pats Queue mechanizmas Laravel 5 versijoje nepasikeitė - vis dar galima naudoti beanstalkd ar kitą eilių valdymo sistemą. Bet su komandų pagalba paprasta tą mechanizmą panaudoti - įdėti komandą į Queue.

Nėra nieko paprasčiau - tam tikslui, kurdami komandą per Artisan, tiesiog pridedame parametrą --queued:

php artisan make:command EmailConfirmation --queued

To rezultatas - komandos klasėje atsiranda užrašas ShouldBeQueued ir dar naudojamas SerializesModels trait'as. Bet tai jums neturėtų rūpėti - visa tai vykdoma automatiškai per Queue.

Štai tiek apie komandas, kaip sakoma - imkite ir naudokite.

Priešingas funkcionalumas - Events

Prisipažinsiu - pradžioje norėjau kurti atskirą skyrelį apie Events, bet tarp jų ir Commands yra tiek daug panašumų, kad prasmingiau apie juos parašyti iškart čia. Netgi, tiesą pasakius, sunkiai sugalvoju pavyzdį, kur labiau apsimokėtų naudoti Events o ne Commands, nes veikimas beveik toks pat.

Priminsiu - Commands funkcionalumo principas: kažkam įvykiui įvykus, kviečiama komanda. O Events principas kardinaliai priešingas: jie laukia kol kažkoks įvykis įvyks, ir tada išsikviečia.

Netgi ir sudarymas bei naudojimas yra labai panašus - trumpai papasakosiu:

1. Su Artisan sukuriama Event klasė:

php artisan make:event ItemWasPurchased

2. "Prenumeruojame" įvykį ir pririšame jo apdorojimo klasę faile app/Providers/EventServiceProvider.php:

protected $listen = [
    'App\Events\ItemWasPurchased' => [
        'App\Handlers\Events\EmailPurchaseConfirmation',
    ],
];

3. Sukuriame Evento "handlerį" - su Artisan:

php artisan handler:event EmailPurchaseConfirmation --event=ItemWasPurchased

4. O tada, iš kur mums reikia, turime informuoti, kad toks įvykis įvyko:

$response = Event::fire(new ItemWasPurchased($item));

Vėlgi pasakysiu savo asmeninę nuomonę - nematau prasmės naudoti Events funkcionalumą, kol yra Commands - gaunasi beveik dubliavimas. Bet galbūt tai verta daryti dėl architektūrinio sprendimo - panašiai kaip duomenų bazėje logiką dėti į Trigerius - pats nesu to šalininkas.



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