Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's new in Laravel 9

What's new in Laravel 9

Some of the new features we get in PHP's favourite framework: Laravel 9

E157a71a8b1585e6a33e2c6da01d4cac?s=128

Christian Leo-Pernold

March 10, 2022
Tweet

More Decks by Christian Leo-Pernold

Other Decks in Technology

Transcript

  1. What's new in Laravel 9

  2. About me — ! Christian Leo-Pernold — "#$%&'()*⛰,-. — /

    @mazedlx — ⭐ github.com/mazedlx — 1 mazedlx.net — 2 gusch.fredl.at 2/40
  3. Laravel 9 Released on 2022-02-08 3/40

  4. Minimum PHP Version 8.0 4/40

  5. Controller Route Groups 5/40

  6. // Laravel 8 use App\Http\Controllers\CustomerController; Route::get('customers', [CustomerController::class, 'index']); Route::get('customers/create', [CustomerController::class,

    'create']); Route::post('customers', [CustomerController::class, 'store']); Route::get('customers/{customer}', [CustomerController::class, 'show']); Route::get('customers/{customer}/edit', [CustomerController::class, 'edit']); Route::patch('customers/{customer}', [CustomerController::class, 'update']); 6/40
  7. // Laravel 9 use App\Http\Controllers\CustomerController; Route::controller(CustomerController::class)->group(function() { Route::get('customers', 'index'); Route::get('customers/create',

    'create'); Route::post('customers', 'store'); Route::get('customers/{customer}', 'show'); Route::get('customers/{customer}/edit', 'edit'); Route::patch('customers/{customer}', 'update'); }); 7/40
  8. Be!er php artisan route:list 8/40

  9. // Laravel 8 $ php artisan route:list +--------+----------+----------------------------------+-----------------------+------------------------------------------------------+---------------------------------------------------------+ | Domain

    | Method | URI | Name | Action | Middleware | +--------+----------+----------------------------------+-----------------------+------------------------------------------------------+---------------------------------------------------------+ | | GET|HEAD | / | episodes.index | App\Http\Livewire\Episodes\Index | web | | | GET|HEAD | backstage | backstage | App\Http\Livewire\Backstage | web | | | | | | | App\Http\Middleware\Authenticate | | | | | | | Spatie\ResponseCache\Middlewares\DoNotCacheResponse | | | GET|HEAD | episodes/create | episodes.create | App\Http\Livewire\Episodes\Create | web | | | | | | | App\Http\Middleware\Authenticate | | | | | | | Spatie\ResponseCache\Middlewares\DoNotCacheResponse | | | | | | | Illuminate\Auth\Middleware\Authorize:create,App\Episode | | | GET|HEAD | episodes/{episode}/edit | episodes.edit | App\Http\Livewire\Episodes\Edit | web | +--------+----------+----------------------------------+-----------------------+------------------------------------------------------+---------------------------------------------------------+ 9/40
  10. // Laravel 8 $ php artisan route:list +--------+----------+----------------------------------+-----------------------+------------------------------------------------------ +---------------------------------------------------------+ |

    Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------------------------------+-----------------------+------------------------------------------------------ +---------------------------------------------------------+ | | GET|HEAD | / | episodes.index | App\Http\Livewire\Episodes\Index | web | | | GET|HEAD | backstage | backstage | App\Http\Livewire\Backstage | web | | | | | | | App\Http\Middleware\Authenticate | | | | | | | Spatie\ResponseCache\Middlewares\DoNotCacheResponse | | | GET|HEAD | episodes/create | episodes.create | App\Http\Livewire\Episodes\Create | web | | | | | | | App\Http\Middleware\Authenticate | | | | | | | Spatie\ResponseCache\Middlewares\DoNotCacheResponse | | | | | | | Illuminate\Auth\Middleware\Authorize:create,App\Episode | | | GET|HEAD | episodes/{episode}/edit | episodes.edit | App\Http\Livewire\Episodes\Edit | web | +--------+----------+----------------------------------+-----------------------+------------------------------------------------------ +---------------------------------------------------------+ 10/40
  11. // Laravel 8 $ php artisan route:list -c +----------+----------------------------------+------------------------------------------------------+ |

    Method | URI | Action | +----------+----------------------------------+------------------------------------------------------+ | GET|HEAD | / | App\Http\Livewire\Episodes\Index | | GET|HEAD | backstage | App\Http\Livewire\Backstage | | GET|HEAD | episodes/create | App\Http\Livewire\Episodes\Create | | GET|HEAD | episodes/{episode}/edit | App\Http\Livewire\Episodes\Edit | | GET|HEAD | feed | App\Http\Controllers\FeedController | | GET|HEAD | livewire/livewire.js | Livewire\Controllers\LivewireJavaScriptAssets@source | | GET|HEAD | livewire/livewire.js.map | Livewire\Controllers\LivewireJavaScriptAssets@maps | | POST | livewire/message/{name} | Livewire\Controllers\HttpConnectionHandler | | GET|HEAD | livewire/preview-file/{filename} | Livewire\Controllers\FilePreviewHandler@handle | | POST | livewire/upload-file | Livewire\Controllers\FileUploadHandler@handle | | GET|HEAD | login | App\Http\Livewire\Auth\Login | | GET|HEAD | preview/{episode} | App\Http\Livewire\Episodes\Index | | GET|HEAD | {episode} | App\Http\Livewire\Episodes\Index | +----------+----------------------------------+------------------------------------------------------+ 11/40
  12. // Laravel 9 $ php artisan route:list GET|HEAD posts ................................................

    posts.index › PostController@index POST posts ................................................ posts.store › PostController@store GET|HEAD posts/create ....................................... posts.create › PostController@create GET|HEAD posts/{post} ........................................... posts.show › PostController@show PATCH posts/{post} ....................................... posts.update › PostController@update GET|HEAD posts/{post}/edit ...................................... posts.edit › PostController@edit POST posts/{post}/pin .......................................... posts.pin › PinPostController POST posts/{post}/publish .............................. posts.publish › PublishPostController POST posts/{post}/unpin .................................... posts.unpin › UnpinPostController 12/40
  13. Anonymous Migration Classes 13/40

  14. use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends

    Migration { public function up() { Schema::create('tablename', function (Blueprint $table) { $table->id(); $table->timestamps(); }); } public function down() { Schema::dropIfExists('tablename'); } }; 14/40
  15. New Helper Functions 15/40

  16. // str() - alias for Illuminate\Support\Str::of($string) str('hello')->append(' world!); // to_route()

    - equivalent to redirect()->route($route) return to_route('home'); 16/40
  17. Refreshed Ignition Error Pages 17/40

  18. 18/40

  19. 19/40

  20. 20/40

  21. Yes, of course there is a Dark Mode 21/40

  22. 22/40

  23. Render Blade String 23/40

  24. Route::get('/', function () { return Blade::render('{{ $greeting }}, World!', [

    'greeting' => 'Hello', ]); }); 24/40
  25. Forced Scope Bindings 25/40

  26. // Scopes the second Eloquent model // that it must

    be a child of the first Eleoquent model Route::get('users/{user}/posts/{post}', function (User $user, Post $post) { return $post; })->scopeBindings(); 26/40
  27. Test Coverage 27/40

  28. $ php artisan test --coverage Console/Kernel ............................................................................ 100.0 % Exceptions/Handler

    ........................................................................ 100.0 % Http/Controllers/Controller ............................................................... 100.0 % Http/Kernel ............................................................................... 100.0 % Http/Middleware/Authenticate ................................................................. 0.0 % Http/Middleware/EncryptCookies ............................................................ 100.0 % Http/Middleware/PreventRequestsDuringMaintenance .......................................... 100.0 % Http/Middleware/RedirectIfAuthenticated ...................................................... 0.0 % Http/Middleware/TrimStrings ............................................................... 100.0 % Http/Middleware/TrustHosts ................................................................... 0.0 % Http/Middleware/TrustProxies .............................................................. 100.0 % Http/Middleware/VerifyCsrfToken ........................................................... 100.0 % Models/User ............................................................................... 100.0 % Providers/AppServiceProvider .............................................................. 100.0 % Providers/AuthServiceProvider ............................................................. 100.0 % Providers/BroadcastServiceProvider ........................................................... 0.0 % Providers/EventServiceProvider ............................................................ 100.0 % Providers/RouteServiceProvider 51 ........................................................... 90.9 % Total Coverage .............................................................................. 57.7 % 28/40
  29. $ php artisan test --coverage --min=90 Console/Kernel ............................................................................ 100.0 %

    Exceptions/Handler ........................................................................ 100.0 % Http/Controllers/Controller ............................................................... 100.0 % Http/Kernel ............................................................................... 100.0 % Http/Middleware/Authenticate ................................................................. 0.0 % Http/Middleware/EncryptCookies ............................................................ 100.0 % Http/Middleware/PreventRequestsDuringMaintenance .......................................... 100.0 % Http/Middleware/RedirectIfAuthenticated ...................................................... 0.0 % Http/Middleware/TrimStrings ............................................................... 100.0 % Http/Middleware/TrustHosts ................................................................... 0.0 % Http/Middleware/TrustProxies .............................................................. 100.0 % Http/Middleware/VerifyCsrfToken ........................................................... 100.0 % Models/User ............................................................................... 100.0 % Providers/AppServiceProvider .............................................................. 100.0 % Providers/AuthServiceProvider ............................................................. 100.0 % Providers/BroadcastServiceProvider ........................................................... 0.0 % Providers/EventServiceProvider ............................................................ 100.0 % Providers/RouteServiceProvider 51 ........................................................... 90.9 % Total Coverage .............................................................................. 57.7 % FAIL Code coverage below expected: 57.7 %. Minimum: 90.0 %. 29/40
  30. Laravel Scout Database Engine 30/40

  31. No need for Algolia or MeiliSearch* * depending on how

    many records you have 31/40
  32. Full Text Indexing for MySQL and PostgreSQL 32/40

  33. Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('body')->fulltext(); $table->timestamps(); });

    Post::whereFullText('body', 'search')->get(); 33/40
  34. Enum A!ribute Casting 34/40

  35. enum PostState: string { case Draft = 'draft'; case Published

    = 'published'; case Archived = 'archived'; } Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('body')->fulltext(); //$table->enum('state', ['draft', 'published', 'archived']); $table->string('state')->default('draft'); $table->timestamps(); }); 35/40
  36. class Post extends Model { protected $casts = [ 'state'

    => PostState::class, ]; } 36/40
  37. Simplified Accessors and Mutators 37/40

  38. // Laravel 8 class User extends Model { public function

    getFirstNameAttribute() { return ucfirst($this->first_name); } public function setFirstNameAttribute($value) { $this->attributes['first_name'] = strtolower($value); } } 38/40
  39. // Laravel 9 use Illuminate\Database\Eloquent\Casts\Attribute; class User extends Model {

    public function firstName(): Attribute { return new Attribute( get: fn ($value) => ucfirst($value), set: fn ($value) => strtolower($value), ); } } 39/40
  40. 40/40