TL;DR: On Wednesday, February 7, 2018, Laravel 5.6, was released to the public. It's a major release to the most popular PHP framework on GitHub as of this writing. Furthermore, Spark 6.0 was also released alongside Laravel 5.6. According to the policy laid down by the Taylor and the core team, major Laravel framework releases are released every six months (February and August). In this article, I'll cover the new features in Laravel 5.6 and several other changes and deprecations.


Laravel is the most popular, open-source PHP framework as of this writing. It is designed for building web applications with an expressive and elegant syntax. With Laravel, application development is fast because it ships with a lot of features out of the box. Without further ado, let's dive right into Laravel 5.6.

What's new in Laravel 5.6?

1. Support For Argon Password Hashing

Argon2, the recommended password hashing algorithm by the Password Hashing Competition, is a modern algorithm for securely hashing passwords. And it comes in two distinct flavors, Argon 2i and Argon 2d. PHP 7.2 recently added support for Argon 2i password hashing. Therefore, Michael Lundbol took the initiative to add support for Argon hashing in Laravel.

Argon Password Hashing Support Initiative to add Argon Password Hashing

The bcrypt driver is the default driver for password hashing in Laravel. However, Laravel 5.6 now supports argon.

Config File for Hashing Config file for hashing

Note: Laravel 5.6 ships with a hashing config file as displayed above.

2. Better Support For Dynamic Rate Limiting

One of the beautiful built-in features of Laravel is API Rate Limiting. Before now, Laravel's rate limiting configuration involved specifying a hard-coded number of requests on a group of routes. However, Laravel 5.6 adds icing to the cake by allowing you specify a maximum number of requests based on an authenticated User model attribute.

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    Route::get('/users', function () {
        // do something awesome
    });
});

In the code above, the rate_limit parameter is an attribute of the User model in a Laravel 5.6 application.

3. Model Serialization on Steriods

Before now, there was a persistent bug on queued models. When queued models are finally processed, it's without their loaded relationships in place.

In Laravel 5.6, huge improvements have been made to ensure that relationships loaded on queued models are automatically re-loaded when the job is processed by the queue.

4. Improved Logging

There is a new logging config file in Laravel 5.6. In this file, you can set up logging stacks that send log messages to various handlers.

Check out the example below:

'channels' => [
  'stack' => [
      'driver' => 'stack',
      'channels' => ['syslog', 'slack'],
  ],

  'syslog' => [
      'driver' => 'syslog',
      'level' => 'debug',
  ],

  'slack' => [
      'driver' => 'slack',
      'url' => env('LOG_SLACK_WEBHOOK_URL'),
      'username' => 'Laravel Log',
      'emoji' => ':boom:',
      'level' => 'critical',
  ],
],

The stack driver allows you to combine multiple channels, in this case, syslog and slack, into a single log channel as shown above.

Furthermore, with the tap array on a channel's configuration, you can easily customize Monolog for an existing channel like so:

'single' => [
    'driver' => 'single',
    'tap' => [App\Logging\CustomizeFormatter::class],
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],

Note: Monolog is a library that sends your application logs to files, sockets, inboxes, databases and various web services. It's a comprehensive library with various log handlers.

Check out more information on Logging in Laravel 5.6.

5. Single Server Task Scheduling

Before now, if your app ran on multiple servers and the task scheduler was active on those servers, then your scheduled tasks also executed multiple times. However, in Laravel 5.6, you can now schedule your task to execute on just a single server if your app runs on multiple servers.

" In Laravel 5.6, you can now schedule your task to execute on just a single server if your app runs on multiple servers."

$schedule->command('launch:flasheavy')
         ->tuesdays()
         ->at('12:00')
         ->onOneServer();

6. Beautiful Error Reporting With Collision

Collision is an awesome package developed and maintained by Nuno Maduro. It is a detailed, beautiful and intuitive error handler for console/command-line PHP applications.

Laravel 5.6 now ships with Collision via the dev composer dependency. When working with your Laravel app via the command line, Collision provides an awesome error reporting interface like so:

Collision Integration Collision Integration with Laravel 5.6

7. Elevated Eloquent Date Formatting

Laravel 5.6 provides a subtle way to cast Eloquent date model attributes to a specific date format. All you need to do is to specify the desired date format in the $casts array.

"Laravel 5.6 provides a subtle way to cast Eloquent date model attributes to a specific date format."

Now, you can customize the date model attributes like so:

protected $casts = [
  'date_enrolled' => 'date:Y-m-d',
  'date_evicted' => 'datetime:Y-m-d H:00',
];

When the model is cast to JSON or array output, the attributes will be formatted to the date formats example provided above like so:

date_enrolled: 2005-02-19
date_evicted: 2018-02-20 8:30

8. Aliasing Blade Components For Easier Access

This feature is very handy. Accessing a blade component in a sub-directory is easier via aliasing. With the component method, you can alias components.card to card assuming the card component's directory is resources/views/components/card.blade.php.

Blade::component('components.card', 'card');

Once it has been aliased, you can invoke the component like so:

@card
  This is your Valentine card.
@card

9. Broadcasting Channel Classes

In Laravel 5.6, you can now generate broadcasting channel classes via the make:channel Artisan command. The generated channel class will be placed in the App/Broadcasting directory.

php artisan make:channel PurchaseChannel

Registering the channel is as easy as calling the Broadcast::channel method below in the routes/channel.php file:

use App\Broadcasting\PurchaseChannel;

Broadcast::channel('purchase.{purchase}', PurchaseChannel::class);

In the PurchaseChannel class, you can add the authorization logic in the join method. Before now, the authorization logic was placed in the channel authorization Closure.

<?php

namespace App\Broadcasting;

use App\User;
use App\Purchase;

class PurchaseChannel
{

  ....

  /**
   * Authenticate the user's access to the channel.
   *
   * @param  \App\User  $user
   * @param  \App\Purchase $purchase
   * @return array|bool
   */
  public function join(User $user, Purchase $purchase)
  {
      return $user->id === $purchase->user_id;
  }
}

10. Daring Upgrade Of Symfony Components and Bootstrap

All the Symfony components used by Laravel 5.6 have been bumped to the ~4.0 release. Furthermore, all the front-end scaffolding of Laravel 5.6 and Spark 6.0 has been bumped to v4.

I covered all the major additions and deprecations of Bootstrap 4 in this article.

Deprecations and Other Updates

  • Generating an API resource controller can now be done by using the --api switch when executing the make:controller command.
  • Laravel 5.6 introduced helper methods, Arr::wrap(), classes_uses_recursive(), Str::uuid(), and Str::orderedUuid(), the latter generating a timestamp first UUID that's more easily and efficiently indexed by databases like MySQL.
  • PHPUnit, upgraded to v7.
  • Laravel Mix, upgraded to v2.
  • The deprecated Artisan optimize command has been removed.
  • Added support for customizing the mail message building in ResetPassword::toMail().
  • Add policies() method to AuthServiceProvider to retrieve all the policies defined by the provider.
  • Two new blade directives have been added to the framework, @csrf and @method.
  • Support for PostgreSQL comments was added. Furthermore, Laravel 5.6 now has better support for enumeration columns.

Check out other Laravel 5.6 updates here.

Upgrading to Laravel 5.6

Laravel 5.6 requires PHP >= 7.1.3. And the estimated upgrade time from Laravel v5.5 is about ten to thirty minutes.

Check out this comprehensive upgrade guide. However, if you don't want to be bothered about manually configuring and changing files for the upgrade, I recommend using Laravel Shift - A service that provides automated, instant Laravel upgrade services by an army of thorough bots and friendly humans.

Laravel Shift Laravel Shift

Aside: Securing Laravel APIs with Auth0

Securing Laravel APIs with Auth0 is very easy and brings a lot of great features to the table. With Auth0, we only have to write a few lines of code to get:

Sign Up for Auth0

You'll need an Auth0 account to manage authentication. You can sign up for a free account here. Next, set up an Auth0 API.

Set Up an API

Go to APIs in your Auth0 dashboard and click on the "Create API" button. Enter a name for the API. Set the Identifier to a URL(existent or non-existent URL). The Signing Algorithm should be RS256.

Create API on Auth0 dashboard Create API on Auth0 dashboard

We're now ready to implement Auth0 authentication on our Laravel backend API.

Dependencies and Setup

Install the laravel-auth0 package via composer like so:

composer require auth0/login:"~5.0"

Generate the laravel-auth0 package config file like so:

php artisan vendor:publish

After the file is generated, it will be located at config/laravel-auth0.php. Ensure you replace the placeholder values with the authentic values from the Auth0 Admin Dashboard. Double check your values with laravel-auth0.

Your .env file should have the AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET and AUTH0_CALLBACK_URL values like so:

AUTH0_DOMAIN=kabiyesi.auth0.com
AUTH0_CLIENT_ID=xxxxxxxxxxxxxxxxxx
AUTH0_CLIENT_SECRET=xxxxxxxxxxxxxxxxx
AUTH0_AUDIENCE=http://mylaravelapi.com
AUTH0_CALLBACK_URL=null

Activate Provider and Facade

The laravel-auth0 package comes with a provder called LoginServiceProvider. Add this to the list of application providers.

// config/app.php
'providers' => array(
    // ...
    \Auth0\Login\LoginServiceProvider::class,
);

If you would like to use the Auth0 Facade, add it to the list of aliases.

// config/app.php

'aliases' => array(
    // ...
    'Auth0' => \Auth0\Login\Facade\Auth0::class,
);

The user information can now be accessed with Auth0::getUser(). Finally, you need to bind a class that provides a user (your app model user) each time the user is logged in or an access_token is decoded. You can use the Auth0UserRepository provided by this package or you can build your own class.

To use Auth0UserRepository, add the following lines to your app's AppServiceProvider:

// app/Providers/AppServiceProvider.php

public function register()
{

    $this->app->bind(
      \Auth0\Login\Contract\Auth0UserRepository::class, 
      \Auth0\Login\Repository\Auth0UserRepository::class
    );

}

Configure Authentication Driver

The laravel-auth0 package comes with an authentication driver called auth0. This driver defines a user structure that wraps the normalized user profile defined by Auth0. It doesn't actually persist the object but rather simply stores it in the session for future calls.

This is adequate for basic testing or if you don't have a requirement to persist the user. At any point you can call Auth::check() to determine if there is a user logged in and Auth::user() to retreive the wrapper with the user information.

Configure the driver in config/auth.php to use auth0.

// app/config/auth.php

// ...
'providers' => [
    'users' => [
        'driver' => 'auth0'
    ],
],

Secure API Routes

Your API routes are defined in routes/api.php for Laravel 5.3+ apps.

// routes/api.php

<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::get('/public', function (Request $request) {
  return response()->json(["message" => "Hello from a public endpoint! You don't need any token to access this URL..Yaaaay!"]);
});

Route::get('/wakanda', function (Request $request) {
  return response()->json(["message" => "Access token is valid. Welcome to this private endpoint. You need elevated scopes to access Vibranium."]);
})->middleware('auth:api');

Now, you can send a request to your protected endpoint which includes an access_token.

curl --request GET \
  --url http://localhost:8000/api/wakanda \
  --header 'authorization: Bearer <ACCESS TOKEN>'

Once a user hits the api/wakanda endpoint, a valid JWT access_token will be required before the resource can be released. With this in place, private routes can be secured.

More Resources

That's it! We have an authenticated Laravel API with protected routes. To learn more, check out the following resources:

Conclusion

Laravel 5.6 came loaded with new features and significant improvements. Another major release will be out by August and some of the features shipping with the next major release will be unleashed at Laracon 2018. Get your tickets already!

Have you upgraded to Laravel v5.6 yet? What are your thoughts? Let me know in the comments section! 😊