Laravel 7 có gì mới?

Ngày 3/3/2020, Laravel team đã cho ra mắt version 7.0.0 với nhiều tính năng mới cũng như cải thiện tốc độ.

Kể từ version 6 thì Laravel và các package khác cùng hệ sinh thái đã chuyển sang dùng chuẩn Semantic Versioning, các bản cập nhật lớn sẽ được phát hành 6 tháng một lần (khoảng tháng 2 và tháng 8), các bản bản vá và các tính năng nhỏ không gây ảnh hưởng đến code cũ sẽ được cập nhật hàng tuần.

Do Laravel 7 không phải là bản được hỗ trợ dài hạn (LTS) nên chỉ được hỗ trợ vá lỗi 6 tháng (đến tháng 9/2020) và sửa lỗi bảo mật 1 năm (đến tháng 3/2021). Dưới đây là thời gian hỗ trợ cho các phiên bản:

VersionReleaseBug Fixes UntilSecurity Fixes Until
5.5 (LTS)30/8/201730/8/201930/8/2020
5.67/2/20187/8/20187/2/2019
5.74/9/20184/3/20194/9/2019
5.826/2/201926/8/201926/2/2020
6 (LTS)3/9/20193/9/20213/9/2022
73/3/20203/9/20203/3/2021

Laravel Airlock

Laravel Airlock được phát triển bởi Taylor Otwell.

Laravel Airlock cung cấp khả năng xác thực cho SPAs (single page applications), Mobile Apps, token based APIs.

1. Tạo API Token

Tính năng này tương tự OAuth nhưng ở mức đơn giản hơn), nó được lấy cảm hứng từ tính năng Access Token của Github.

Mỗi người dùng ứng dụng có thể tạo được nhiều API Token gắn với tài khoản của họ. Những API Token này có thể thiết lập được phạm vi truy cập, thời gian hết hạn cũng như xóa khỏi tài khoản bất cứ lúc nào.

2. SPA Authentication.

Laravel Airlock không sử dụng token để xác thực cho SPAs, thay vào đó Laravel Airlock xác thực qua cookie và session (giống như là một statefull application bình thường).

Bằng cách này SPA Authentication của Laravel Airlock cung cấp khả năng chống tấn công CSRF.

Chi tiết hơn về Laravel Airlock: https://laravel.com/docs/7.x/airlock

Custom Eloquent Casts

Laravel cung cấp sẵn rất nhiều kiểu dữ liệu cho Eloquent Casts nhưng đôi khi ứng dụng của bạn lại cần cast thuộc tính sang một định dạng dữ liệu riêng. Với Laravel 7 thì bạn có thể làm việc đó thông qua interface CastsAttributes

Class implemet CastsAttributes interface sẽ cần implement 2 phương thức là getset.

  • Phương thức get sẽ dùng để chuyển raw data từ database sang định dạng dữ liệu mong muốn.
  • Phương thức set sẽ dùng để chuyển dữ liệu về định dạng lưu ở database.

Tạo một Custom Elequent Cast

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Json implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return array
     */
    public function get($model, $key, $value, $attributes)
    {
        return json_decode($value, true);
    }
    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return json_encode($value);
    }
}

Sử dụng Custom Eloquent Cast trong Model

<?php

namespace App;

use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'options' => Json::class,
    ];
}

Xem thêm về Custom Eloquent Casts tại đây: https://laravel.com/docs/7.x/eloquent-mutators#custom-casts

Blade Component Tags & Improvements

Blade Component trong Laravel 7 được làm lại, linh hoạt hơn, dễ quản lý hơn.

Với Laravel 7, mỗi component có thể liên kết đến 1 Class, tất cả các thuộc tính và phương thức public trong Class này đều có thể truy cập từ component view. Một tính năng nữa đó là Tag based rendering, component có thể sử dụng dưới dạng HTML Tag, tất cả các html attribute được truyền vào component sẽ có thể truy cập qua biến $attribute ở component view.

Ví dụ về 1 component trong Laravel 7

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    /**
     * The alert type.
     *
     * @var string
     */
    public $type;
    /**
     * Create the component instance.
     *
     * @param  string  $type
     * @return void
     */
    public function __construct($type)
    {
        $this->type = $type;
    }
    /**
     * Get the class for the given alert type.
     *
     * @return string
     */
    public function classForType()
    {
        return $this->type == 'danger' ? 'alert-danger' : 'alert-warning';
    }
    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

Blade template của component:

<!-- /resources/views/components/alert.blade.php -->
<div class="alert {{ $classForType() }}" {{ $attributes }}>
    {{ $heading }}
    {{ $slot }}
</div>

Sử dụng component trong Blade template

<x-alert type="error" class="mb-4">
    <x-slot name="heading">
        Alert content...
    </x-slot>
    Default slot content...
</x-alert>

Xem thêm các tính năng của Component trong Laravel 7 tại đây: https://laravel.com/docs/7.x/blade#components

HTTP Client

HTTP Client dựa trên Guzzle HTTP Client, cung cấp một cách đơn giản để tương tác với các API.

Ví dụ sử dụng HTTP Client gửi requets POST

use Illuminate\Support\Facades\Http;
$response = Http::withHeaders([
    'X-First' => 'foo'
    'X-Second' => 'bar'
])->post('http://test.com/users', [
    'name' => 'Taylor',
]);
return $response['id'];

Testing với HTTP Client

Http::fake([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),
    // Stub a string response for Google endpoints...
    'google.com/*' => Http::response('Hello World', 200, ['Headers']),
    // Stub a series of responses for Facebook endpoints...
    'facebook.com/*' => Http::sequence()
                            ->push('Hello World', 200)
                            ->push(['foo' => 'bar'], 200)
                            ->pushStatus(404),
]);

Xem thêm về các tính năng của HTTP Client trong Laravel 7 tại đây: https://laravel.com/docs/7.x/http-client

Fluent String Operations

Việc thao tác với String trong PHP là theo kiểu hướng function nên rất dài dòng. Laravel 7 thêm mới đối tượng Illuminate\Support\Stringable giúp thao tác với String một cách hướng đối tượng, dễ đọc dễ hiểu hơn.

return (string) Str::of('  Laravel Framework 6.x ')
                    ->trim()
                    ->replace('6.x', '7.x')
                    ->slug();

Xem thêm tại đây: https://laravel.com/docs/7.x/helpers#fluent-strings

Route Model Binding Improvements

Key Customization

Auto resolve eloquent model từ route param bằng một field khác field id

Ở ví dụ dưới đây Laravel 7 sẽ tìm model Post bằng field slug

Route::get('api/posts/{post:slug}', function (App\Post $post) {
    return $post;
});

Route Caching Speed Improvements

Laravel 7 sử dụng một cách thức mới để tìm kiếm route phù hợp từ route cache từ đó có thể làm tăng tốc độ lên đến 2 lần.

Cải tiến này phát huy hiệu quả rõ nhất khi application có số lượng routes nhiều.

CORS Support

Laravel 7 bổ sung thêm 1 file config là cors.php, tất cả logic về CORS có thể config trong file này

<?php
return [
    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */
    'paths' => ['api/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => false,
    'max_age' => false,
    'supports_credentials' => false,
];

Xem thêm tại: https://laravel.com/docs/7.x/routing#cors

Ngoài những tính năng kể trên, Laravel 7 còn có rất nhiều tính năng mới và cải tiến, tham khảo thêm tại Release NotesLaravel 7 Documentation