Pull to refresh

Что нового в Laravel 5?

Reading time 10 min
Views 51K


Несколько месяцев назад в студии, где я работаю, было принято решение всей командой перебраться на Laravel. Последние пару лет популярность этого фреймворка неустанно росла, и, как оказалось, не напрасно!

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

Например, 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

Возможно я что-то упустил, тогда пишите в личку, я подправлю. Спасибо за внимание! Надеюсь статья была полезной.
Tags:
Hubs:
+32
Comments 90
Comments Comments 90

Articles