Що нового в Laravel 5?



Кілька місяців тому в студії, де я працюю, було прийнято рішення всією командою перебратися на Laravel. Останні кілька років популярність цього фреймворку невпинно зростала, і, як виявилося, не даремно!

Я не вважаю себе гуру в php і фреймворках. До цього кілька разів працював з першим і другим зенден, безсмертним битриксом, стикався з Yii і Symphony, винаходив велосипеди сам, але кожен раз у мене залишалося неясне почуття незадоволеності.

Наприклад, Zend Framework завжди викликав у мене бажання швидше виконати завдання і забути про нього як про страшний сон. Прихильники цього фреймворку звичайно не погодяться зі мною, і я ні в якому разі не хочу критикувати їх вибір. Кожному своє. У мене Zend Framework завжди викликав відчуття, що код писався не людьми і не для людей.

Мені завжди здавалося, що ті ж самі завдання можна вирішувати більш просто і елегантно. Хотілося знайти фреймворк, на якому мені б подобалося писати. Який я зміг би вивчити як свої п'ять пальців і займатися тим, чим мені і подобається займатися — програмуванням, створенням чогось нового. Я думаю, у кожного тесляра є улюблений молоток, і таке бажання для програміста цілком природно. Хто з нас, тих хто пише на php, не поглядав з заздрістю на Rails в Ruby або Django в Python?

Останньою краплею став пост від JetBrains про розширеної підтримки у новій версії PhpStorm 8 шаблонів Blade і Source & Test directories. У цій IDE ми і створили перший проект на Laravel.

Попрацювавши з Laravel, я зрозумів, що знайшов те, що шукав. Напевно, саме тому символом Laravel став слоган «You have arrived».

З першого дня він не перестає мене приємно дивувати, від документації, спільноти (коли я зіткнувся з проблемою при написанні цієї статті, я зайшов в чат онлайн спільноти, описав проблему і відповів мені особисто(!) Taylor Otwell, творець фреймворку) і туториалов, до різних булочок, які можна і потрібно використовувати вже після розміщення проекту на сервері.

Але моя стаття не про це. Про плюси Laravel написано вже достатньо.

У цій статті я хотів би написати про нової версії Laravel, офіційний реліз якої відбудеться в листопаді, але скачати і спробувати яку можна вже зараз через Composer.

Спочатку версія повинна була називатися 4.3, але нова структура директорій і деякі суттєві зміни в коді підштовхнули творців до вирішення анонсувати версію 5.0.

Наскільки серйозними були ці зміни судити вам. Отже, давайте на ділі розберемося, що нам готує Laravel 5.

Установка

Установка нової версії по суті нічим не відрізняється від старої. Для початку скачайте Laravel 5, додавши у файл composer.json рядок

"require": {
//...
"laravel/framework": "5.0.*@dev"
//...
}


Після цього запустіть composer update, і після закінчення операції у вас буде встановлена остання версія.



Структура

Якщо подивитися на структуру Laravel 4 і Laravel 5 то відразу можна помітити різницю. Насамперед, папки Config, Tests, Storage і Database були винесені з папки App в корінь. З'явилася нова директорія resources.



Виникає логічне запитання: а що залишилося в папці App?

Тепер в папці App зберігається тільки логіка самого додатка. Таким чином розробники узаконили те, що і так робили більшість розробників на Laravel до цього — видалили папку model і створили окрему директорію для всього, що пов'язане з розробкою цього конкретного проекту — моделі, команди, події тощо. Насамперед, це дозволяє чітко провести межу між кодом самого фреймворку і кодом, який пише сам розробник.

У папці App за замовчуванням знаходиться 3 нові директорії. Директорія Console призначена для класів консольних команд, папка Service Providers містить класи-постачальники послуг, папка Http містить контролери, фільтри і все, що пов'язано з роутингом.



У свою чергу, в директорії Http лежить 3 папки — Controllers для контролерів програми, Filters для фільтрів маршрутів, які тепер створюються у вигляді окремих класів, і папки Requests, про яку я докладно розповім нижче.
Папка View була перенесена в директорію Resources, разом з папкою локалізації Lang.
Кому-то нова структура може здатися незвичною, але по собі можу сказати, що вже через пару днів ви зрозумієте, що так набагато зручніше.

Перше питання, яке найімовірніше виникне у вас у зв'язку із зміною структури: а що стало з просторами імен і автозавантаженням класів?

Простору імен
До моєї великої радості, Laravel 5 офіційно використовує стандарт psr-4, а значить кожен клас в папці App, у якого буде правильно задано простір імен буде доступний для автозавантажувач.
Тому просто переконайтеся, що кожен клас в цій папці починається з App\*назва директорії і назавжди забудьте про проблеми з завантаженням файлів.

З іншого боку, використання psr-4 означає, що доступ до фасадів тепер вимагає звернення з глобального простору імен, наприклад \Auth::*ім'я методу* або \Events::*ім'я методу*.
У зв'язку з цим, фасади тепер необхідно імпортувати командою use \имяфасада (наприклад \View) на початку файлу або звертатися до них через зворотній слеш.

Крім цього, тепер необхідно вказувати простору імен для контролерів. Тому переконайтеся, що кожен ваш контролер містить рядок
namespace App\Http\Controllers;

і використовує простір імен абстрактного контролера
use Illuminate\Routing\Controller;


Якщо ви використовуєте BaseController як батьківський клас всіх ваших контролерів, то ви можете винести останню сходинку туди, так всі ваші контролери отримають доступ до цього простору імен.

Коренева папка програми
Якщо ви не хочете звертатися до основної папці вашого застосування як до App? Якщо ви звикли називати директорію, в якій зберігається логіка програми, по назві самого додатка, як робили багато в Laravel 4?

Розробники передбачили і це. Вам достатньо просто написати в командному рядку $ php artisan app:name і бажане ім'я вашого додатка. Laravel самостійно змінить простору імен в необхідних файлах, а також налаштування у файлах конфігурації.

Якщо ви хочете використовувати вкладену теку, то використовуйте два зворотних слеша, наприклад
$ php artisan app:name MyAppName\\HabrProject


До речі, в папці Config з'явився новий файл namespaces.php, в якому прописується простір імен для програми в цілому та шляхи до файлів. Стати в нагоді, якщо будуть проблеми з автозавантаженням!

Впровадження параметрів методу
Ще одним потужним нововведенням Laravel 5 стало впровадження параметрів методу (Method Parameter Injection або просто Method Injection).
Раніше, якщо в контролері нам потрібен був якийсь клас моделі, наприклад репозиторій, ми могли використовувати Ioc Container Dependency Injection, тобто передати назва класу в конструктор контролера і привласнити його властивості об'єкта.
Ioc контейнер самостійно створював екземпляр даного класу і повертав до властивість контролера, через який ми отримували до нього доступ. І це було круто.

Наприклад, так:

class FeedController extends BaseController {
protected $feedbackRepository;
/**
* @param FeedbackRepository $feedbackRepository
*/
public function __construct(FeedbackRepository $feedbackRepository)
{
$this->feedbackRepository = $feedbackRepository;
}
public function index($id)
{
$feed = $this->feedbackRepository->getFeed($id);
return View::make('feed.index', compact('feed'));
}

Однак якщо об'єкт потрібен нам тільки в одному методі? Навіщо створювати в конструкторі цілого контролера экзмепляр об'єкта, якщо він буде використаний тільки в одному його методі
Тому в Laravel 5 з'явилося впровадження параметра методу!
Тепер в будь-якому методі контролера можна вказати клас, і ви автоматично отримаєте доступ до його методів через Ioc контейнер. Наш приклад тепер виглядав би так:

class FeedController extends BaseController {
public function index(FeedbackRepository $feedRepo, $id){
$feed = $feedRepo->getFeed($id);
Return view('feed.index', compact('feed')
}
}

І все! Чарівним чином Ioc контейнер сам знайде і підключить мій репозиторій.

Але справжню міць цього нововведення можна відчути в сукупності з іншою нової фичей:

Запити (Requests) та запити до формі (FormRequests)
Пам'ятаєте, я говорив про папку Requests в директорії App\Http? Ось ми, нарешті, дісталися до неї.
Давайте згадаємо, як ми здійснювали перевірку введених користувачем даних при відправці форми в Laravel 4.2.

Якщо ви працювали з Laravel, то вам безумовно знаком фасад Validator.
Він надає потужний функціонал валідації даних, отриманих від користувача. Однак кожен розробник використав його по-різному. Хтось використовував валідатор прямо в контролері,
хтось прописував правила валідації в моделі (масив rules[]) і використовував метод isValid.

Тепер про це можна забути: Laravel надає окремий рівень абстракції для обробки запитів до форми.
Давайте розберемося, як це працює.
У командному рядку наберіть php artisan make:request MyRequest і фреймворк самостійно згенерує для вас шаблон запиту до форми.

У даному класі, який успадковує клас FormRequest, міститься всього 2 методу: authorize і rules.
Rules повертає масив, в якому ви можете прописати правила валідації для своєї форми, зовсім як у Laravel 4.
Метод authorize за замовчуванням повертає false.
Якщо зараз ми спробуємо відправити форму, пов'язану з цим класом, в браузері ми отримаємо сторінку forbidden(заборонено).

Так от, метод authorize перевіряє, чи має право користувач, який звертається до форми, її надсилати. Наприклад, чи має користувач право редагувати статтю, яку написав не він? Постити коментар, якщо він не залягання? Це саме те місце, куди тепер потрібно поміщати перевірки.

Припустимо, у нас є форма, яка публікує статус на стіну користувача. Ми хочемо, щоб поле статус (звичайний input type ='text' name ='status') було обов'язковим для заповнення та містило, скажімо, 20 символів. Нам також потрібно перевірити, що користувач публікує статус на свою стіну, тобто id сторінки користувача збігається з id автора посту.
У цьому прикладі наш клас-валідатор виглядав би так.

namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use \Auth;
class AddFeedRequest extends FormRequest {

public function rules()
{
return [
'status' => 'required|min:20',
];
}

public function authorize()
{
return Auth::id() == $this->route->parameter('id');
}

Тепер з допомогою впровадження параметра методу, про який ми говорили вище, нам досить просто вказати назву класу в параметрах методу контролера, відповідального за відправку форми.
Якщо ми використовуємо REST контролер, то це буде метод store.

public function store(MyRequest $request)
{
//код відправляє форму
}

І все! Більше нічого робити не потрібно! Laravel сам здійснить валідацію форми і виконає код, що міститься в методі контролера, якщо валідація пройде успішно. Ще раз: ні єдина рядок коду з методу store не буде виконана, якщо форма не проходить валідацію. На мій погляд, це неймовірно круто!

Генератори
Якщо ми наберемо в командному рядку php artisan ми побачимо цілий новий розділ, який називається make:
Ми вже скористалися одним з них, для генерації класу myRequest. Крім цього, команда make: допоможе створити контролер, консольну команду,
фільтр, міграцію, постачальника послуг.

Особливо хочу виділити команду php artisan make:auth. Цей генератор зробить за вас те, що ви робили знову і знову в кожному новому проекті — систему авторизації користувача.

Якщо ми виконаємо її зараз, ми побачимо, що Laravel створить для нас два контролера — один відповідає за авторизацію, другий — за відновлення пароля, міграцію password resets, 2 класу-валідатора для запитів login і register. Всього одна команда і шаблон для авторизації готовий!

Кешування маршрутів
Команда routes теж розрослася в цілий розділ. Тепер щоб подивитися список маршрутів потрібно ввести php artisan route:list.
Тут важко не помітити нову команду route:cache. Вона робить дуже просту річ — кешує ваші маршрути.
Якщо виконати цю команду, ви побачите, що в папці storage/meta з'явився файл routes.php. У ньому міститься кеш ваших маршрутів. Тепер Laravel буде в першу чергу звертатися до нього, а не до основного файлу http/routes.php.

При розробці це навряд чи знадобиться, принаймні, мені складно уявити таку ситуацію, а ось при деплое, коли проект вже написаний і нові маршрути додаються рідко, це може бути дуже корисним.

Контракти
Всі компоненти Laravel 5 тепер реалізують той чи інший інтерфейс з папки illuminate/contracts. Таким чином розробники спробували зробити ваш додаток більш гнучким і менш залежним від самого Laravel.

У Laravel 4 часто виникали проблеми з type-hinting-му інтерфейсів. Якщо ви вказували в параметрах методу екземпляр об'єкта, який повинен реалізовувати якийсь інтерфейс, Ioc контейнер розглядав його як dependency injection і намагався створити екземпляр класу, що призводило до помилок.

Щоб вирішити цю проблему потрібно було безпосередньо пов'язувати інтерфейс з конкретним класом-реалізацією інтерфейсу з допомогою app::bind. Однак це все одно викликало деякі проблеми, наприклад при unit-тестуванні.
У Laravel 5 досить використовувати інтерфейс на початку файлу з допомогою use (наприклад use Illuminate\Contracts\Mailer) і type-hinting буде працювати як треба.

Це дозволяє писати більш гнучкі програми, не прив'язуючись до конкретних класів-реалізацій.

Якщо надалі ви захочете підключити інший модуль авторизації, відмінний від стандартного модуля Laravel? Інший модуль кешування? Відправлення листів? Просто переконайтеся, що він реалізує інтерфейс з папки contracts і пишіть код, спираючись на type-hinting інтерфейсів.

Нові функції помічники
Дрібниця, яку ви будете знову і знову використовувати в своїх проектах: підключення файлів подання тепер доступно через функцію view('имяпредставления'). Старий спосіб View::make теж працює, але тепер до нього, як я вже сказав вище, потрібно звертатися через зворотній слеш.

Така ж доля спіткала і Redirect::to — тепер можна просто писати redirect('маршрут').

З інших змін у звичних інструментах роботи варто згадати і те, що фасади HTML Form тепер не входять в стандартний пакет Laravel. Не бійтеся, якщо ви до них звикли, ви без праці зможете підключити їх через composer.

Socialite
У Laravel 5 з'явився власний модуль Socialite Beta, який призначений для аутентифікації сторонніх сервісів, таких як Twitter, Facebook, GitHub. Нам доводилося досить часто дописувати плагіни для авторизації під різні соціальні мережі і як було б здорово, якби в інших фреймворках були подібні інструменти. Плагін є опціональним та додати його достатньо лише підключити залежність. Посудіть самі, потрібно всього лише створити конфіг провайдера і після цього усі необхідні методи будуть доступні у вигляді:

$this->socialite->driver('twitter')->user();

Все, що для цього потрібно зробити, це підключити відповідний клас на початку вашого файлу:
use Laravel\Socialite\Contracts\Factory as SocialiteFactory;
Найближчим часом плануємо дописати авторизацію і для vk.

Blade
Із змін Blade, є одна суттєва, з-за якого співтовариство за останні пару днів створило десятки однотипних питань. Тепер і тег {{ link_to_route('login_path') }} і тег{{{ link_to_route('login_path') }}} будуть екрануватися і виводитися як текст, щоб знизити ризик ін'єкцій коду.

Замість цього доведеться використовувати конструкцію {!!! link_to_route('login_path') !!}. До речі, для полегшення переходу на нову версію Blade можна замінити теги на старі:
Blade::setRawTags($openTag, $closeTag);
Тоді не доведеться переписувати всі вистави.



Резюме

П'ята версія саме та версія, з якою тепер слід починати знайомство з Laravel, якщо ви все ще відкладаєте цей хвилюючий момент. Переважна більшість плагінів вже підтримує нову версію фреймворку, а до релізу буде готова вичерпна документація. Laravel на мій погляд, це найбільш цікавий і перспективний проект в php-співтоваристві за останній час. Приємно бачити, як з кожним днем він привертає все більше прихильників.

Якщо ви хочете детальніше дізнатися про Laravel, ось кілька корисних ресурсів:

laravel.com
laravel.io
laracasts.com

Можливо я щось пропустив, тоді пишіть в лічку, я підправлю. Спасибі за увагу! Сподіваюся стаття була корисною.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.