
Сегодня состоялся вход новой версии PHP фреймворка Laravel — 5.4! В новой версии были добавлены такие возможности, как поддержка Markdown-разметки для формирования электронных писем и уведомлений, улучшена поддержка Redis, добавлены новые возможности шаблонизатора Blade и множество других. Но обо всём по порядку.
Markdown-разметка для электронных писем и уведомлений
С поддержкой Markdown, Laravel теперь может генерировать красивые и адаптивные HTML шаблоны для электронных писем, а также генерирует обычную текстовую версию. Например, теперь Ваш код для генерирования письма может выглядеть так:
@component('mail::message') # Order Shipped Your order has been shipped! @component('mail::button', ['url' => $url]) View Order @endcomponent Next Steps: - Track Your Order On Our Website - Pre-Sign For Delivery Thanks,<br> {{ config('app.name') }} @endcomponent
Выглядеть это будет так:

Laravel Dusk
Laravel Dusk — это новая утилита для end-to-end тестирования приложений. По-умолчанию, для её использования не требуется установка JDK или Selenium. Вместо них, Dusk использует standalone версию ChromeDrive, но вы также можете использовать любой другой драйвер, совместивый с Selenium.
Поскольку Dusk использует реальный браузер для тестирования, Вы можете с лёгкостью тестировать и взаимодействовать с приложениями, в которых используется JavaScript:
/** * A basic browser test example. * * @return void */ public function testBasicExample() { $user = factory(User::class)->create([ 'email' => 'taylor@laravel.com', ]); $this->browse(function ($browser) use ($user) { $browser->loginAs($user) ->visit('/home') ->press('Create Playlist') ->whenAvailable('.playlist-modal', function ($modal) { $modal->type('name', 'My Playlist') ->press('Create'); }); $browser->waitForText('Playlist Created'); }); }
Компоненты и слоты для Blade шаблонизатора
Использование новых функций шаблонизатора Blade — компонентов и слотов — позволяет делать всё то, что вы привыкли делать с секциями и шаблонами. Однако, для некоторых разработчиков модель компонент-слот может показаться намного легче для понимания. Для начала, представим, что у нас есть компонент "alert", который мы хотим использовать в нашем приложении во всех шаблонах:
<!-- /resources/views/alert.blade.php --> <div class="alert alert-danger"> {{ $slot }} </div>
Переменная {{ $slot }} будет содержать тот контент, который мы захотим передать в компонент. Чтобы объявить этот компонент, мы использ��ем новую дериктиву @component:
@component('alert') <strong>Whoops!</strong> Something went wrong! @endcomponent
Именованыне слоты позволяют использовать несколько слотов в одном компоненте:
<!-- /resources/views/alert.blade.php --> <div class="alert alert-danger"> <div class="alert-title">{{ $title }}</div> {{ $slot }} </div>
Они передаются в компонент с использованием директивы @slot. Любой контент вне это директивы будет передан в компонент в качестве переменной $slot:
@component('alert') @slot('title') Forbidden @endslot You are not allowed to access this resource! @endcomponent
Broadcast Model Binding
Равно как и HTTP роуты, роуты для каналов прослушки событий теперь также могут использовать неявную привязку к модели. Например, вместо строки или числового ID, вы можете передать экземпляр модели (класса) Order:
use App\Order; Broadcast::channel('order.{order}', function ($user, Order $order) { return $user->id === $order->user_id; });
Сообщения высшего порядка в коллекциях (Higher order messages, HOM)
Коллекция теперь поддерживают сообщения высшего порядка, которые позволяют производить общие операции с коллекциями. Сейчас доступны следующие сообщения:
- contains
- each
- every
- filter
- first
- map
- partition
- reject
- sortBy
- sortByDesc
- sum
К каждому сообщению можно обратиться как к динамическому свойству экземпляра коллекции. Например, используем сообщение each, чтобы применить какой-либо метод к каждому объекту внутри коллекции:
$users = User::where('votes', '>', 500)->get(); $users->each->markAsVip();
Аналогичным образом, Вы можете использовать sum, чтобы, к примеру, посчитать количество голосов в коллекции с пользователями:
$users = User::where('group', 'Development')->get(); return $users->sum->votes;
Пользовательские обработчики событий Eloquent
Обработчики событий в Eloquent теперь могут быть привязаны к объектам событий. Это позволяет намного проще обрабатывать события Eloquent, а также упрощает тестирование этих событий. Чтобы использовать это нововведение, необходимо объявить свойство $events в классе Вашей модели, что позволит использовать Ваши собственные классы для обработки базовых событий Eloquent:
<?php namespace App; use App\Events\UserSaved; use App\Events\UserDeleted; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * The event map for the model. * * @var array */ protected $events = [ 'saved' => UserSaved::class, 'deleted' => UserDeleted::class, ]; }
Retry & Timeout для каждого процесса
Раньше, настройки "retry" и "timeout" устанавливались глобально для всех процессов командной строки. В Laravel 5.4, эти настройки теперь можно задавать для каждого процесса в индивидуальном порядке, определив их непосредственно в классе процесса:
<?php namespace App\Jobs; class ProcessPodcast implements ShouldQueue { /** * The number of times the job may be attempted. * * @var int */ public $tries = 5; /** * The number of seconds the job can run before timing out. * * @var int */ public $timeout = 120; }
Middleware для очистки запросов
В Laravel 5.4 появились два новых middleware'a (фильтра запросов): TrimStrings и ConvertEmptyStringsToNull
/** * The application's global HTTP middleware stack. * * These middleware are run during every request to your application. * * @var array */ protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];
Эти два фильтра автоматически убирают пробелы в начале и конце значений, а также конвертируют пустые строки в null, что позволяет нормализировать данные каждого запроса и забыть про постоянное использование функции trim в Вашем коде.
"Realtime" Фасады
Раньше, только поставляемые по-умолчанию Laravel сервисы предоставляли фасады, которые позволяли быстро и лаконично использовать свои методы через сервис-контейнер. В Laravel 5.4 появилась возможность легко конвертировать любой ваш класс в фасад в реальном времени. Представим, что у нас имеется следующий класс:
<?php namespace App\Services; class PaymentGateway { protected $tax; /** * Create a new payment gateway instance. * * @param TaxCalculator $tax * @return void */ public function __construct(TaxCalculator $tax) { $this->tax = $tax; } /** * Pay the given amount. * * @param int $amount * @return void */ public function pay($amount) { // Pay an amount... } }
Чтобы сделать его фасадом, достаточно лишь добавить префикс Facades:
use Facades\ { App\Services\PaymentGateway }; Route::get('/pay/{amount}', function ($amount) { PaymentGateway::pay($amount); });
Вы также можете писать тесты взаимодействи с использованием функции имитирования фасадов:
PaymentGateway::shouldReceive('pay')->with('100');
Пользовательские модели для связующих таблиц
В Laravel 5.3 все модели "связующих" таблиц для связей "many-to-many" использовали один и тот же экземпляр встроенной модели Pivot. В Laravel 5.4 вы можете определить свою модель для сводной таблицы после объявления связи следующим образом:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model { /** * The users that belong to the role. */ public function users() { return $this->belongsToMany('App\User')->using('App\UserRole'); } }
Улучшена поддержка кластеров Redis
Ранее не было возможность определить соединения Redis к одному хосту и кластерам в одном приложении. С Laravel 5.4 Вы можете определить несколько подключений к хостам и кластерам. Более подробно в документации к Redis.
Длинна строк по-умолчанию в миграциях
В Laravel 5.4 используется utf8mb4 в качестве кодировки по-умолчанию, которая поддерживает хранение эмодзи в базе данных. Если вы обновляетесь с Laravel 5.3, вам не нужно менять кодировку.
Если Вы всё же её меняете вручную или используете MySQL версии младше 5.7.7, вам необходимо вручную настроить длину строк по-умолчанию, которые генирируют миграции, с помощью метода Schema::defaultStringLength в вашем AppServiceProvider:
use Illuminate\Support\Facades\Schema; /** * Bootstrap any application services. * * @return void */ public function boot() { Schema::defaultStringLength(191); }
Поддержка JSON-формата в языковых файлах
В версии 5.4 добавилась возможность использовать JSON-формат для составления языковых файлов в приложениях. Они по-прежнему хранятся в директории resources/lang.
Например, если у вас есть русский перевод вашего проекта, вы можете создать ru.json в директории resources/lang, и его содержимое может выглядеть примерно так:
{ "I love Laravel!": "Я люблю Laravel!" }