TL;DR: Laravel 5.7 is a major release to, at time of writing, the most popular PHP framework on GitHub. Furthermore, Laravel Nova was also released. In this article, I'll cover the new features in Laravel 5.7 and several other changes and deprecations.

What's new in Laravel 5.7?

1. Symfony Dump Server Integration

Marcel Pociot, authored a package called laravel-dump-server. This package provides you a dump server, that collects all your dump call outputs. It's inspired by Symfony's Var-Dump Server.

Laravel 5.7 now officially ships with the laravel_dump-server package and makes it available via the Artisan command:

php artisan dump-server

All dump calls will be displayed in the console window once the server has started.

Laravel - Symfony Dump Server Integration Source: murze.be

2. Better Support For Filesystem

Laravel 5.7 ships with two new methods for reading and writing streams in the filesystem. They are readStream and writeStream methods for reading and writing streams respectively as shown in the example below:

Storage::disk('s3')->writeStream(
    'new-package.zip',
    Storage::disk('local')->readStream('local-package.zip')
);

3. Improved Artisan Command Testing

Laravel 5.7 provides a better approach for testing artisan commands.

Check out the example below:

This is an Artisan command:

Artisan::command('hackathon-starter:init', function () {
    $project = $this->ask('What type of project do you want to build?');

    $this->line('Initializing...');

    $answer = $this->choice('Which language do you program in?', [
        'pwa-on-steroids',
        'pwa-normal',
        'pwa-on-fire',
    ]);

    $this->line('Installing...');
});

You may now test the command above with the slick test approach below:

/**
 * Test a console command.
 *
 * @return void
 */
public function test_console_command()
{
    $this->artisan('hackathon-starter:init')
         ->expectsQuestion('What type of project do you want to build?', 'PWA')
         ->expectsOutput('Initializing..')
         ->expectsQuestion('Please specify the type of PWA', 'pwa-on-fire')
         ->expectsOutput('Installing...')
         ->assertExitCode(0);
}

"Laravel 5.7 provides a better approach for testing artisan commands."

4. Multi-Lingual Support for Notifications

In Laravel 5.7, you can now send notifications in other locales, apart from the current language.

The Illuminate\Notifications\Notification class offers a locale method that can be invoked to set the preferred language.

  $user->notify((new EmailSent($email))->locale('zh'));
  Notification::locale('zh')->send($users, new EmailSent($email));

5. Paginator

By default, Laravel provides three links on each side of the primary paginator links.

In Laravel 5.7, there's a new option, onEachSide, to enable customization of the number of links displayed on both sides.

 {{ $paginator->onEachSide(7)->links() }}

6. More Options for Guest Policies

By default, authorization gates and policies return false for guest visitors to your application. In this new release, you can now allow unauthenticated visitors to pass through authorization checks by declaring an "optional" type-hint or supplying a null default value for the user argument.

Gate::define('modify-sheet', function (?User $user, Sheet $sheet) {
    // ...
});

7. Optional Email Verification

Laravel 5.7 provides an optional email verification feature. An email_verified_at timestamp column has to be added to the user's table migration for this feature to work as intended.

If you want new users to verify their email, the User model needs to implement the MustVerfifyEmail interface.

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    // ...
}

The newly registered users will receive an email containing a signed verification link. Once the user clicks the link, the app will automatically update the database and redirect the user to the intended location.

This feature also ships with a verified middleware for situations where you need to protect certain app routes from only verified members.

  'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,

8. Better Support for Development Errors

Joseph Silber submitted a PR that allows Laravel 5.7 to provide a clear and concise message when a non-existent method is called on a model.

9. URL Generator & Callable Syntax

Laravel 5.7 now supports callable array syntax for controller actions that generate URLs.

Before Laravel 5.7

$url = action('FoodController@index');

$url = action('FoodController@view', ['id' => 1]);

Now

$url = action([FoodController::class, 'index']);

$url = action([FoodController::class, 'view'], ['id' => 1]);

10. Laravel Nova

Taylor already announced that he was working on a project several months ago. The long awaited project called Laravel Nova has been released. Nova is a beautifully designed administration panel for Laravel. It offers support for filters, lenses, actions, queued actions, metrics, authorization, custom tools, custom cards, custom fields, etc.

Laravel Nova Laravel Nova

"As if Laravel 5.7 wasn't enough, @taylorotwell formally introduced @laravel_nova, a beautifully designed administration panel for Laravel."

Deprecations and Other Updates

  • The resources/assets directory has been flattened into resources.

Check out other Laravel 5.7 updates on GitHub.

Upgrading to Laravel 5.7

Laravel 5.7 requires PHP >= 7.1.3. And the estimated upgrade time from Laravel v5.6 is about ten to fifteen 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.

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, you 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

You're now ready to implement Auth0 authentication in your Laravel API.

Dependencies and Setup

Install the laravel-auth0 package by entering the following in your terminal:

composer require auth0/login:"~5.0"

Generate the laravel-auth0 package config file:

php artisan vendor:publish

After the file is generated, it will be located at config/laravel-auth0.php. Double check your values match those found here.

Now you need to open your .env file to create and fill in those variables. Add the following anywhere in your .env file:

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

Now replace all of those placeholders with the corresponding value from your Auth0 dashboard.

Activate Provider and Facade

The laravel-auth0 package comes with a provider 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 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 need 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 retrieve 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 with 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! You have an authenticated Laravel API with protected routes. To learn more, check out the following resources:

Conclusion

Laravel 5.7 PHP framework came loaded with new features and significant improvements. And Nova is a product every Laravel developer should try out!

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

"Laravel 5.7 has been released! Learn what's new in the most popular PHP framework"