Przez bardzo długi czas byłem zapalonym zwolennikiem Zend Frameworka. Prawie każdy projekt PHP, jaki wychodził spod mojej ręki, oparty był o ten framework. Czas mijał, kolejne projekty powstawały, a framework się starzał, więc z ogromną niecierpliwością wypatrywałem kolejnej jego wersji. Niestety wraz z pojawiającymi się betami i RC, zniechęcałem się do tego frameworka coraz bardziej. Problemy z ZF2 spowodowały, iż zacząłem rozglądać się za alternatywą. Po kilku miesiącach testów różnych frameworków, wygrał Laravel.

Bardzo zadowolony ze swojego wyboru, zacząłem tworzyć kolejne projekty w tym frameworku i każda kolejna realizacja, utwierdzała mnie w przekonaniu, że był to dobry wybór. Najnowszą stabilną wersję (4.2) poznałem całkiem dobrze, gdy doszły mnie informacje, że niedługo światło dzienne ujrzeć ma wersja 5. Jak się okazało, termin listopadowy nie zostanie dotrzymany i możemy spodziewać się wydania Laravela 5 dopiero w styczniu, niemniej już teraz warto wiedzieć czego się spodziewać.

  1. Nowa struktura katalogów
  2. Nowe generatory
  3. Adnotacje route’ów
  4. Adnotacje zdarzeń
  5. Kontrakty
  6. Formularze
  7. Helpery
  8. Middleware
  9. Harmonogramowanie zadań

Nowa struktura katalogów

W obecnej wersji frameworka, zdecydowana większość kodu znajduje się w katalogu app. Znajdziemy w nim konfigurację, testy, kontrolery, wersje językowe, magazyn na pliki, cache, sesje, itp. Wszystkie te elementy są niezbędne do działania aplikacji, jednak nie koniecznie powinny znajdować się w katalogu aplikacji. Twórcy frameworka doszli do takich właśnie wniosków i przenieśli większość tych katalogów do głównej gałęzi projektu. Teraz w katalogu app znajdują się jedynie kontrolery, modele, klasy odpowiedzialne za konsolową część aplikacji (wcześniej znajdowały się w katalogu commands, teraz jest to Console) oraz providery . Zmiana zaszła również w filtrach, które nie są już przechowywane w jednym pliku. Zamiast tego, każdy filtr to osobna klasa. Nowa struktura katalogów wygląda następująco:

Drzewo katalogów

Kolejną nowością w Laravel 5 jest obecność folderu Middleware. Przy pomocy klas tego typu będziemy w stanie napisać wrappery dla requestów i odpowiedzi na nie. Upraszczając nieco ich rolę, będzie to nowy sposób tworzenia filtrów, które nie są bezpośrednio związane z logiką aplikacji.

Jeśli przyjrzeliście się powyższej grafice, na pewno zauważyliście, że pojawił się folder resources. Od wersji 5 będzie on miejscem, w którym przechowywane będą widoki, pliki językowe oraz zasoby takie jak np. pliki sass.

Nowe komendy wiersza poleceń

Wiersz poleceń we frameworku Laravel doskonały nie jest. Mimo iż wiele przy jego pomocy można uzyskać (na pewno więcej niż w przypadku Zend Frameworka), do doskonałości jeszcze mu trochę brakuje. Piąta wersja frameworka wprowadza kilka zmian, dzięki którym łatwiej się będzie poruszać w konsoli. Najbardziej rzucającą się w oczy zmianą jest utowrzenie wspólnej przestrzeni dla generatorów. Od piątej wersji dostępna będzie komenda make, z poziomu której będziemy tworzyć kontrolery, migracje, itd. Pojawił się generator schedule pozwalający na ustawienie zadań cyklicznych (napiszę o tym więcej przy okazji jednego z kolejnych wpisów poświęconych temu frameworkowi). Dodane zostały również kolejne komendy do zarządzania route’ami. Również publikacja została zaktualizowana i teraz publikowanie zasobów czy plików konfiguracyjnych zostało przeniesione do publish:.

Adnotacje route’ów

Nie jestem fanem adnotacji, zwłaszcza w PHP, ponieważ zaciemniają one obraz aplikacji, a źle używane mogą spowodować ból głowy u każdej osoby, która chce debugować nie swój kod. Z drugiej strony, jeśli mamy bardzo dużą aplikację z ogromną ilością route’ów, trzymanie ich wszystkich w jednym pliku na pewno spowoduje bałagan. Niestety złotego środka nie ma, więc wszystko zależy od zdrowego rozsądku programistów oraz od narzędzi z jakich korzystają. Laravel 5 pozwala tworzyć adnotacje w kontrolerach i na ich podstawie generuje route’y do naszej aplikacji.

Korzystanie z adnotacji jest banalnie proste. W podstawowej wersji wygląda następująco:

namespace App\Http\Controllers;

class TestowyController extends Controller
{
    /**
     * @Get("/testujemy")
     */
    public function index()
    {
        return view('index');
    }
}

Poza samym dodaniem adnotacji do akcji, musimy jeszcze wygenerować reguły route’ów (dzięki temu nie będą one każdorazowo parsowane). Wpierw musimy wskazać frameworkowi, gdzie ma szukać dodatkowych definicji. W tym celu w klasie RouteServiceProvider dodajemy kontroler z route’ami do tablicy $scan.

protected $scan = [
'App\Http\Controllers\TestowyController'
];

Na koniec skanujemy nasze kontrolery przy pomocy polecenia

php artisan route:scan

Wygenerowane route’y przechowywane są w pliku storage/framework/routes.scanned.php.

Adnotacje zdarzeń

Podobnie jak w przypadku route’ów, zdarzenia również można opisywać przy pomocy adnotacji. Obsługę zdarzenia najlepiej umieścić w klasie

class Test
{
    /**
     * @Hears("some.event")
     */
    public function doIt()
    {
        echo 'I did it!';
    }
}

Kolejne kroki są identyczne jak w przypadku route’ów. Najpierw dodajemy do tablicy $scan informację o klasach, jakie mają być przeszukane pod kątem obsługi zdarzeń.

protected $scan = [
    'App\Test'
];

Następnie wykonujemy komendę

php artisan event:scan

Wygenerowana obsługa zdarzeń trafiła do pliku storage/framework/events.scanned.php. Od tej pory możemy korzystać ze zdarzeń, które zapisaliśmy w postaci adnotacji.

Kontrakty

Kontrakty w Laraverze 5 to nic innego jak zbiór interfejsów, definiujących usługi dostarczane przez framework. Dzięki zastosowaniu interfejsów, mamy możliwość przygotować własną implementację usług w sposób, który najlepiej sprawdzi się w konkretnym przypadku.

Formularze

W czasach gdy większość czasu przy PHP spędzałem z Zend Frameworkiem, komponent Zend_Form byłbym w stanie odtworzyć z pamięci. Niezliczone godziny poświęcone na poznanie tego złożonego mechanizmu pozwoliły na takie przygotowanie dekoratorów, że nie było dla mnie formularza, którego bym nie zrobił przy pomocy Zend_Form. Wraz z przesiadką na Laravela, musiałem zmienić nawyki (jak się okazało na lepsze) tworzenia formularzy. Już w czwartej wersji tego frameworka formularze tworzyło i walidowało się niezwykle prosto. Jak się okazuje, można jeszcze prościej.

W temacie tworzenia formularzy można napisać bardzo dużo, więc dzisiaj skupię się tylko na ogólnych kwestiach, których rozwinięcie pojawi się w jednym z przyszłych wpisów na temat Laravela.

Piąta wersja frameworka wprowadziła nowy element o nazwie FormRequest. Dziedzicząc po tej klasie, otrzymujemy kompletny komponent, w którym zawieramy reguły walidacji oraz autoryzacji. Możemy również dodać własną obsługę odpowiedzi wysyłanej do użytkownika. Jeśli z jakiegoś powodu chcemy jeden formularz obsługiwać na różne sposoby, wystarczy że utworzymy klasę zawierającą ogólne zasady obsługi formularzy i rozszerzymy ją o kolejne klasy, zawierające specyficzną logikę, uzależnioną od sytuacji. Jak już wspomniałem, szczegóły obsługi formularzy opiszę niedługo w osobnym wpisie.

Helpery

Wraz z pojawieniem się Laravela 5, do dyspozycji otrzymamy nowe helpery. Najczęściej wykorzystywanymi będą helpery route’ów oraz widoku. Zaliczają się do nich funkcje: get, post, put, delete (odpowiedzialne za budowanie route’ów odpowiednio dla metod GET, POST, PUT oraz DELETE) oraz view, będący zamiennikiem View::make().

Innymi przydatnymi helperami są config (zwraca wartość powiązaną z przekazanym w parametrze kluczem) oraz redirect (przekierowuje na wskazany adres).

Middleware

Middleware to kolejna nowość w Laravel 5. Jego celem jest zastąpienie filtrów. Nie oznacza to, że filtry zostały całkowicie usunięte. Nadal można z nich korzystać, jednak preferowanym sposobem dekorowania requestów jest właśnie middleware.

Middleware generujemy przy pomocy komendy

php artisan make:middleware TestMiddleware

W efekcie otrzymamy klasę:

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Routing\Middleware;

class TestMiddleware implements Middleware {

	/**
	 * Handle an incoming request.
	 *
	 * @param  \Illuminate\Http\Request  $request
	 * @param  \Closure  $next
	 * @return mixed
	 */
	public function handle($request, Closure $next)
	{
		//
	}
}

Za obsługę odpowiada metoda handle, która przyjmuje dwa parametry – $request (tutaj raczej nie trzeba dodatkowych wyjaśnień) oraz $next, będąca funkcją anonimową odpowiedzialną za przekazanie requestu do kolejnych warstw aplikacji.

Jak skorzystać z middleware w aplikacji? Mamy dwie możliwości. Jeśli chcemy aby middleware był uruchamiany przy każdym requeście, musimy w klasie app/Http/Kernel.php dodać naszą klasę do tablicy $middleware. Drugim sposobem jest przypisanie middleware do konkretnego route’a (tak jak w przypadku filtrów).

Harmonogramowanie zadań

Laravel 5 dostarcza bardzo ciekawe rozwiązanie pozwalające na ustawianie harmonogramów zadań. Innymi słowy – zamiast dodawać do crona kolejne wpisy, wystarczy jeden. Resztą zajmie się framework.

php artisan schedule:run

Takie polecenie dodajemy do crona, by wykonywało się co minutę. Pozostałe cykliczne zadania definiujemy już w PHP. Najpierw musimy utworzyć klasę Command.

php artisan make:console TestCommand

Po wykonaniu powyższej komendy, otrzymamy klasę, w której zawieramy wymaganą logikę.

<?php namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

class TestCommand extends Command {

	protected $name = 'command:name';
	protected $description = 'Command description.';

	public function __construct()
	{
		parent::__construct();
	}

	public function fire()
	{
		echo 'IT works!';
	}

	protected function getArguments()
	{
		return [
			['example', InputArgument::REQUIRED, 'An example argument.'],
		];
	}

	protected function getOptions()
	{
		return [
			['example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null],
		];
	}
}

Na koniec wystarczy dodać do klasy app\Console\Kernel.php wywołanie naszej komendy wraz z czasem jej wykonania.

$schedule->command('command:name')
	 ->everyFiveMinutes();

Podsumowanie

Nie są to jedyne zmiany w Laravel 5. Piąta wersja wersja tego frameworka wprowadza szereg usprawnień, dzięki którym tworzenie aplikacji będzie jeszcze prostsze. Szkoda, że framework nie pojawi się w listopadzie. Z drugiej strony, lepiej poczekać kilka dodatkowych miesięcy i otrzymać skończony i przetestowany produkt. Ja już z niecierpliwością wyczekuję stabilnej wersji Laravela 5.