Docs.git

GitHub - sutekin/docs
Repo URL: https://github.com/sutekin/docs.git
Edited by:
Cover image: Cover image
Share this using: email, Google+, Twitter, Facebook.
Exports: EPUB | MOBI

1 Release Notes

<a name=“versioning-scheme”></a>

1.1 Versioning Scheme

Laravel’s versioning scheme maintains the following convention: paradigm.major.minor. Major framework releases are released every six months (February and August), while minor releases may be released as often as every week. Minor releases should never contain breaking changes.

When referencing the Laravel framework or its components from your application or package, you should always use a version constraint such as 5.5.*, since major releases of Laravel do include breaking changes. However, we strive to always ensure you may update to a new major release in one day or less.

Paradigm shifting releases are separated by many years and represent fundamental shifts in the framework’s architecture and conventions. Currently, there is no paradigm shifting release under development.

1.1.0.1 Why Doesn’t Laravel Use Semantic Versioning?

On one hand, all optional components of Laravel (Cashier, Dusk, Valet, Socialite, etc.) do use semantic versioning. However, the Laravel framework itself does not. The reason for this is because semantic versioning is a “reductionist” way of determining if two pieces of code are compatible. Even when using semantic versioning, you still must install the upgraded package and run your automated test suite to know if anything is actually incompatible with your code base.

So, instead, the Laravel framework uses a versioning scheme that is more communicative of the actual scope of the release. Furthermore, since minor releases never contain intentional breaking changes, you should never receive a breaking change as long as your version constraints follow the paradigm.major.* convention.

<a name=“support-policy”></a>

1.2 Support Policy

For LTS releases, such as Laravel 5.1, bug fixes are provided for 2 years and security fixes are provided for 3 years. These releases provide the longest window of support and maintenance. For general releases, bug fixes are provided for 6 months and security fixes are provided for 1 year.

<a name=“laravel-5.5”></a>

1.3 Laravel 5.5 (LTS)

Laravel 5.5 continues the improvements made in Laravel 5.4 by adding package auto-detection, API resources / transformations, auto-registration of console commands, queued job chaining, queued job rate limiting, time based job attempts, renderable mailables, renderable and reportable exceptions, more consistent exception handling, database testing improvements, simpler custom validation rules, React front-end presets, Route::view and Route::redirect methods, “locks” for the Memcached and Redis cache drivers, on-demand notifications, headless Chrome support in Dusk, convenient Blade shortcuts, improved trusted proxy support, and more.

In addition, Laravel 5.5 coincides with the release of Laravel Horizon, a beautiful new queue dashboard and configuration system for your Redis based Laravel queues.

{tip} This documentation summarizes the most notable improvements to the framework; however, more thorough change logs are always available on GitHub.

1.3.1 Laravel Horizon

Horizon provides a beautiful dashboard and code-driven configuration for your Laravel powered Redis queues. Horizon allows you to easily monitor key metrics of your queue system such as job throughput, runtime, and job failures.

All of your worker configuration is stored in a single, simple configuration file, allowing your configuration to stay in source control where your entire team can collaborate.

For more information on Horizon, check out the full Horizon documentation

1.3.2 Package Discovery

{video} There is a free video tutorial for this feature available on Laracasts.

In previous versions of Laravel, installing a package typically required several additional steps such as adding the service provider to your app configuration file and registering any relevant facades. However, beginning with Laravel 5.5, Laravel can automatically detect and register service providers and facades for you.

For example, you can experience this by installing the popular barryvdh/laravel-debugbar package into your Laravel application. Once the package is installed via Composer, the debug bar will be available to your application with no additional configuration:

composer require barryvdh/laravel-debugbar

Package developers only need to add their service providers and facades to their package’s composer.json file:

"extra": {
    "laravel": {
        "providers": [
            "Laravel\\Tinker\\TinkerServiceProvider"
        ]
    }
},

For more information on updating your packages to use service provider and facade discovery, check out the full documentation on package development.

1.3.3 API Resources

When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application’s users. Laravel’s resource classes allow you to expressively and easily transform your models and model collections into JSON.

A resource class represents a single model that needs to be transformed into a JSON structure. For example, here is a simple User resource class:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class User extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

Of course, this is only the most basic example of an API resource. Laravel also provides a variety of methods to help you when building your resources and resource collections. For more information, check out the full documentation on API resources.

1.3.4 Console Command Auto-Registration

{video} There is a free video tutorial for this feature available on Laracasts.

When creating new console commands, you no longer are required to manually list them in the $commands property of your Console kernel. Instead, a new load method is called from the commands method of your kernel, which will scan the given directory for any console commands and register them automatically:

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $this->load(__DIR__.'/Commands');

    // ...
}

1.3.5 New Frontend Presets

{video} There is a free video tutorial for this feature available on Laracasts.

While the basic Vue scaffolding is still included in Laravel 5.5, several new frontend preset options are now available. In a fresh Laravel application, you can swap the Vue scaffolding for React scaffolding using the preset command:

php artisan preset react

Or, you can remove the JavaScript and CSS framework scaffolding entirely using the none preset. This preset will leave your application with a plain Sass file and a few simple JavaScript utilities:

php artisan preset none

{note} These commands are only intended to be run on fresh Laravel installations. They should not be used on existing applications.

1.3.6 Queued Job Chaining

Job chaining allows you to specify a list of queued jobs that should be run in sequence. If one job in the sequence fails, the rest of the jobs will not be run. To execute a queued job chain, you may use the withChain method on any of your dispatchable jobs:

ProvisionServer::withChain([
    new InstallNginx,
    new InstallPhp
])->dispatch();

1.3.7 Queued Job Rate Limiting

If your application interacts with Redis, you may now throttle your queued jobs by time or concurrency. This feature can be of assistance when your queued jobs are interacting with APIs that are also rate limited. For example, you may throttle a given type of job to only run 10 times every 60 seconds:

Redis::throttle('key')->allow(10)->every(60)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});

{tip} In the example above, the key may be any string that uniquely identifies the type of job you would like to rate limit. For example, you may wish to construct the key based on the class name of the job and the IDs of the Eloquent models it operates on.

Alternatively, you may specify the maximum number of workers that may simultaneously process a given job. This can be helpful when a queued job is modifying a resource that should only be modified by one job at a time. For example, we may limit jobs of a given type to only be processed by one worker at a time:

Redis::funnel('key')->limit(1)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});

1.3.8 Time Based Job Attempts

As an alternative to defining how many times a job may be attempted before it fails, you may now define a time at which the job should timeout. This allows a job to be attempted any number of times within a given time frame. To define the time at which a job should timeout, add a retryUntil method to your job class:

/**
 * Determine the time at which the job should timeout.
 *
 * @return \DateTime
 */
public function retryUntil()
{
    return now()->addSeconds(5);
}

{tip} You may also define a retryUntil method on your queued event listeners.

1.3.9 Validation Rule Objects

{video} There is a free video tutorial for this feature available on Laracasts.

Validation rule objects provide a new, compact way of adding custom validation rules to your application. In previous versions of Laravel, the Validator::extend method was used to add custom validation rules via Closures. However, this can grow cumbersome. In Laravel 5.5, a new make:rule Artisan command will generate a new validation rule in the app/Rules directory:

php artisan make:rule ValidName

A rule object only has two methods: passes and message. The passes method receives the attribute value and name, and should return true or false depending on whether the attribute value is valid or not. The message method should return the validation error message that should be used when validation fails:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class ValidName implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strlen($value) === 6;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The name must be six characters long.';
    }
}

Once the rule has been defined, you may use it by simply passing an instance of the rule object with your other validation rules:

use App\Rules\ValidName;

$request->validate([
    'name' => ['required', new ValidName],
]);

1.3.10 Trusted Proxy Integration

When running applications behind a load balancer that terminates TLS / SSL certificates, you may notice your application sometimes does not generate HTTPS links. Typically this is because your application is being forwarded traffic from your load balancer on port 80 and does not know it should generate secure links.

To solve this, many Laravel users install the Trusted Proxies package by Chris Fidao. Since this is such a common use case, Chris’ package now ships with Laravel 5.5 by default.

A new App\Http\Middleware\TrustProxies middleware is included in the default Laravel 5.5 application. This middleware allows you to quickly customize the proxies that should be trusted by your application:

<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies;

    /**
     * The current proxy header mappings.
     *
     * @var array
     */
    protected $headers = [
        Request::HEADER_FORWARDED => 'FORWARDED',
        Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
        Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
        Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
        Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
    ];
}

1.3.11 On-Demand Notifications

Sometimes you may need to send a notification to someone who is not stored as a “user” of your application. Using the new Notification::route method, you may specify ad-hoc notification routing information before sending the notification:

Notification::route('mail', 'taylor@laravel.com')
            ->route('nexmo', '5555555555')
            ->send(new InvoicePaid($invoice));

1.3.12 Renderable Mailables

{video} There is a free video tutorial for this feature available on Laracasts.

Mailables can now be returned directly from routes, allowing you to quickly preview your mailable’s designs in the browser:

Route::get('/mailable', function () {
    $invoice = App\Invoice::find(1);

    return new App\Mail\InvoicePaid($invoice);
});

1.3.13 Renderable & Reportable Exceptions

{video} There is a free video tutorial for this feature available on Laracasts.

In previous versions of Laravel, you may have had to resort to “type checking” in your exception handler in order to render a custom response for a given exception. For instance, you may have written code like this in your exception handler’s render method:

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $exception
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $exception)
{
    if ($exception instanceof SpecialException) {
        return response(...);
    }

    return parent::render($request, $exception);
}

In Laravel 5.5, you may now define a render method directly on your exceptions. This allows you to place the custom response rendering logic directly on the exception, which helps avoid conditional logic accumulation in your exception handler. If you would like to also customize the reporting logic for the exception, you may define a report method on the class:

<?php

namespace App\Exceptions;

use Exception;

class SpecialException extends Exception
{
    /**
     * Report the exception.
     *
     * @return void
     */
    public function report()
    {
        //
    }

    /**
     * Report the exception.
     *
     * @param  \Illuminate\Http\Request
     * @return void
     */
    public function render($request)
    {
        return response(...);
    }
}

1.3.14 Request Validation

{video} There is a free video tutorial for this feature available on Laracasts.

The Illuminate\Http\Request object now provides a validate method, allowing you to quickly validate an incoming request from a route Closure or controller:

use Illuminate\Http\Request;

Route::get('/comment', function (Request $request) {
    $request->validate([
        'title' => 'required|string',
        'body' => 'required|string',
    ]);

    // ...
});

1.3.15 Consistent Exception Handling

Validation exception handling is now consistent throughout the framework. Previously, there were multiple locations in the framework that required customization to change the default format for JSON validation error responses. In addition, the default format for JSON validation responses in Laravel 5.5 now adheres the following convention:

{
    "message": "The given data was invalid.",
    "errors": {
        "field-1": [
            "Error 1",
            "Error 2"
        ],
        "field-2": [
            "Error 1",
            "Error 2"
        ],
    }
}

All JSON validation error formatting can be controlled by defining a single method on your App\Exceptions\Handler class. For example, the following customization will format JSON validation responses using the Laravel 5.4 convention.

use Illuminate\Validation\ValidationException;

/**
 * Convert a validation exception into a JSON response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Validation\ValidationException  $exception
 * @return \Illuminate\Http\JsonResponse
 */
protected function invalidJson($request, ValidationException $exception)
{
    return response()->json($exception->errors(), $exception->status);
}

1.3.16 Cache Locks

The Redis and Memcached cache drivers now have support for obtaining and releasing atomic “locks”. This provides a simple method of obtaining arbitrary locks without worrying about race conditions. For example, before performing a task, you may wish to obtain a lock so no other processes attempt the same task that is already in progress:

if (Cache::lock('lock-name', 60)->get()) {
    // Lock obtained for 60 seconds, continue processing...

    Cache::lock('lock-name')->release();
} else {
    // Lock was not able to be obtained...
}

Or, you may pass a Closure to the get method. The Closure will only be executed if the lock can be obtained and the lock will automatically be released after the Closure is executed:

Cache::lock('lock-name', 60)->get(function () {
    // Lock obtained for 60 seconds...
});

In addition, you may “block” until the lock becomes available:

if (Cache::lock('lock-name', 60)->block(10)) {
    // Wait for a maximum of 10 seconds for the lock to become available...
}

1.3.17 Blade Improvements

{video} There is a free video tutorial for this feature available on Laracasts.

Programming a custom directive is sometimes more complex than necessary when defining simple, custom conditional statements. For that reason, Blade now provides a Blade::if method which allows you to quickly define custom conditional directives using Closures. For example, let’s define a custom conditional that checks the current application environment. We may do this in the boot method of our AppServiceProvider:

use Illuminate\Support\Facades\Blade;

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    Blade::if('env', function ($environment) {
        return app()->environment($environment);
    });
}

Once the custom conditional has been defined, we can easily use it on our templates:

@env('local')
    // The application is in the local environment...
@else
    // The application is not in the local environment...
@endenv

In addition to the ability to easily define custom Blade conditional directives, new shortcuts have been added to quickly check the authentication status of the current user:

@auth
    // The user is authenticated...
@endauth

@guest
    // The user is not authenticated...
@endguest

1.3.18 New Routing Methods

{video} There is a free video tutorial for this feature available on Laracasts.

If you are defining a route that redirects to another URI, you may now use the Route::redirect method. This method provides a convenient shortcut so that you do not have to define a full route or controller for performing a simple redirect:

Route::redirect('/here', '/there', 301);

If your route only needs to return a view, you may now use the Route::view method. Like the redirect method, this method provides a simple shortcut so that you do not have to define a full route or controller. The view method accepts a URI as its first argument and a view name as its second argument. In addition, you may provide an array of data to pass to the view as an optional third argument:

Route::view('/welcome', 'welcome');

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

1.3.19 “Sticky” Database Connections

1.3.19.1 The sticky Option

When configuration read / write database connections, a new sticky configuration option is available:

'mysql' => [
    'read' => [
        'host' => '192.168.1.1',
    ],
    'write' => [
        'host' => '196.168.1.2'
    ],
    'sticky'    => true,
    'driver'    => 'mysql',
    'database'  => 'database',
    'username'  => 'root',
    'password'  => '',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix'    => '',
],

The sticky option is an optional value that can be used to allow the immediate reading of records that have been written to the database during the current request cycle. If the sticky option is enabled and a “write” operation has been performed against the database during the current request cycle, any further “read” operations will use the “write” connection. This ensures that any data written during the request cycle can be immediately read back from the database during that same request. It is up to you to decide if this is the desired behavior for your application.

2 Upgrade Guide

<a name=“upgrade-5.5.0”></a>

2.1 Upgrading To 5.5.0 From 5.4

2.1.0.1 Estimated Upgrade Time: 1 Hour

{note} We attempt to document every possible breaking change. Since some of these breaking changes are in obscure parts of the framework only a portion of these changes may actually affect your application.

2.1.1 Updating Dependencies

Update your laravel/framework dependency to 5.5.* in your composer.json file. In addition, you should update your phpunit/phpunit dependency to ~6.0.

{tip} If you commonly use the Laravel installer via laravel new, you should update your Laravel installer package using the composer global update command.

2.1.1.1 Laravel Dusk

Laravel Dusk 2.0.0 has been released to provide compatibility with Laravel 5.5 and headless Chrome testing.

2.1.1.2 Pusher

The Pusher event broadcasting driver now requires version ~3.0 of the Pusher SDK.

2.1.2 Artisan

2.1.2.1 The fire Method

Any fire methods present on your Artisan commands should be renamed to handle.

2.1.2.2 The optimize Command

With recent improvements to PHP op-code caching, the optimize Artisan command is no longer needed. You should remove any references to this command from your deployment scripts as it will be removed in a future release of Laravel.

2.1.3 Authorization

2.1.3.1 The authorizeResource Controller Method

When passing a multi-word model name to the authorizeResource method, the resulting route segment will now be “snake” case, matching the behavior of resource controllers.

2.1.3.2 The before Policy Method

The before method of a policy class will not be called if the class doesn’t contain a method with name matching the name of the ability being checked.

2.1.4 Cache

2.1.4.1 Database Driver

If you are using the database cache driver, you should run php artisan cache:clear when deploying your upgraded Laravel 5.5 application for the first time.

2.1.5 Eloquent

2.1.5.1 The belongsToMany Method

If you are overriding the belongsToMany method on your Eloquent model, you should update your method signature to reflect the addition of new arguments:

/**
 * Define a many-to-many relationship.
 *
 * @param  string  $related
 * @param  string  $table
 * @param  string  $foreignPivotKey
 * @param  string  $relatedPivotKey
 * @param  string  $parentKey
 * @param  string  $relatedKey
 * @param  string  $relation
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function belongsToMany($related, $table = null, $foreignPivotKey = null,
                              $relatedPivotKey = null, $parentKey = null,
                              $relatedKey = null, $relation = null)
{
    //
}

2.1.5.2 Model is Method

If you are overriding the is method of your Eloquent model, you should remove the Model type-hint from the method. This allows the is method to receive null as an argument:

/**
 * Determine if two models have the same ID and belong to the same table.
 *
 * @param  \Illuminate\Database\Eloquent\Model|null  $model
 * @return bool
 */
public function is($model)
{
    //
}

2.1.5.3 Model $events Property

The $events property on your models should be renamed to $dispatchesEvents. This change was made because of a high number of users needing to define an events relationship, which caused a conflict with the old property name.

2.1.5.4 Pivot $parent Property

The protected $parent property on the Illuminate\Database\Eloquent\Relations\Pivot class has been renamed to $pivotParent.

2.1.5.5 Relationship create Methods

The BelongsToMany, HasOneOrMany, and MorphOneOrMany class’ create methods have been modified to provide a default value for the $attributes argument. If you are overriding these methods, you should update your signatures to match the new definition:

public function create(array $attributes = [])
{
    //
}

2.1.5.6 Soft Deleted Models

When deleting a “soft deleted” model, the exists property on the model will remain true.

2.1.5.7 withCount Column Formatting

When using an alias, the withCount method will no longer automatically append _count onto the resulting column name. For example, in Laravel 5.4, the following query would result in a bar_count column being added to the query:

$users = User::withCount('foo as bar')->get();

However, in Laravel 5.5, the alias will be used exactly as it is given. If you would like to append _count to the resulting column, you must specify that suffix when defining the alias:

$users = User::withCount('foo as bar_count')->get();

2.1.6 Exception Format

In Laravel 5.5, all exceptions, including validation exceptions, are converted into HTTP responses by the exception handler. In addition, the default format for JSON validation errors has changed. The new format conforms to the following convention:

{
    "message": "The given data was invalid.",
    "errors": {
        "field-1": [
            "Error 1",
            "Error 2"
        ],
        "field-2": [
            "Error 1",
            "Error 2"
        ],
    }
}

However, if you would like to maintain the Laravel 5.4 JSON error format, you may add the following method to your App\Exceptions\Handler class:

use Illuminate\Validation\ValidationException;

/**
 * Convert a validation exception into a JSON response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Validation\ValidationException  $exception
 * @return \Illuminate\Http\JsonResponse
 */
protected function invalidJson($request, ValidationException $exception)
{
    return response()->json($exception->errors(), $exception->status);
}

2.1.6.1 JSON Authentication Attempts

This change also affects the validation error formatting for authentication attempts made over JSON. In Laravel 5.5, JSON authentication failures will return the error messages following the new formatting convention described above.

2.1.6.2 A Note On Form Requests

If you were customizing the response format of an individual form request, you should now override the failedValidation method of that form request, and throw an HttpResponseException instance containing your custom response:

use Illuminate\Http\Exceptions\HttpResponseException;

/**
 * Handle a failed validation attempt.
 *
 * @param  \Illuminate\Contracts\Validation\Validator  $validator
 * @return void
 *
 * @throws \Illuminate\Validation\ValidationException
 */
protected function failedValidation(Validator $validator)
{
    throw new HttpResponseException(response()->json(..., 422));
}

2.1.7 Filesystem

2.1.7.1 The files Method

The files method now returns an array of SplFileInfo objects, similar to the allFiles method. Previously, the files method returned an array of string path names.

2.1.8 Mail

2.1.8.1 Unused Parameters

The unused $data and $callback arguments were removed from the Illuminate\Contracts\Mail\MailQueue contract’s queue and later methods:

/**
 * Queue a new e-mail message for sending.
 *
 * @param  string|array|MailableContract  $view
 * @param  string  $queue
 * @return mixed
 */
public function queue($view, $queue = null);

/**
 * Queue a new e-mail message for sending after (n) seconds.
 *
 * @param  \DateTimeInterface|\DateInterval|int  $delay
 * @param  string|array|MailableContract  $view
 * @param  string  $queue
 * @return mixed
 */
public function later($delay, $view, $queue = null);

2.1.9 Requests

2.1.9.1 The has Method

The $request->has method will now return true for empty strings and null. A new $request->filled method has been added that provides the previous behavior of the has method.

2.1.9.2 The intersect Method

The intersect method has been removed. You may replicate this behavior using array_filter on a call to $request->only:

return array_filter($request->only('foo'));

2.1.9.3 The only Method

The only method will now only return attributes that are actually present in the request payload. If you would like to preserve the old behavior of the only method, you may use the all method instead.

return $request->all('foo');

2.1.9.4 The request() Helper

The request helper will no longer retrieve nested keys. If needed, you may use the input method of the request to achieve this behavior:

return request()->input('filters.date');

2.1.10 Testing

2.1.10.1 Authentication Assertions

Some authentication assertions were renamed for better consistency with the rest of the framework’s assertions:

<div class=“content-list” markdown=“1”>

  • seeIsAuthenticated was renamed to assertAuthenticated.
  • dontSeeIsAuthenticated was renamed to assertGuest.
  • seeIsAuthenticatedAs was renamed to assertAuthenticatedAs.
  • seeCredentials was renamed to assertCredentials.
  • dontSeeCredentials was renamed to assertInvalidCredentials.
    </div>

2.1.10.2 Mail Fake

If you are using the Mail fake to determine if a mailable was queued during a request, you should now use Mail::assertQueued instead of Mail::assertSent. This distinction allows you to specifically assert that the mail was queued for background sending and not sent during the request itself.

2.1.11 Translation

2.1.11.1 The LoaderInterface

The Illuminate\Translation\LoaderInterface interface has been moved to Illuminate\Contracts\Translation\Loader.

2.1.12 Validation

2.1.12.1 Validator Methods

All of the validator’s validation methods are now public instead of protected.

2.1.13 Views

2.1.13.1 Dynamic “With” Variable Names

When allowing the dynamic __call method to share variables with a view, these variables will automatically use “camel” case. For example, given the following:

return view('pool')->withMaximumVotes(100);

The maximumVotes variable may be accessed in the template like so:

{{ $maximumVotes }}

2.1.14 Miscellaneous

We also encourage you to view the changes in the laravel/laravel GitHub repository. While many of these changes are not required, you may wish to keep these files in sync with your application. Some of these changes will be covered in this upgrade guide, but others, such as changes to configuration files or comments, will not be. You can easily view the changes with the GitHub comparison tool and choose which updates are important to you.

3 Contribution Guide

<a name=“bug-reports”></a>

3.1 Bug Reports

To encourage active collaboration, Laravel strongly encourages pull requests, not just bug reports. “Bug reports” may also be sent in the form of a pull request containing a failing test.

However, if you file a bug report, your issue should contain a title and a clear description of the issue. You should also include as much relevant information as possible and a code sample that demonstrates the issue. The goal of a bug report is to make it easy for yourself - and others - to replicate the bug and develop a fix.

Remember, bug reports are created in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the bug report will automatically see any activity or that others will jump to fix it. Creating a bug report serves to help yourself and others start on the path of fixing the problem.

The Laravel source code is managed on GitHub, and there are repositories for each of the Laravel projects:

<div class=“content-list” markdown=“1”>

<a name=“core-development-discussion”></a>

3.2 Core Development Discussion

You may propose new features or improvements of existing Laravel behavior in the Laravel Internals issue board. If you propose a new feature, please be willing to implement at least some of the code that would be needed to complete the feature.

Informal discussion regarding bugs, new features, and implementation of existing features takes place in the #internals channel of the LaraChat Slack team. Taylor Otwell, the maintainer of Laravel, is typically present in the channel on weekdays from 8am-5pm (UTC-06:00 or America/Chicago), and sporadically present in the channel at other times.

<a name=“which-branch”></a>

3.3 Which Branch?

All bug fixes should be sent to the latest stable branch or to the current LTS branch (5.5). Bug fixes should never be sent to the master branch unless they fix features that exist only in the upcoming release.

Minor features that are fully backwards compatible with the current Laravel release may be sent to the latest stable branch.

Major new features should always be sent to the master branch, which contains the upcoming Laravel release.

If you are unsure if your feature qualifies as a major or minor, please ask Taylor Otwell in the #internals channel of the LaraChat Slack team.

<a name=“security-vulnerabilities”></a>

3.4 Security Vulnerabilities

If you discover a security vulnerability within Laravel, please send an email to Taylor Otwell at <a href=“”>taylor@laravel.com</a>. All security vulnerabilities will be promptly addressed.

<a name=“coding-style”></a>

3.5 Coding Style

Laravel follows the PSR-2 coding standard and the PSR-4 autoloading standard.

<a name=“phpdoc”></a>

3.5.1 PHPDoc

Below is an example of a valid Laravel documentation block. Note that the @param attribute is followed by two spaces, the argument type, two more spaces, and finally the variable name:

/**
 * Register a binding with the container.
 *
 * @param  string|array  $abstract
 * @param  \Closure|string|null  $concrete
 * @param  bool  $shared
 * @return void
 */
public function bind($abstract, $concrete = null, $shared = false)
{
    //
}

<a name=“styleci”></a>

3.5.2 StyleCI

Don’t worry if your code styling isn’t perfect! StyleCI will automatically merge any style fixes into the Laravel repository after pull requests are merged. This allows us to focus on the content of the contribution and not the code style.

4 Installation

<a name=“installation”></a>

4.1 Installation

{video} Are you a visual learner? Laracasts provides a free, thorough introduction to Laravel for newcomers to the framework. It’s a great place to start your journey.

<a name=“server-requirements”></a>

4.1.1 Server Requirements

The Laravel framework has a few system requirements. Of course, all of these requirements are satisfied by the Laravel Homestead virtual machine, so it’s highly recommended that you use Homestead as your local Laravel development environment.

However, if you are not using Homestead, you will need to make sure your server meets the following requirements:

<div class=“content-list” markdown=“1”>

  • PHP >= 7.0.0
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension
    </div>

<a name=“installing-laravel”></a>

4.1.2 Installing Laravel

Laravel utilizes Composer to manage its dependencies. So, before using Laravel, make sure you have Composer installed on your machine.

4.1.2.1 Via Laravel Installer

First, download the Laravel installer using Composer:

composer global require "laravel/installer"

Make sure to place the $HOME/.composer/vendor/bin directory (or the equivalent directory for your OS) in your $PATH so the laravel executable can be located by your system.

Once installed, the laravel new command will create a fresh Laravel installation in the directory you specify. For instance, laravel new blog will create a directory named blog containing a fresh Laravel installation with all of Laravel’s dependencies already installed:

laravel new blog

4.1.2.2 Via Composer Create-Project

Alternatively, you may also install Laravel by issuing the Composer create-project command in your terminal:

composer create-project --prefer-dist laravel/laravel blog

4.1.2.3 Local Development Server

If you have PHP installed locally and you would like to use PHP’s built-in development server to serve your application, you may use the serve Artisan command. This command will start a development server at http://localhost:8000:

php artisan serve

Of course, more robust local development options are available via Homestead and Valet.

<a name=“configuration”></a>

4.1.3 Configuration

4.1.3.1 Public Directory

After installing Laravel, you should configure your web server’s document / web root to be the public directory. The index.php in this directory serves as the front controller for all HTTP requests entering your application.

4.1.3.2 Configuration Files

All of the configuration files for the Laravel framework are stored in the config directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you.

4.1.3.3 Directory Permissions

After installing Laravel, you may need to configure some permissions. Directories within the storage and the bootstrap/cache directories should be writable by your web server or Laravel will not run. If you are using the Homestead virtual machine, these permissions should already be set.

4.1.3.4 Application Key

The next thing you should do after installing Laravel is set your application key to a random string. If you installed Laravel via Composer or the Laravel installer, this key has already been set for you by the php artisan key:generate command.

Typically, this string should be 32 characters long. The key can be set in the .env environment file. If you have not renamed the .env.example file to .env, you should do that now. If the application key is not set, your user sessions and other encrypted data will not be secure!

4.1.3.5 Additional Configuration

Laravel needs almost no other configuration out of the box. You are free to get started developing! However, you may wish to review the config/app.php file and its documentation. It contains several options such as timezone and locale that you may wish to change according to your application.

You may also want to configure a few additional components of Laravel, such as:

<div class=“content-list” markdown=“1”>

<a name=“web-server-configuration”></a>

4.2 Web Server Configuration

<a name=“pretty-urls”></a>

4.2.1 Pretty URLs

4.2.1.1 Apache

Laravel includes a public/.htaccess file that is used to provide URLs without the index.php front controller in the path. Before serving Laravel with Apache, be sure to enable the mod_rewrite module so the .htaccess file will be honored by the server.

If the .htaccess file that ships with Laravel does not work with your Apache installation, try this alternative:

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

4.2.1.2 Nginx

If you are using Nginx, the following directive in your site configuration will direct all requests to the index.php front controller:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

Of course, when using Homestead or Valet, pretty URLs will be automatically configured.

5 Configuration

<a name=“introduction”></a>

5.1 Introduction

All of the configuration files for the Laravel framework are stored in the config directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you.

<a name=“environment-configuration”></a>

5.2 Environment Configuration

It is often helpful to have different configuration values based on the environment where the application is running. For example, you may wish to use a different cache driver locally than you do on your production server.

To make this a cinch, Laravel utilizes the DotEnv PHP library by Vance Lucas. In a fresh Laravel installation, the root directory of your application will contain a .env.example file. If you install Laravel via Composer, this file will automatically be renamed to .env. Otherwise, you should rename the file manually.

Your .env file should not be committed to your application’s source control, since each developer / server using your application could require a different environment configuration. Furthermore, this would be a security risk in the event an intruder gain access to your source control repository, since any sensitive credentials would get exposed.

If you are developing with a team, you may wish to continue including a .env.example file with your application. By putting place-holder values in the example configuration file, other developers on your team can clearly see which environment variables are needed to run your application. You may also create a .env.testing file. This file will override values from the .env file when running PHPUnit tests or executing Artisan commands with the --env=testing option.

{tip} Any variable in your .env file can be overridden by external environment variables such as server-level or system-level environment variables.

<a name=“retrieving-environment-configuration”></a>

5.2.1 Retrieving Environment Configuration

All of the variables listed in this file will be loaded into the $_ENV PHP super-global when your application receives a request. However, you may use the env helper to retrieve values from these variables in your configuration files. In fact, if you review the Laravel configuration files, you will notice several of the options already using this helper:

'debug' => env('APP_DEBUG', false),

The second value passed to the env function is the “default value”. This value will be used if no environment variable exists for the given key.

<a name=“determining-the-current-environment”></a>

5.2.2 Determining The Current Environment

The current application environment is determined via the APP_ENV variable from your .env file. You may access this value via the environment method on the App facade:

$environment = App::environment();

You may also pass arguments to the environment method to check if the environment matches a given value. The method will return true if the environment matches any of the given values:

if (App::environment('local')) {
    // The environment is local
}

if (App::environment(['local', 'staging'])) {
    // The environment is either local OR staging...
}

{tip} The current application environment detection can be overriden by a server-level APP_ENV environment variable. This can be useful when you need to share the same application for different environment configurations, so you can set up a given host to match a given environment in your server’s configurations.

<a name=“accessing-configuration-values”></a>

5.3 Accessing Configuration Values

You may easily access your configuration values using the global config helper function from anywhere in your application. The configuration values may be accessed using “dot” syntax, which includes the name of the file and option you wish to access. A default value may also be specified and will be returned if the configuration option does not exist:

$value = config('app.timezone');

To set configuration values at runtime, pass an array to the config helper:

config(['app.timezone' => 'America/Chicago']);

<a name=“configuration-caching”></a>

5.4 Configuration Caching

To give your application a speed boost, you should cache all of your configuration files into a single file using the config:cache Artisan command. This will combine all of the configuration options for your application into a single file which will be loaded quickly by the framework.

You should typically run the php artisan config:cache command as part of your production deployment routine. The command should not be run during local development as configuration options will frequently need to be changed during the course of your application’s development.

{note} If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files.

<a name=“maintenance-mode”></a>

5.5 Maintenance Mode

When your application is in maintenance mode, a custom view will be displayed for all requests into your application. This makes it easy to “disable” your application while it is updating or when you are performing maintenance. A maintenance mode check is included in the default middleware stack for your application. If the application is in maintenance mode, a MaintenanceModeException will be thrown with a status code of 503.

To enable maintenance mode, simply execute the down Artisan command:

php artisan down

You may also provide message and retry options to the down command. The message value may be used to display or log a custom message, while the retry value will be set as the Retry-After HTTP header’s value:

php artisan down --message="Upgrading Database" --retry=60

To disable maintenance mode, use the up command:

php artisan up

{tip} You may customize the default maintenance mode template by defining your own template at resources/views/errors/503.blade.php.

5.5.0.1 Maintenance Mode & Queues

While your application is in maintenance mode, no queued jobs will be handled. The jobs will continue to be handled as normal once the application is out of maintenance mode.

5.5.0.2 Alternatives To Maintenance Mode

Since maintenance mode requires your application to have several seconds of downtime, consider alternatives like Envoyer to accomplish zero-downtime deployment with Laravel.

6 Directory Structure

<a name=“introduction”></a>

6.1 Introduction

The default Laravel application structure is intended to provide a great starting point for both large and small applications. Of course, you are free to organize your application however you like. Laravel imposes almost no restrictions on where any given class is located - as long as Composer can autoload the class.

6.1.0.1 Where Is The Models Directory?

When getting started with Laravel, many developers are confused by the lack of a models directory. However, the lack of such a directory is intentional. We find the word “models” ambiguous since it means many different things to many different people. Some developers refer to an application’s “model” as the totality of all of its business logic, while others refer to “models” as classes that interact with a relational database.

For this reason, we choose to place Eloquent models in the app directory by default, and allow the developer to place them somewhere else if they choose.

<a name=“the-root-directory”></a>

6.2 The Root Directory

<a name=“the-root-app-directory”></a>

6.2.0.1 The App Directory

The app directory, as you might expect, contains the core code of your application. We’ll explore this directory in more detail soon; however, almost all of the classes in your application will be in this directory.

<a name=“the-bootstrap-directory”></a>

6.2.0.2 The Bootstrap Directory

The bootstrap directory contains files that bootstrap the framework and configure autoloading. This directory also houses a cache directory which contains framework generated files for performance optimization such as the route and services cache files.

<a name=“the-config-directory”></a>

6.2.0.3 The Config Directory

The config directory, as the name implies, contains all of your application’s configuration files. It’s a great idea to read through all of these files and familiarize yourself with all of the options available to you.

<a name=“the-database-directory”></a>

6.2.0.4 The Database Directory

The database directory contains your database migration and seeds. If you wish, you may also use this directory to hold an SQLite database.

<a name=“the-public-directory”></a>

6.2.0.5 The Public Directory

The public directory contains the index.php file, which is the entry point for all requests entering your application. This directory also houses your assets such as images, JavaScript, and CSS.

<a name=“the-resources-directory”></a>

6.2.0.6 The Resources Directory

The resources directory contains your views as well as your raw, un-compiled assets such as LESS, SASS, or JavaScript. This directory also houses all of your language files.

<a name=“the-routes-directory”></a>

6.2.0.7 The Routes Directory

The routes directory contains all of the route definitions for your application. By default, several route files are included with Laravel: web.php, api.php, console.php and channels.php.

The web.php file contains routes that the RouteServiceProvider places in the web middleware group, which provides session state, CSRF protection, and cookie encryption. If your application does not offer a stateless, RESTful API, all of your routes will most likely be defined in the web.php file.

The api.php file contains routes that the RouteServiceProvider places in the api middleware group, which provides rate limiting. These routes are intended to be stateless, so requests entering the application through these routes are intended to be authenticated via tokens and will not have access to session state.

The console.php file is where you may define all of your Closure based console commands. Each Closure is bound to a command instance allowing a simple approach to interacting with each command’s IO methods. Even though this file does not define HTTP routes, it defines console based entry points (routes) into your application.

The channels.php file is where you may register all of the event broadcasting channels that your application supports.

<a name=“the-storage-directory”></a>

6.2.0.8 The Storage Directory

The storage directory contains your compiled Blade templates, file based sessions, file caches, and other files generated by the framework. This directory is segregated into app, framework, and logs directories. The app directory may be used to store any files generated by your application. The framework directory is used to store framework generated files and caches. Finally, the logs directory contains your application’s log files.

The storage/app/public directory may be used to store user-generated files, such as profile avatars, that should be publicly accessible. You should create a symbolic link at public/storage which points to this directory. You may create the link using the php artisan storage:link command.

<a name=“the-tests-directory”></a>

6.2.0.9 The Tests Directory

The tests directory contains your automated tests. An example PHPUnit is provided out of the box. Each test class should be suffixed with the word Test. You may run your tests using the phpunit or php vendor/bin/phpunit commands.

<a name=“the-vendor-directory”></a>

6.2.0.10 The Vendor Directory

The vendor directory contains your Composer dependencies.

<a name=“the-app-directory”></a>

6.3 The App Directory

The majority of your application is housed in the app directory. By default, this directory is namespaced under App and is autoloaded by Composer using the PSR-4 autoloading standard.

The app directory contains a variety of additional directories such as Console, Http, and Providers. Think of the Console and Http directories as providing an API into the core of your application. The HTTP protocol and CLI are both mechanisms to interact with your application, but do not actually contain application logic. In other words, they are simply two ways of issuing commands to your application. The Console directory contains all of your Artisan commands, while the Http directory contains your controllers, middleware, and requests.

A variety of other directories will be generated inside the app directory as you use the make Artisan commands to generate classes. So, for example, the app/Jobs directory will not exist until you execute the make:job Artisan command to generate a job class.

{tip} Many of the classes in the app directory can be generated by Artisan via commands. To review the available commands, run the php artisan list make command in your terminal.

<a name=“the-console-directory”></a>

6.3.0.1 The Console Directory

The Console directory contains all of the custom Artisan commands for your application. These commands may be generated using the make:command command. This directory also houses your console kernel, which is where your custom Artisan commands are registered and your scheduled tasks are defined.

<a name=“the-events-directory”></a>

6.3.0.2 The Events Directory

This directory does not exist by default, but will be created for you by the event:generate and make:event Artisan commands. The Events directory, as you might expect, houses event classes. Events may be used to alert other parts of your application that a given action has occurred, providing a great deal of flexibility and decoupling.

<a name=“the-exceptions-directory”></a>

6.3.0.3 The Exceptions Directory

The Exceptions directory contains your application’s exception handler and is also a good place to place any exceptions thrown by your application. If you would like to customize how your exceptions are logged or rendered, you should modify the Handler class in this directory.

<a name=“the-http-directory”></a>

6.3.0.4 The Http Directory

The Http directory contains your controllers, middleware, and form requests. Almost all of the logic to handle requests entering your application will be placed in this directory.

<a name=“the-jobs-directory”></a>

6.3.0.5 The Jobs Directory

This directory does not exist by default, but will be created for you if you execute the make:job Artisan command. The Jobs directory houses the queueable jobs for your application. Jobs may be queued by your application or run synchronously within the current request lifecycle. Jobs that run synchronously during the current request are sometimes referred to as “commands” since they are an implementation of the command pattern.

<a name=“the-listeners-directory”></a>

6.3.0.6 The Listeners Directory

This directory does not exist by default, but will be created for you if you execute the event:generate or make:listener Artisan commands. The Listeners directory contains the classes that handle your events. Event listeners receive an event instance and perform logic in response to the event being fired. For example, a UserRegistered event might be handled by a SendWelcomeEmail listener.

<a name=“the-mail-directory”></a>

6.3.0.7 The Mail Directory

This directory does not exist by default, but will be created for you if you execute the make:mail Artisan command. The Mail directory contains all of your classes that represent emails sent by your application. Mail objects allow you to encapsulate all of the logic of building an email in a single, simple class that may be sent using the Mail::send method.

<a name=“the-notifications-directory”></a>

6.3.0.8 The Notifications Directory

This directory does not exist by default, but will be created for you if you execute the make:notification Artisan command. The Notifications directory contains all of the “transactional” notifications that are sent by your application, such as simple notifications about events that happen within your application. Laravel’s notification features abstracts sending notifications over a variety of drivers such as email, Slack, SMS, or stored in a database.

<a name=“the-policies-directory”></a>

6.3.0.9 The Policies Directory

This directory does not exist by default, but will be created for you if you execute the make:policy Artisan command. The Policies directory contains the authorization policy classes for your application. Policies are used to determine if a user can perform a given action against a resource. For more information, check out the authorization documentation.

<a name=“the-providers-directory”></a>

6.3.0.10 The Providers Directory

The Providers directory contains all of the service providers for your application. Service providers bootstrap your application by binding services in the service container, registering events, or performing any other tasks to prepare your application for incoming requests.

In a fresh Laravel application, this directory will already contain several providers. You are free to add your own providers to this directory as needed.

<a name=“the-rules-directory”></a>

6.3.0.11 The Rules Directory

This directory does not exist by default, but will be created for you if you execute the make:rule Artisan command. The Rules directory contains the custom validation rule objects for your application. Rules are used to encapsulate complicated validation logic in a simple object. For more information, check out the validation documentation.

7 Laravel Homestead

<a name=“introduction”></a>

7.1 Introduction

Laravel strives to make the entire PHP development experience delightful, including your local development environment. Vagrant provides a simple, elegant way to manage and provision Virtual Machines.

Laravel Homestead is an official, pre-packaged Vagrant box that provides you a wonderful development environment without requiring you to install PHP, a web server, and any other server software on your local machine. No more worrying about messing up your operating system! Vagrant boxes are completely disposable. If something goes wrong, you can destroy and re-create the box in minutes!

Homestead runs on any Windows, Mac, or Linux system, and includes the Nginx web server, PHP 7.1, MySQL, PostgreSQL, Redis, Memcached, Node, and all of the other goodies you need to develop amazing Laravel applications.

{note} If you are using Windows, you may need to enable hardware virtualization (VT-x). It can usually be enabled via your BIOS. If you are using Hyper-V on a UEFI system you may additionally need to disable Hyper-V in order to access VT-x.

<a name=“included-software”></a>

7.1.1 Included Software

  • Ubuntu 16.04
  • Git
  • PHP 7.1
  • Nginx
  • MySQL
  • MariaDB
  • Sqlite3
  • PostgreSQL
  • Composer
  • Node (With Yarn, Bower, Grunt, and Gulp)
  • Redis
  • Memcached
  • Beanstalkd
  • Mailhog
  • ngrok

<a name=“installation-and-setup”></a>

7.2 Installation & Setup

<a name=“first-steps”></a>

7.2.1 First Steps

Before launching your Homestead environment, you must install VirtualBox 5.1, VMWare, or Parallels as well as Vagrant. All of these software packages provide easy-to-use visual installers for all popular operating systems.

To use the VMware provider, you will need to purchase both VMware Fusion / Workstation and the VMware Vagrant plug-in. Though it is not free, VMware can provide faster shared folder performance out of the box.

To use the Parallels provider, you will need to install Parallels Vagrant plug-in. It is free of charge.

7.2.1.1 Installing The Homestead Vagrant Box

Once VirtualBox / VMware and Vagrant have been installed, you should add the laravel/homestead box to your Vagrant installation using the following command in your terminal. It will take a few minutes to download the box, depending on your Internet connection speed:

vagrant box add laravel/homestead

If this command fails, make sure your Vagrant installation is up to date.

7.2.1.2 Installing Homestead

You may install Homestead by simply cloning the repository. Consider cloning the repository into a Homestead folder within your “home” directory, as the Homestead box will serve as the host to all of your Laravel projects:

cd ~

git clone https://github.com/laravel/homestead.git Homestead

You should check out a tagged version of Homestead since the master branch may not always be stable. You can find the latest stable version on the GitHub Release Page:

cd Homestead

// Clone the desired release...
git checkout v6.1.0

Once you have cloned the Homestead repository, run the bash init.sh command from the Homestead directory to create the Homestead.yaml configuration file. The Homestead.yaml file will be placed in the Homestead directory:

// Mac / Linux...
bash init.sh

// Windows...
init.bat

<a name=“configuring-homestead”></a>

7.2.2 Configuring Homestead

7.2.2.1 Setting Your Provider

The provider key in your Homestead.yaml file indicates which Vagrant provider should be used: virtualbox, vmware_fusion, vmware_workstation, or parallels. You may set this to the provider you prefer:

provider: virtualbox

7.2.2.2 Configuring Shared Folders

The folders property of the Homestead.yaml file lists all of the folders you wish to share with your Homestead environment. As files within these folders are changed, they will be kept in sync between your local machine and the Homestead environment. You may configure as many shared folders as necessary:

folders:
    - map: ~/Code
      to: /home/vagrant/Code

To enable NFS, you only need to add a simple flag to your synced folder configuration:

folders:
    - map: ~/Code
      to: /home/vagrant/Code
      type: "nfs"

{note} When using NFS, you should consider installing the vagrant-bindfs plug-in. This plug-in will maintain the correct user / group permissions for files and directories within the Homestead box.

You may also pass any options supported by Vagrant’s Synced Folders by listing them under the options key:

folders:
    - map: ~/Code
      to: /home/vagrant/Code
      type: "rsync"
      options:
          rsync__args: ["--verbose", "--archive", "--delete", "-zz"]
          rsync__exclude: ["node_modules"]

7.2.2.3 Configuring Nginx Sites

Not familiar with Nginx? No problem. The sites property allows you to easily map a “domain” to a folder on your Homestead environment. A sample site configuration is included in the Homestead.yaml file. Again, you may add as many sites to your Homestead environment as necessary. Homestead can serve as a convenient, virtualized environment for every Laravel project you are working on:

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public

If you change the sites property after provisioning the Homestead box, you should re-run vagrant reload --provision to update the Nginx configuration on the virtual machine.

7.2.2.4 The Hosts File

You must add the “domains” for your Nginx sites to the hosts file on your machine. The hosts file will redirect requests for your Homestead sites into your Homestead machine. On Mac and Linux, this file is located at /etc/hosts. On Windows, it is located at C:\Windows\System32\drivers\etc\hosts. The lines you add to this file will look like the following:

192.168.10.10  homestead.app

Make sure the IP address listed is the one set in your Homestead.yaml file. Once you have added the domain to your hosts file and launched the Vagrant box you will be able to access the site via your web browser:

http://homestead.app

<a name=“launching-the-vagrant-box”></a>

7.2.3 Launching The Vagrant Box

Once you have edited the Homestead.yaml to your liking, run the vagrant up command from your Homestead directory. Vagrant will boot the virtual machine and automatically configure your shared folders and Nginx sites.

To destroy the machine, you may use the vagrant destroy --force command.

<a name=“per-project-installation”></a>

7.2.4 Per Project Installation

Instead of installing Homestead globally and sharing the same Homestead box across all of your projects, you may instead configure a Homestead instance for each project you manage. Installing Homestead per project may be beneficial if you wish to ship a Vagrantfile with your project, allowing others working on the project to simply vagrant up.

To install Homestead directly into your project, require it using Composer:

composer require laravel/homestead --dev

Once Homestead has been installed, use the make command to generate the Vagrantfile and Homestead.yaml file in your project root. The make command will automatically configure the sites and folders directives in the Homestead.yaml file.

Mac / Linux:

php vendor/bin/homestead make

Windows:

vendor\\bin\\homestead make

Next, run the vagrant up command in your terminal and access your project at http://homestead.app in your browser. Remember, you will still need to add an /etc/hosts file entry for homestead.app or the domain of your choice.

<a name=“installing-mariadb”></a>

7.2.5 Installing MariaDB

If you prefer to use MariaDB instead of MySQL, you may add the mariadb option to your Homestead.yaml file. This option will remove MySQL and install MariaDB. MariaDB serves as a drop-in replacement for MySQL so you should still use the mysql database driver in your application’s database configuration:

box: laravel/homestead
ip: "192.168.20.20"
memory: 2048
cpus: 4
provider: virtualbox
mariadb: true

<a name=“daily-usage”></a>

7.3 Daily Usage

<a name=“accessing-homestead-globally”></a>

7.3.1 Accessing Homestead Globally

Sometimes you may want to vagrant up your Homestead machine from anywhere on your filesystem. You can do this on Mac / Linux systems by adding a Bash function to your Bash profile. On Windows, you may accomplish this by adding a “batch” file to your PATH. These scripts will allow you to run any Vagrant command from anywhere on your system and will automatically point that command to your Homestead installation:

7.3.1.1 Mac / Linux

function homestead() {
    ( cd ~/Homestead && vagrant $* )
}

Make sure to tweak the ~/Homestead path in the function to the location of your actual Homestead installation. Once the function is installed, you may run commands like homestead up or homestead ssh from anywhere on your system.

7.3.1.2 Windows

Create a homestead.bat batch file anywhere on your machine with the following contents:

@echo off

set cwd=%cd%
set homesteadVagrant=C:\Homestead

cd /d %homesteadVagrant% && vagrant %*
cd /d %cwd%

set cwd=
set homesteadVagrant=

Make sure to tweak the example C:\Homestead path in the script to the actual location of your Homestead installation. After creating the file, add the file location to your PATH. You may then run commands like homestead up or homestead ssh from anywhere on your system.

<a name=“connecting-via-ssh”></a>

7.3.2 Connecting Via SSH

You can SSH into your virtual machine by issuing the vagrant ssh terminal command from your Homestead directory.

But, since you will probably need to SSH into your Homestead machine frequently, consider adding the “function” described above to your host machine to quickly SSH into the Homestead box.

<a name=“connecting-to-databases”></a>

7.3.3 Connecting To Databases

A homestead database is configured for both MySQL and PostgreSQL out of the box. For even more convenience, Laravel’s .env file configures the framework to use this database out of the box.

To connect to your MySQL or PostgreSQL database from your host machine’s database client, you should connect to 127.0.0.1 and port 33060 (MySQL) or 54320 (PostgreSQL). The username and password for both databases is homestead / secret.

{note} You should only use these non-standard ports when connecting to the databases from your host machine. You will use the default 3306 and 5432 ports in your Laravel database configuration file since Laravel is running within the virtual machine.

<a name=“adding-additional-sites”></a>

7.3.4 Adding Additional Sites

Once your Homestead environment is provisioned and running, you may want to add additional Nginx sites for your Laravel applications. You can run as many Laravel installations as you wish on a single Homestead environment. To add an additional site, simply add the site to your Homestead.yaml file:

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public
    - map: another.app
      to: /home/vagrant/Code/another/public

If Vagrant is not automatically managing your “hosts” file, you may need to add the new site to that file as well:

192.168.10.10  homestead.app
192.168.10.10  another.app

Once the site has been added, run the vagrant reload --provision command from your Homestead directory.

<a name=“site-types”></a>

7.3.4.1 Site Types

Homestead supports several types of sites which allow you to easily run projects that are not based on Laravel. For example, we may easily add a Symfony application to Homestead using the symfony2 site type:

sites:
    - map: symfony2.app
      to: /home/vagrant/Code/Symfony/web
      type: symfony2

The available site types are: apache, laravel (the default), proxy, silverstripe, statamic, symfony2, and symfony4.

<a name=“site-parameters”></a>

7.3.4.2 Site Parameters

You may add additional Nginx fastcgi_param values to your site via the params site directive. For example, we’ll add a FOO parameter with a value of BAR:

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public
      params:
          - key: FOO
            value: BAR

<a name=“configuring-cron-schedules”></a>

7.3.5 Configuring Cron Schedules

Laravel provides a convenient way to schedule Cron jobs by scheduling a single schedule:run Artisan command to be run every minute. The schedule:run command will examine the job schedule defined in your App\Console\Kernel class to determine which jobs should be run.

If you would like the schedule:run command to be run for a Homestead site, you may set the schedule option to true when defining the site:

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public
      schedule: true

The Cron job for the site will be defined in the /etc/cron.d folder of the virtual machine.

<a name=“ports”></a>

7.3.6 Ports

By default, the following ports are forwarded to your Homestead environment:

  • **SSH:** 2222 → Forwards To 22
  • **HTTP:** 8000 → Forwards To 80
  • **HTTPS:** 44300 → Forwards To 443
  • MySQL: 33060 → Forwards To 3306
  • PostgreSQL: 54320 → Forwards To 5432
  • Mailhog: 8025 → Forwards To 8025

7.3.6.1 Forwarding Additional Ports

If you wish, you may forward additional ports to the Vagrant box, as well as specify their protocol:

ports:
    - send: 50000
      to: 5000
    - send: 7777
      to: 777
      protocol: udp

<a name=“sharing-your-environment”></a>

7.3.7 Sharing Your Environment

Sometimes you may wish to share what you’re currently working on with coworkers or a client. Vagrant has a built-in way to support this via vagrant share; however, this will not work if you have multiple sites configured in your Homestead.yaml file.

To solve this problem, Homestead includes its own share command. To get started, SSH into your Homestead machine via vagrant ssh and run share homestead.app. This will share the homestead.app site from your Homestead.yaml configuration file. Of course, you may substitute any of your other configured sites for homestead.app:

share homestead.app

After running the command, you will see an Ngrok screen appear which contains the activity log and the publicly accessible URLs for the shared site. If you would like to specify a custom region, subdomain, or other Ngrok runtime option, you may add them to your share command:

share homestead.app -region=eu -subdomain=laravel

{note} Remember, Vagrant is inherently insecure and you are exposing your virtual machine to the Internet when running the share command.

<a name=“multiple-php-versions”></a>

7.3.8 Multiple PHP Versions

{note} This feature is only compatible with Nginx.

Homestead 6 introduced support for multiple versions of PHP on the same virtual machine. You may specify which version of PHP to use for a given site within your Homestead.yaml file. The available PHP versions are: “5.6”, “7.0”, and “7.1”:

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public
      php: "5.6"

In addition, you may use any of the supported PHP versions via the CLI:

php5.6 artisan list
php7.0 artisan list
php7.1 artisan list

<a name=“network-interfaces”></a>

7.4 Network Interfaces

The networks property of the Homestead.yaml configures network interfaces for your Homestead environment. You may configure as many interfaces as necessary:

networks:
    - type: "private_network"
      ip: "192.168.10.20"

To enable a bridged interface, configure a bridge setting and change the network type to public_network:

networks:
    - type: "public_network"
      ip: "192.168.10.20"
      bridge: "en1: Wi-Fi (AirPort)"

To enable DHCP, just remove the ip option from your configuration:

networks:
    - type: "public_network"
      bridge: "en1: Wi-Fi (AirPort)"

<a name=“updating-homestead”></a>

7.5 Updating Homestead

You can update Homestead in two simple steps. First, you should update the Vagrant box using the vagrant box update command:

vagrant box update

Next, you need to update the Homestead source code. If you cloned the repository you can simply git pull origin master at the location you originally cloned the repository.

If you have installed Homestead via your project’s composer.json file, you should ensure your composer.json file contains "laravel/homestead": "^4" and update your dependencies:

composer update

<a name=“old-versions”></a>

7.6 Old Versions

{tip} If you need an older version of PHP check the documentation on <a href=“#multiple-php-versions”>multiple PHP versions</a> before attempting to use an old version of Homestead.

You can easily override the version of the box that Homestead uses by adding the following line to your Homestead.yaml file:

version: 0.6.0

An example:

box: laravel/homestead
version: 0.6.0
ip: "192.168.20.20"
memory: 2048
cpus: 4
provider: virtualbox

When you use an older version of the Homestead box you need to match that with a compatible version of the Homestead source code. Below is a chart which shows the supported box versions, which version of Homestead source code to use, and the version of PHP provided:

Homestead Version Box Version
PHP 7.0 3.1.0 0.6.0
PHP 7.1 4.0.0 1.0.0
PHP 7.1 5.0.0 2.0.0
PHP 7.1 6.0.0 3.0.0

<a name=“provider-specific-settings”></a>

7.7 Provider Specific Settings

<a name=“provider-specific-virtualbox”></a>

7.7.1 VirtualBox

By default, Homestead configures the natdnshostresolver setting to on. This allows Homestead to use your host operating system’s DNS settings. If you would like to override this behavior, add the following lines to your Homestead.yaml file:

provider: virtualbox
natdnshostresolver: off

8 Laravel Valet

<a name=“introduction”></a>

8.1 Introduction

Valet is a Laravel development environment for Mac minimalists. No Vagrant, no /etc/hosts file. You can even share your sites publicly using local tunnels. Yeah, we like it too.

Laravel Valet configures your Mac to always run Nginx in the background when your machine starts. Then, using DnsMasq, Valet proxies all requests on the *.dev domain to point to sites installed on your local machine.

In other words, a blazing fast Laravel development environment that uses roughly 7 MB of RAM. Valet isn’t a complete replacement for Vagrant or Homestead, but provides a great alternative if you want flexible basics, prefer extreme speed, or are working on a machine with a limited amount of RAM.

Out of the box, Valet support includes, but is not limited to:

<div class=“content-list” markdown=“1”>

However, you may extend Valet with your own custom drivers.

<a name=“valet-or-homestead”></a>

8.1.1 Valet Or Homestead

As you may know, Laravel offers Homestead, another local Laravel development environment. Homestead and Valet differ in regards to their intended audience and their approach to local development. Homestead offers an entire Ubuntu virtual machine with automated Nginx configuration. Homestead is a wonderful choice if you want a fully virtualized Linux development environment or are on Windows / Linux.

Valet only supports Mac, and requires you to install PHP and a database server directly onto your local machine. This is easily achieved by using Homebrew with commands like brew install php71 and brew install mysql. Valet provides a blazing fast local development environment with minimal resource consumption, so it’s great for developers who only require PHP / MySQL and do not need a fully virtualized development environment.

Both Valet and Homestead are great choices for configuring your Laravel development environment. Which one you choose will depend on your personal taste and your team’s needs.

<a name=“installation”></a>

8.2 Installation

Valet requires macOS and Homebrew. Before installation, you should make sure that no other programs such as Apache or Nginx are binding to your local machine’s port 80.

<div class=“content-list” markdown=“1”>

  • Install or update Homebrew to the latest version using brew update.
  • Install PHP 7.1 using Homebrew via brew install homebrew/php/php71.
  • Install Valet with Composer via composer global require laravel/valet. Make sure the ~/.composer/vendor/bin directory is in your system’s “PATH”.
  • Run the valet install command. This will configure and install Valet and DnsMasq, and register Valet’s daemon to launch when your system starts.
    </div>

Once Valet is installed, try pinging any *.dev domain on your terminal using a command such as ping foobar.dev. If Valet is installed correctly you should see this domain responding on 127.0.0.1.

Valet will automatically start its daemon each time your machine boots. There is no need to run valet start or valet install ever again once the initial Valet installation is complete.

8.2.0.1 Using Another Domain

By default, Valet serves your projects using the .dev TLD. If you’d like to use another domain, you can do so using the valet domain tld-name command.

For example, if you’d like to use .app instead of .dev, run valet domain app and Valet will start serving your projects at *.app automatically.

8.2.0.2 Database

If you need a database, try MySQL by running brew install mysql on your command line. Once MySQL has been installed, you may start it using the brew services start mysql command. You can then connect to the database at 127.0.0.1 using the root username and an empty string for the password.

<a name=“upgrading”></a>

8.2.1 Upgrading

You may update your Valet installation using the composer global update command in your terminal. After upgrading, it is good practice to run the valet install command so Valet can make additional upgrades to your configuration files if necessary.

8.2.1.1 Upgrading To Valet 2.0

Valet 2.0 transitions Valet’s underlying web server from Caddy to Nginx. Before upgrading to this version you should run the following commands to stop and uninstall the existing Caddy daemon:

valet stop
valet uninstall

Next, you should upgrade to the latest version of Valet. Depending on how you installed Valet, this is typically done through Git or Composer. If you installed Valet via Composer, you should use the following command to update to the latest major version:

composer global require laravel/valet

Once the fresh Valet source code has been downloaded, you should run the install command:

valet install
valet restart

After upgrading, it may be necessary to re-park or re-link your sites.

<a name=“serving-sites”></a>

8.3 Serving Sites

Once Valet is installed, you’re ready to start serving sites. Valet provides two commands to help you serve your Laravel sites: park and link.

<a name=“the-park-command”></a>
The park Command

<div class=“content-list” markdown=“1”>

  • Create a new directory on your Mac by running something like mkdir ~/Sites. Next, cd ~/Sites and run valet park. This command will register your current working directory as a path that Valet should search for sites.
  • Next, create a new Laravel site within this directory: laravel new blog.
  • Open http://blog.dev in your browser.
    </div>

That’s all there is to it. Now, any Laravel project you create within your “parked” directory will automatically be served using the http://folder-name.dev convention.

<a name=“the-link-command”></a>
The link Command

The link command may also be used to serve your Laravel sites. This command is useful if you want to serve a single site in a directory and not the entire directory.

<div class=“content-list” markdown=“1”>

  • To use the command, navigate to one of your projects and run valet link app-name in your terminal. Valet will create a symbolic link in ~/.valet/Sites which points to your current working directory.
  • After running the link command, you can access the site in your browser at http://app-name.dev.
    </div>

To see a listing of all of your linked directories, run the valet links command. You may use valet unlink app-name to destroy the symbolic link.

{tip} You can use valet link to serve the same project from multiple (sub)domains. To add a subdomain or another domain to your project run valet link subdomain.app-name from the project folder.

<a name=“securing-sites”></a>
Securing Sites With TLS

By default, Valet serves sites over plain HTTP. However, if you would like to serve a site over encrypted TLS using HTTP/2, use the secure command. For example, if your site is being served by Valet on the laravel.dev domain, you should run the following command to secure it:

valet secure laravel

To “unsecure” a site and revert back to serving its traffic over plain HTTP, use the unsecure command. Like the secure command, this command accepts the host name that you wish to unsecure:

valet unsecure laravel

<a name=“sharing-sites”></a>

8.4 Sharing Sites

Valet even includes a command to share your local sites with the world. No additional software installation is required once Valet is installed.

To share a site, navigate to the site’s directory in your terminal and run the valet share command. A publicly accessible URL will be inserted into your clipboard and is ready to paste directly into your browser. That’s it.

To stop sharing your site, hit Control + C to cancel the process.

{note} valet share does not currently support sharing sites that have been secured using the valet secure command.

<a name=“custom-valet-drivers”></a>

8.5 Custom Valet Drivers

You can write your own Valet “driver” to serve PHP applications running on another framework or CMS that is not natively supported by Valet. When you install Valet, a ~/.valet/Drivers directory is created which contains a SampleValetDriver.php file. This file contains a sample driver implementation to demonstrate how to write a custom driver. Writing a driver only requires you to implement three methods: serves, isStaticFile, and frontControllerPath.

All three methods receive the $sitePath, $siteName, and $uri values as their arguments. The $sitePath is the fully qualified path to the site being served on your machine, such as /Users/Lisa/Sites/my-project. The $siteName is the “host” / “site name” portion of the domain (my-project). The $uri is the incoming request URI (/foo/bar).

Once you have completed your custom Valet driver, place it in the ~/.valet/Drivers directory using the FrameworkValetDriver.php naming convention. For example, if you are writing a custom valet driver for WordPress, your file name should be WordPressValetDriver.php.

Let’s take a look at a sample implementation of each method your custom Valet driver should implement.

8.5.0.1 The serves Method

The serves method should return true if your driver should handle the incoming request. Otherwise, the method should return false. So, within this method you should attempt to determine if the given $sitePath contains a project of the type you are trying to serve.

For example, let’s pretend we are writing a WordPressValetDriver. Our serve method might look something like this:

/**
 * Determine if the driver serves the request.
 *
 * @param  string  $sitePath
 * @param  string  $siteName
 * @param  string  $uri
 * @return bool
 */
public function serves($sitePath, $siteName, $uri)
{
    return is_dir($sitePath.'/wp-admin');
}

8.5.0.2 The isStaticFile Method

The isStaticFile should determine if the incoming request is for a file that is “static”, such as an image or a stylesheet. If the file is static, the method should return the fully qualified path to the static file on disk. If the incoming request is not for a static file, the method should return false:

/**
 * Determine if the incoming request is for a static file.
 *
 * @param  string  $sitePath
 * @param  string  $siteName
 * @param  string  $uri
 * @return string|false
 */
public function isStaticFile($sitePath, $siteName, $uri)
{
    if (file_exists($staticFilePath = $sitePath.'/public/'.$uri)) {
        return $staticFilePath;
    }

    return false;
}

{note} The isStaticFile method will only be called if the serves method returns true for the incoming request and the request URI is not /.

8.5.0.3 The frontControllerPath Method

The frontControllerPath method should return the fully qualified path to your application’s “front controller”, which is typically your “index.php” file or equivalent:

/**
 * Get the fully resolved path to the application's front controller.
 *
 * @param  string  $sitePath
 * @param  string  $siteName
 * @param  string  $uri
 * @return string
 */
public function frontControllerPath($sitePath, $siteName, $uri)
{
    return $sitePath.'/public/index.php';
}

<a name=“local-drivers”></a>

8.5.1 Local Drivers

If you would like to define a custom Valet driver for a single application, create a LocalValetDriver.php in the application’s root directory. Your custom driver may extend the base ValetDriver class or extend an existing application specific driver such as the LaravelValetDriver:

class LocalValetDriver extends LaravelValetDriver
{
    /**
     * Determine if the driver serves the request.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return bool
     */
    public function serves($sitePath, $siteName, $uri)
    {
        return true;
    }

    /**
     * Get the fully resolved path to the application's front controller.
     *
     * @param  string  $sitePath
     * @param  string  $siteName
     * @param  string  $uri
     * @return string
     */
    public function frontControllerPath($sitePath, $siteName, $uri)
    {
        return $sitePath.'/public_html/index.php';
    }
}

<a name=“other-valet-commands”></a>

8.6 Other Valet Commands

Command Description
valet forget Run this command from a “parked” directory to remove it from the parked directory list.
valet paths View all of your “parked” paths.
valet restart Restart the Valet daemon.
valet start Start the Valet daemon.
valet stop Stop the Valet daemon.
valet uninstall Uninstall the Valet daemon entirely.

9 Request Lifecycle

<a name=“introduction”></a>

9.1 Introduction

When using any tool in the “real world”, you feel more confident if you understand how that tool works. Application development is no different. When you understand how your development tools function, you feel more comfortable and confident using them.

The goal of this document is to give you a good, high-level overview of how the Laravel framework works. By getting to know the overall framework better, everything feels less “magical” and you will be more confident building your applications. If you don’t understand all of the terms right away, don’t lose heart! Just try to get a basic grasp of what is going on, and your knowledge will grow as you explore other sections of the documentation.

<a name=“lifecycle-overview”></a>

9.2 Lifecycle Overview

9.2.1 First Things

The entry point for all requests to a Laravel application is the public/index.php file. All requests are directed to this file by your web server (Apache / Nginx) configuration. The index.php file doesn’t contain much code. Rather, it is simply a starting point for loading the rest of the framework.

The index.php file loads the Composer generated autoloader definition, and then retrieves an instance of the Laravel application from bootstrap/app.php script. The first action taken by Laravel itself is to create an instance of the application / service container.

9.2.2 HTTP / Console Kernels

Next, the incoming request is sent to either the HTTP kernel or the console kernel, depending on the type of request that is entering the application. These two kernels serve as the central location that all requests flow through. For now, let’s just focus on the HTTP kernel, which is located in app/Http/Kernel.php.

The HTTP kernel extends the Illuminate\Foundation\Http\Kernel class, which defines an array of bootstrappers that will be run before the request is executed. These bootstrappers configure error handling, configure logging, detect the application environment, and perform other tasks that need to be done before the request is actually handled.

The HTTP kernel also defines a list of HTTP middleware that all requests must pass through before being handled by the application. These middleware handle reading and writing the HTTP session, determining if the application is in maintenance mode, verifying the CSRF token, and more.

The method signature for the HTTP kernel’s handle method is quite simple: receive a Request and return a Response. Think of the Kernel as being a big black box that represents your entire application. Feed it HTTP requests and it will return HTTP responses.

9.2.2.1 Service Providers

One of the most important Kernel bootstrapping actions is loading the service providers for your application. All of the service providers for the application are configured in the config/app.php configuration file’s providers array. First, the register method will be called on all providers, then, once all providers have been registered, the boot method will be called.

Service providers are responsible for bootstrapping all of the framework’s various components, such as the database, queue, validation, and routing components. Since they bootstrap and configure every feature offered by the framework, service providers are the most important aspect of the entire Laravel bootstrap process.

9.2.2.2 Dispatch Request

Once the application has been bootstrapped and all service providers have been registered, the Request will be handed off to the router for dispatching. The router will dispatch the request to a route or controller, as well as run any route specific middleware.

<a name=“focus-on-service-providers”></a>

9.3 Focus On Service Providers

Service providers are truly the key to bootstrapping a Laravel application. The application instance is created, the service providers are registered, and the request is handed to the bootstrapped application. It’s really that simple!

Having a firm grasp of how a Laravel application is built and bootstrapped via service providers is very valuable. Of course, your application’s default service providers are stored in the app/Providers directory.

By default, the AppServiceProvider is fairly empty. This provider is a great place to add your application’s own bootstrapping and service container bindings. Of course, for large applications, you may wish to create several service providers, each with a more granular type of bootstrapping.

10 Service Container

<a name=“introduction”></a>

10.1 Introduction

The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are “injected” into the class via the constructor or, in some cases, “setter” methods.

Let’s look at a simple example:

<?php

namespace App\Http\Controllers;

use App\User;
use App\Repositories\UserRepository;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * The user repository implementation.
     *
     * @var UserRepository
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function show($id)
    {
        $user = $this->users->find($id);

        return view('user.profile', ['user' => $user]);
    }
}

In this example, the UserController needs to retrieve users from a data source. So, we will inject a service that is able to retrieve users. In this context, our UserRepository most likely uses Eloquent to retrieve user information from the database. However, since the repository is injected, we are able to easily swap it out with another implementation. We are also able to easily “mock”, or create a dummy implementation of the UserRepository when testing our application.

A deep understanding of the Laravel service container is essential to building a powerful, large application, as well as for contributing to the Laravel core itself.

<a name=“binding”></a>

10.2 Binding

<a name=“binding-basics”></a>

10.2.1 Binding Basics

Almost all of your service container bindings will be registered within service providers, so most of these examples will demonstrate using the container in that context.

{tip} There is no need to bind classes into the container if they do not depend on any interfaces. The container does not need to be instructed on how to build these objects, since it can automatically resolve these objects using reflection.

10.2.1.1 Simple Bindings

Within a service provider, you always have access to the container via the $this->app property. We can register a binding using the bind method, passing the class or interface name that we wish to register along with a Closure that returns an instance of the class:

$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});

Note that we receive the container itself as an argument to the resolver. We can then use the container to resolve sub-dependencies of the object we are building.

10.2.1.2 Binding A Singleton

The singleton method binds a class or interface into the container that should only be resolved one time. Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container:

$this->app->singleton('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});

10.2.1.3 Binding Instances

You may also bind an existing object instance into the container using the instance method. The given instance will always be returned on subsequent calls into the container:

$api = new HelpSpot\API(new HttpClient);

$this->app->instance('HelpSpot\API', $api);

10.2.1.4 Binding Primitives

Sometimes you may have a class that receives some injected classes, but also needs an injected primitive value such as an integer. You may easily use contextual binding to inject any value your class may need:

$this->app->when('App\Http\Controllers\UserController')
          ->needs('$variableName')
          ->give($value);

<a name=“binding-interfaces-to-implementations”></a>

10.2.2 Binding Interfaces To Implementations

A very powerful feature of the service container is its ability to bind an interface to a given implementation. For example, let’s assume we have an EventPusher interface and a RedisEventPusher implementation. Once we have coded our RedisEventPusher implementation of this interface, we can register it with the service container like so:

$this->app->bind(
    'App\Contracts\EventPusher',
    'App\Services\RedisEventPusher'
);

This statement tells the container that it should inject the RedisEventPusher when a class needs an implementation of EventPusher. Now we can type-hint the EventPusher interface in a constructor, or any other location where dependencies are injected by the service container:

use App\Contracts\EventPusher;

/**
 * Create a new class instance.
 *
 * @param  EventPusher  $pusher
 * @return void
 */
public function __construct(EventPusher $pusher)
{
    $this->pusher = $pusher;
}

<a name=“contextual-binding”></a>

10.2.3 Contextual Binding

Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, two controllers may depend on different implementations of the Illuminate\Contracts\Filesystem\Filesystem contract. Laravel provides a simple, fluent interface for defining this behavior:

use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;

$this->app->when(PhotoController::class)
          ->needs(Filesystem::class)
          ->give(function () {
              return Storage::disk('local');
          });

$this->app->when(VideoController::class)
          ->needs(Filesystem::class)
          ->give(function () {
              return Storage::disk('s3');
          });

<a name=“tagging”></a>

10.2.4 Tagging

Occasionally, you may need to resolve all of a certain “category” of binding. For example, perhaps you are building a report aggregator that receives an array of many different Report interface implementations. After registering the Report implementations, you can assign them a tag using the tag method:

$this->app->bind('SpeedReport', function () {
    //
});

$this->app->bind('MemoryReport', function () {
    //
});

$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');

Once the services have been tagged, you may easily resolve them all via the tagged method:

$this->app->bind('ReportAggregator', function ($app) {
    return new ReportAggregator($app->tagged('reports'));
});

<a name=“resolving”></a>

10.3 Resolving

<a name=“the-make-method”></a>

10.3.0.1 The make Method

You may use the make method to resolve a class instance out of the container. The make method accepts the name of the class or interface you wish to resolve:

$api = $this->app->make('HelpSpot\API');

If you are in a location of your code that does not have access to the $app variable, you may use the global resolve helper:

$api = resolve('HelpSpot\API');

If some of your class’ dependencies are not resolvable via the container, you may inject them by passing them as an associative array into the makeWith method:

$api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);

<a name=“automatic-injection”></a>

10.3.0.2 Automatic Injection

Alternatively, and importantly, you may simply “type-hint” the dependency in the constructor of a class that is resolved by the container, including controllers, event listeners, queue jobs, middleware, and more. In practice, this is how most of your objects should be resolved by the container.

For example, you may type-hint a repository defined by your application in a controller’s constructor. The repository will automatically be resolved and injected into the class:

<?php

namespace App\Http\Controllers;

use App\Users\Repository as UserRepository;

class UserController extends Controller
{
    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

    /**
     * Show the user with the given ID.
     *
     * @param  int  $id
     * @return Response
     */
    public function show($id)
    {
        //
    }
}

<a name=“container-events”></a>

10.4 Container Events

The service container fires an event each time it resolves an object. You may listen to this event using the resolving method:

$this->app->resolving(function ($object, $app) {
    // Called when container resolves object of any type...
});

$this->app->resolving(HelpSpot\API::class, function ($api, $app) {
    // Called when container resolves objects of type "HelpSpot\API"...
});

As you can see, the object being resolved will be passed to the callback, allowing you to set any additional properties on the object before it is given to its consumer.

<a name=“psr-11”></a>

10.5 PSR-11

Laravel’s service container implements the PSR-11 interface. Therefore, you may type-hint the PSR-11 container interface to obtain an instance of the Laravel container:

use Psr\Container\ContainerInterface;

Route::get('/', function (ContainerInterface $container) {
    $service = $container->get('Service');

    //
});

{note} Calling the get method will throw an exception if the identifier has not been explicitly bound into the container.

11 Service Providers

<a name=“introduction”></a>

11.1 Introduction

Service providers are the central place of all Laravel application bootstrapping. Your own application, as well as all of Laravel’s core services are bootstrapped via service providers.

But, what do we mean by “bootstrapped”? In general, we mean registering things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application.

If you open the config/app.php file included with Laravel, you will see a providers array. These are all of the service provider classes that will be loaded for your application. Of course, many of these are “deferred” providers, meaning they will not be loaded on every request, but only when the services they provide are actually needed.

In this overview you will learn how to write your own service providers and register them with your Laravel application.

<a name=“writing-service-providers”></a>

11.2 Writing Service Providers

All service providers extend the Illuminate\Support\ServiceProvider class. Most service providers contain a register and a boot method. Within the register method, you should only bind things into the service container. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register method.

The Artisan CLI can generate a new provider via the make:provider command:

php artisan make:provider RiakServiceProvider

<a name=“the-register-method”></a>

11.2.1 The Register Method

As mentioned previously, within the register method, you should only bind things into the service container. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register method. Otherwise, you may accidentally use a service that is provided by a service provider which has not loaded yet.

Let’s take a look at a basic service provider. Within any of your service provider methods, you always have access to the $app property which provides access to the service container:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection(config('riak'));
        });
    }
}

This service provider only defines a register method, and uses that method to define an implementation of Riak\Connection in the service container. If you don’t understand how the service container works, check out its documentation.

<a name=“the-boot-method”></a>

11.2.2 The Boot Method

So, what if we need to register a view composer within our service provider? This should be done within the boot method. This method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('view', function () {
            //
        });
    }
}

11.2.2.1 Boot Method Dependency Injection

You may type-hint dependencies for your service provider’s boot method. The service container will automatically inject any dependencies you need:

use Illuminate\Contracts\Routing\ResponseFactory;

public function boot(ResponseFactory $response)
{
    $response->macro('caps', function ($value) {
        //
    });
}

<a name=“registering-providers”></a>

11.3 Registering Providers

All service providers are registered in the config/app.php configuration file. This file contains a providers array where you can list the class names of your service providers. By default, a set of Laravel core service providers are listed in this array. These providers bootstrap the core Laravel components, such as the mailer, queue, cache, and others.

To register your provider, simply add it to the array:

'providers' => [
    // Other Service Providers

    App\Providers\ComposerServiceProvider::class,
],

<a name=“deferred-providers”></a>

11.4 Deferred Providers

If your provider is only registering bindings in the service container, you may choose to defer its registration until one of the registered bindings is actually needed. Deferring the loading of such a provider will improve the performance of your application, since it is not loaded from the filesystem on every request.

Laravel compiles and stores a list of all of the services supplied by deferred service providers, along with the name of its service provider class. Then, only when you attempt to resolve one of these services does Laravel load the service provider.

To defer the loading of a provider, set the defer property to true and define a provides method. The provides method should return the service container bindings registered by the provider:

<?php

namespace App\Providers;

use Riak\Connection;
use Illuminate\Support\ServiceProvider;

class RiakServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection($app['config']['riak']);
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [Connection::class];
    }

}

12 Facades

<a name=“introduction”></a>

12.1 Introduction

Facades provide a “static” interface to classes that are available in the application’s service container. Laravel ships with many facades which provide access to almost all of Laravel’s features. Laravel facades serve as “static proxies” to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.

All of Laravel’s facades are defined in the Illuminate\Support\Facades namespace. So, we can easily access a facade like so:

use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});

Throughout the Laravel documentation, many of the examples will use facades to demonstrate various features of the framework.

<a name=“when-to-use-facades”></a>

12.2 When To Use Facades

Facades have many benefits. They provide a terse, memorable syntax that allows you to use Laravel’s features without remembering long class names that must be injected or configured manually. Furthermore, because of their unique usage of PHP’s dynamic methods, they are easy to test.

However, some care must be taken when using facades. The primary danger of facades is class scope creep. Since facades are so easy to use and do not require injection, it can be easy to let your classes continue to grow and use many facades in a single class. Using dependency injection, this potential is mitigated by the visual feedback a large constructor gives you that your class is growing too large. So, when using facades, pay special attention to the size of your class so that its scope of responsibility stays narrow.

{tip} When building a third-party package that interacts with Laravel, it’s better to inject Laravel contracts instead of using facades. Since packages are built outside of Laravel itself, you will not have access to Laravel’s facade testing helpers.

<a name=“facades-vs-dependency-injection”></a>

12.2.1 Facades Vs. Dependency Injection

One of the primary benefits of dependency injection is the ability to swap implementations of the injected class. This is useful during testing since you can inject a mock or stub and assert that various methods were called on the stub.

Typically, it would not be possible to mock or stub a truly static class method. However, since facades use dynamic methods to proxy method calls to objects resolved from the service container, we actually can test facades just as we would test an injected class instance. For example, given the following route:

use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});

We can write the following test to verify that the Cache::get method was called with the argument we expected:

use Illuminate\Support\Facades\Cache;

/**
 * A basic functional test example.
 *
 * @return void
 */
public function testBasicExample()
{
    Cache::shouldReceive('get')
         ->with('key')
         ->andReturn('value');

    $this->visit('/cache')
         ->see('value');
}

<a name=“facades-vs-helper-functions”></a>

12.2.2 Facades Vs. Helper Functions

In addition to facades, Laravel includes a variety of “helper” functions which can perform common tasks like generating views, firing events, dispatching jobs, or sending HTTP responses. Many of these helper functions perform the same function as a corresponding facade. For example, this facade call and helper call are equivalent:

return View::make('profile');

return view('profile');

There is absolutely no practical difference between facades and helper functions. When using helper functions, you may still test them exactly as you would the corresponding facade. For example, given the following route:

Route::get('/cache', function () {
    return cache('key');
});

Under the hood, the cache helper is going to call the get method on the class underlying the Cache facade. So, even though we are using the helper function, we can write the following test to verify that the method was called with the argument we expected:

use Illuminate\Support\Facades\Cache;

/**
 * A basic functional test example.
 *
 * @return void
 */
public function testBasicExample()
{
    Cache::shouldReceive('get')
         ->with('key')
         ->andReturn('value');

    $this->visit('/cache')
         ->see('value');
}

<a name=“how-facades-work”></a>

12.3 How Facades Work

In a Laravel application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the Facade class. Laravel’s facades, and any custom facades you create, will extend the base Illuminate\Support\Facades\Facade class.

The Facade base class makes use of the __callStatic() magic-method to defer calls from your facade to an object resolved from the container. In the example below, a call is made to the Laravel cache system. By glancing at this code, one might assume that the static method get is being called on the Cache class:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        $user = Cache::get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}

Notice that near the top of the file we are “importing” the Cache facade. This facade serves as a proxy to accessing the underlying implementation of the Illuminate\Contracts\Cache\Factory interface. Any calls we make using the facade will be passed to the underlying instance of Laravel’s cache service.

If we look at that Illuminate\Support\Facades\Cache class, you’ll see that there is no static method get:

class Cache extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'cache'; }
}

Instead, the Cache facade extends the base Facade class and defines the method getFacadeAccessor(). This method’s job is to return the name of a service container binding. When a user references any static method on the Cache facade, Laravel resolves the cache binding from the service container and runs the requested method (in this case, get) against that object.

<a name=“facade-class-reference”></a>

12.4 Facade Class Reference

Below you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The service container binding key is also included where applicable.

Facade Class Service Container Binding
App Illuminate\Foundation\Application app
Artisan Illuminate\Contracts\Console\Kernel artisan
Auth Illuminate\Auth\AuthManager auth
Blade Illuminate\View\Compilers\BladeCompiler blade.compiler
Bus Illuminate\Contracts\Bus\Dispatcher  
Cache Illuminate\Cache\Repository cache
Config Illuminate\Config\Repository config
Cookie Illuminate\Cookie\CookieJar cookie
Crypt Illuminate\Encryption\Encrypter encrypter
DB Illuminate\Database\DatabaseManager db
DB (Instance) Illuminate\Database\Connection  
Event Illuminate\Events\Dispatcher events
File Illuminate\Filesystem\Filesystem files
Gate Illuminate\Contracts\Auth\Access\Gate  
Hash Illuminate\Contracts\Hashing\Hasher hash
Lang Illuminate\Translation\Translator translator
Log Illuminate\Log\Writer log
Mail Illuminate\Mail\Mailer mailer
Notification Illuminate\Notifications\ChannelManager  
Password Illuminate\Auth\Passwords\PasswordBrokerManager auth.password
Queue Illuminate\Queue\QueueManager queue
Queue (Instance) Illuminate\Contracts\Queue\Queue queue
Queue (Base Class) Illuminate\Queue\Queue  
Redirect Illuminate\Routing\Redirector redirect
Redis Illuminate\Redis\Database redis
Request Illuminate\Http\Request request
Response Illuminate\Contracts\Routing\ResponseFactory  
Route Illuminate\Routing\Router router
Schema Illuminate\Database\Schema\Blueprint  
Session Illuminate\Session\SessionManager session
Session (Instance) Illuminate\Session\Store  
Storage Illuminate\Contracts\Filesystem\Factory filesystem
URL Illuminate\Routing\UrlGenerator url
Validator Illuminate\Validation\Factory validator
Validator (Instance) Illuminate\Validation\Validator  
View Illuminate\View\Factory view
View (Instance) Illuminate\View\View  

13 Contracts

<a name=“introduction”></a>

13.1 Introduction

Laravel’s Contracts are a set of interfaces that define the core services provided by the framework. For example, a Illuminate\Contracts\Queue\Queue contract defines the methods needed for queueing jobs, while the Illuminate\Contracts\Mail\Mailer contract defines the methods needed for sending e-mail.

Each contract has a corresponding implementation provided by the framework. For example, Laravel provides a queue implementation with a variety of drivers, and a mailer implementation that is powered by SwiftMailer.

All of the Laravel contracts live in their own GitHub repository. This provides a quick reference point for all available contracts, as well as a single, decoupled package that may be utilized by package developers.

<a name=“contracts-vs-facades”></a>

13.1.1 Contracts Vs. Facades

Laravel’s facades and helper functions provide a simple way of utilizing Laravel’s services without needing to type-hint and resolve contracts out of the service container. In most cases, each facade has an equivalent contract.

Unlike facades, which do not require you to require them in your class’ constructor, contracts allow you to define explicit dependencies for your classes. Some developers prefer to explicitly define their dependencies in this way and therefore prefer to use contracts, while other developers enjoy the convenience of facades.

{tip} Most applications will be fine regardless of whether you prefer facades or contracts. However, if you are building a package, you should strongly consider using contracts since they will be easier to test in a package context.

<a name=“when-to-use-contracts”></a>

13.2 When To Use Contracts

As discussed elsewhere, much of the decision to use contracts or facades will come down to personal taste and the tastes of your development team. Both contracts and facades can be used to create robust, well-tested Laravel applications. As long as you are keeping your class’ responsibilities focused, you will notice very few practical differences between using contracts and facades.

However, you may still have several questions regarding contracts. For example, why use interfaces at all? Isn’t using interfaces more complicated? Let’s distill the reasons for using interfaces to the following headings: loose coupling and simplicity.

<a name=“loose-coupling”></a>

13.2.1 Loose Coupling

First, let’s review some code that is tightly coupled to a cache implementation. Consider the following:

<?php

namespace App\Orders;

class Repository
{
    /**
     * The cache instance.
     */
    protected $cache;

    /**
     * Create a new repository instance.
     *
     * @param  \SomePackage\Cache\Memcached  $cache
     * @return void
     */
    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }

    /**
     * Retrieve an Order by ID.
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}

In this class, the code is tightly coupled to a given cache implementation. It is tightly coupled because we are depending on a concrete Cache class from a package vendor. If the API of that package changes our code must change as well.

Likewise, if we want to replace our underlying cache technology (Memcached) with another technology (Redis), we again will have to modify our repository. Our repository should not have so much knowledge regarding who is providing them data or how they are providing it.

Instead of this approach, we can improve our code by depending on a simple, vendor agnostic interface:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository
{
    /**
     * The cache instance.
     */
    protected $cache;

    /**
     * Create a new repository instance.
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }
}

Now the code is not coupled to any specific vendor, or even Laravel. Since the contracts package contains no implementation and no dependencies, you may easily write an alternative implementation of any given contract, allowing you to replace your cache implementation without modifying any of your cache consuming code.

<a name=“simplicity”></a>

13.2.2 Simplicity

When all of Laravel’s services are neatly defined within simple interfaces, it is very easy to determine the functionality offered by a given service. The contracts serve as succinct documentation to the framework’s features.

In addition, when you depend on simple interfaces, your code is easier to understand and maintain. Rather than tracking down which methods are available to you within a large, complicated class, you can refer to a simple, clean interface.

<a name=“how-to-use-contracts”></a>

13.3 How To Use Contracts

So, how do you get an implementation of a contract? It’s actually quite simple.

Many types of classes in Laravel are resolved through the service container, including controllers, event listeners, middleware, queued jobs, and even route Closures. So, to get an implementation of a contract, you can just “type-hint” the interface in the constructor of the class being resolved.

For example, take a look at this event listener:

<?php

namespace App\Listeners;

use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Database;

class CacheOrderInformation
{
    /**
     * The Redis database implementation.
     */
    protected $redis;

    /**
     * Create a new event handler instance.
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * Handle the event.
     *
     * @param  OrderWasPlaced  $event
     * @return void
     */
    public function handle(OrderWasPlaced $event)
    {
        //
    }
}

When the event listener is resolved, the service container will read the type-hints on the constructor of the class, and inject the appropriate value. To learn more about registering things in the service container, check out its documentation.

<a name=“contract-reference”></a>

13.4 Contract Reference

This table provides a quick reference to all of the Laravel contracts and their equivalent facades:

Contract References Facade
Illuminate\Contracts\Auth\Factory Auth
Illuminate\Contracts\Auth\PasswordBroker Password
Illuminate\Contracts\Bus\Dispatcher Bus
Illuminate\Contracts\Broadcasting\Broadcaster  
Illuminate\Contracts\Cache\Repository Cache
Illuminate\Contracts\Cache\Factory Cache::driver()
Illuminate\Contracts\Config\Repository Config
Illuminate\Contracts\Container\Container App
Illuminate\Contracts\Cookie\Factory Cookie
Illuminate\Contracts\Cookie\QueueingFactory Cookie::queue()
Illuminate\Contracts\Encryption\Encrypter Crypt
Illuminate\Contracts\Events\Dispatcher Event
Illuminate\Contracts\Filesystem\Cloud  
Illuminate\Contracts\Filesystem\Factory File
Illuminate\Contracts\Filesystem\Filesystem File
Illuminate\Contracts\Foundation\Application App
Illuminate\Contracts\Hashing\Hasher Hash
Illuminate\Contracts\Logging\Log Log
Illuminate\Contracts\Mail\MailQueue Mail::queue()
Illuminate\Contracts\Mail\Mailer Mail
Illuminate\Contracts\Queue\Factory Queue::driver()
Illuminate\Contracts\Queue\Queue Queue
Illuminate\Contracts\Redis\Factory Redis
Illuminate\Contracts\Routing\Registrar Route
Illuminate\Contracts\Routing\ResponseFactory Response
Illuminate\Contracts\Routing\UrlGenerator URL
Illuminate\Contracts\Support\Arrayable  
Illuminate\Contracts\Support\Jsonable  
Illuminate\Contracts\Support\Renderable  
Illuminate\Contracts\Validation\Factory Validator::make()
Illuminate\Contracts\Validation\Validator  
Illuminate\Contracts\View\Factory View::make()
Illuminate\Contracts\View\View  

14 Routing

<a name=“basic-routing”></a>

14.1 Basic Routing

The most basic Laravel routes simply accept a URI and a Closure, providing a very simple and expressive method of defining routes:

Route::get('foo', function () {
    return 'Hello World';
});

14.1.0.1 The Default Route Files

All Laravel routes are defined in your route files, which are located in the routes directory. These files are automatically loaded by the framework. The routes/web.php file defines routes that are for your web interface. These routes are assigned the web middleware group, which provides features like session state and CSRF protection. The routes in routes/api.php are stateless and are assigned the api middleware group.

For most applications, you will begin by defining routes in your routes/web.php file. The routes defined in routes/web.php may be accessed by entering the defined route’s URL in your browser. For example, you may access the following route by navigating to http://your-app.dev/user in your browser:

Route::get('/user', 'UsersController@index');

Routes defined in the routes/api.php file are nested within a route group by the RouteServiceProvider. Within this group, the /api URI prefix is automatically applied so you do not need to manually apply it to every route in the file. You may modify the prefix and other route group options by modifying your RouteServiceProvider class.

14.1.0.2 Available Router Methods

The router allows you to register routes that respond to any HTTP verb:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the match method. Or, you may even register a route that responds to all HTTP verbs using the any method:

Route::match(['get', 'post'], '/', function () {
    //
});

Route::any('foo', function () {
    //
});

14.1.0.3 CSRF Protection

Any HTML forms pointing to POST, PUT, or DELETE routes that are defined in the web routes file should include a CSRF token field. Otherwise, the request will be rejected. You can read more about CSRF protection in the CSRF documentation:

<form method="POST" action="/profile">
    {{ csrf_field() }}
    ...
</form>

<a name=“redirect-routes”></a>

14.1.1 Redirect Routes

If you are defining a route that redirects to another URI, you may use the Route::redirect method. This method provides a convenient shortcut so that you do not have to define a full route or controller for performing a simple redirect:

Route::redirect('/here', '/there', 301);

<a name=“view-routes”></a>

14.1.2 View Routes

If your route only needs to return a view, you may use the Route::view method. Like the redirect method, this method provides a simple shortcut so that you do not have to define a full route or controller. The view method accepts a URI as its first argument and a view name as its second argument. In addition, you may provide an array of data to pass to the view as an optional third argument:

Route::view('/welcome', 'welcome');

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

<a name=“route-parameters”></a>

14.2 Route Parameters

<a name=“required-parameters”></a>

14.2.1 Required Parameters

Of course, sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user’s ID from the URL. You may do so by defining route parameters:

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

You may define as many route parameters as required by your route:

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

Route parameters are always encased within {} braces and should consist of alphabetic characters, and may not contain a - character. Instead of using the - character, use an underscore (_) instead. Route parameters are injected into route callbacks / controllers based on their order - the names of the callback / controller arguments do not matter.

<a name=“parameters-optional-parameters”></a>

14.2.2 Optional Parameters

Occasionally you may need to specify a route parameter, but make the presence of that route parameter optional. You may do so by placing a ? mark after the parameter name. Make sure to give the route’s corresponding variable a default value:

Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

<a name=“parameters-regular-expression-constraints”></a>

14.2.3 Regular Expression Constraints

You may constrain the format of your route parameters using the where method on a route instance. The where method accepts the name of the parameter and a regular expression defining how the parameter should be constrained:

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

<a name=“parameters-global-constraints”></a>

14.2.3.1 Global Constraints

If you would like a route parameter to always be constrained by a given regular expression, you may use the pattern method. You should define these patterns in the boot method of your RouteServiceProvider:

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');

    parent::boot();
}

Once the pattern has been defined, it is automatically applied to all routes using that parameter name:

Route::get('user/{id}', function ($id) {
    // Only executed if {id} is numeric...
});

<a name=“named-routes”></a>

14.3 Named Routes

Named routes allow the convenient generation of URLs or redirects for specific routes. You may specify a name for a route by chaining the name method onto the route definition:

Route::get('user/profile', function () {
    //
})->name('profile');

You may also specify route names for controller actions:

Route::get('user/profile', 'UserController@showProfile')->name('profile');

14.3.0.1 Generating URLs To Named Routes

Once you have assigned a name to a given route, you may use the route’s name when generating URLs or redirects via the global route function:

// Generating URLs...
$url = route('profile');

// Generating Redirects...
return redirect()->route('profile');

If the named route defines parameters, you may pass the parameters as the second argument to the route function. The given parameters will automatically be inserted into the URL in their correct positions:

Route::get('user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1]);

14.3.0.2 Inspecting The Current Route

If you would like to determine if the current request was routed to a given named route, you may use the named method on a Route instance. For example, you may check the current route name from a route middleware:

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    if ($request->route()->named('profile')) {
        //
    }

    return $next($request);
}

<a name=“route-groups”></a>

14.4 Route Groups

Route groups allow you to share route attributes, such as middleware or namespaces, across a large number of routes without needing to define those attributes on each individual route. Shared attributes are specified in an array format as the first parameter to the Route::group method.

<a name=“route-group-middleware”></a>

14.4.1 Middleware

To assign middleware to all routes within a group, you may use the middleware method before defining the group. Middleware are executed in the order they are listed in the array:

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // Uses first & second Middleware
    });

    Route::get('user/profile', function () {
        // Uses first & second Middleware
    });
});

<a name=“route-group-namespaces”></a>

14.4.2 Namespaces

Another common use-case for route groups is assigning the same PHP namespace to a group of controllers using the namespace method:

Route::namespace('Admin')->group(function () {
    // Controllers Within The "App\Http\Controllers\Admin" Namespace
});

Remember, by default, the RouteServiceProvider includes your route files within a namespace group, allowing you to register controller routes without specifying the full App\Http\Controllers namespace prefix. So, you only need to specify the portion of the namespace that comes after the base App\Http\Controllers namespace.

<a name=“route-group-sub-domain-routing”></a>

14.4.3 Sub-Domain Routing

Route groups may also be used to handle sub-domain routing. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified by calling the the domain method before defining the group:

Route::domain('{account}.myapp.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});

<a name=“route-group-prefixes”></a>

14.4.4 Route Prefixes

The prefix method may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:

Route::prefix('admin')->group(function () {
    Route::get('users', function () {
        // Matches The "/admin/users" URL
    });
});

<a name=“route-model-binding”></a>

14.5 Route Model Binding

When injecting a model ID to a route or controller action, you will often query to retrieve the model that corresponds to that ID. Laravel route model binding provides a convenient way to automatically inject the model instances directly into your routes. For example, instead of injecting a user’s ID, you can inject the entire User model instance that matches the given ID.

<a name=“implicit-binding”></a>

14.5.1 Implicit Binding

Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name. For example:

Route::get('api/users/{user}', function (App\User $user) {
    return $user->email;
});

Since the $user variable is type-hinted as the App\User Eloquent model and the variable name matches the {user} URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI. If a matching model instance is not found in the database, a 404 HTTP response will automatically be generated.

14.5.1.1 Customizing The Key Name

If you would like model binding to use a database column other than id when retrieving a given model class, you may override the getRouteKeyName method on the Eloquent model:

/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

<a name=“explicit-binding”></a>

14.5.2 Explicit Binding

To register an explicit binding, use the router’s model method to specify the class for a given parameter. You should define your explicit model bindings in the boot method of the RouteServiceProvider class:

public function boot()
{
    parent::boot();

    Route::model('user', App\User::class);
}

Next, define a route that contains a {user} parameter:

Route::get('profile/{user}', function (App\User $user) {
    //
});

Since we have bound all {user} parameters to the App\User model, a User instance will be injected into the route. So, for example, a request to profile/1 will inject the User instance from the database which has an ID of 1.

If a matching model instance is not found in the database, a 404 HTTP response will be automatically generated.

14.5.2.1 Customizing The Resolution Logic

If you wish to use your own resolution logic, you may use the Route::bind method. The Closure you pass to the bind method will receive the value of the URI segment and should return the instance of the class that should be injected into the route:

public function boot()
{
    parent::boot();

    Route::bind('user', function ($value) {
        return App\User::where('name', $value)->first();
    });
}

<a name=“form-method-spoofing”></a>

14.6 Form Method Spoofing

HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form. The value sent with the _method field will be used as the HTTP request method:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

You may use the method_field helper to generate the _method input:

{{ method_field('PUT') }}

<a name=“accessing-the-current-route”></a>

14.7 Accessing The Current Route

You may use the current, currentRouteName, and currentRouteAction methods on the Route facade to access information about the route handling the incoming request:

$route = Route::current();

$name = Route::currentRouteName();

$action = Route::currentRouteAction();

Refer to the API documentation for both the underlying class of the Route facade and Route instance to review all accessible methods.

15 Middleware

<a name=“introduction”></a>

15.1 Introduction

Middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.

Of course, additional middleware can be written to perform a variety of tasks besides authentication. A CORS middleware might be responsible for adding the proper headers to all responses leaving your application. A logging middleware might log all incoming requests to your application.

There are several middleware included in the Laravel framework, including middleware for authentication and CSRF protection. All of these middleware are located in the app/Http/Middleware directory.

<a name=“defining-middleware”></a>

15.2 Defining Middleware

To create a new middleware, use the make:middleware Artisan command:

php artisan make:middleware CheckAge

This command will place a new CheckAge class within your app/Http/Middleware directory. In this middleware, we will only allow access to the route if the supplied age is greater than 200. Otherwise, we will redirect the users back to the home URI.

<?php

namespace App\Http\Middleware;

use Closure;

class CheckAge
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->age <= 200) {
            return redirect('home');
        }

        return $next($request);
    }
}

As you can see, if the given age is less than or equal to 200, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application. To pass the request deeper into the application (allowing the middleware to “pass”), simply call the $next callback with the $request.

It’s best to envision middleware as a series of “layers” HTTP requests must pass through before they hit your application. Each layer can examine the request and even reject it entirely.

15.2.1 Before & After Middleware

Whether a middleware runs before or after a request depends on the middleware itself. For example, the following middleware would perform some task before the request is handled by the application:

<?php

namespace App\Http\Middleware;

use Closure;

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        // Perform action

        return $next($request);
    }
}

However, this middleware would perform its task after the request is handled by the application:

<?php

namespace App\Http\Middleware;

use Closure;

class AfterMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // Perform action

        return $response;
    }
}

<a name=“registering-middleware”></a>

15.3 Registering Middleware

<a name=“global-middleware”></a>

15.3.1 Global Middleware

If you want a middleware to run during every HTTP request to your application, simply list the middleware class in the $middleware property of your app/Http/Kernel.php class.

<a name=“assigning-middleware-to-routes”></a>

15.3.2 Assigning Middleware To Routes

If you would like to assign middleware to specific routes, you should first assign the middleware a key in your app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel. To add your own, simply append it to this list and assign it a key of your choosing. For example:

// Within App\Http\Kernel Class...

protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];

Once the middleware has been defined in the HTTP kernel, you may use the middleware method to assign middleware to a route:

Route::get('admin/profile', function () {
    //
})->middleware('auth');

You may also assign multiple middleware to the route:

Route::get('/', function () {
    //
})->middleware('first', 'second');

When assigning middleware, you may also pass the fully qualified class name:

use App\Http\Middleware\CheckAge;

Route::get('admin/profile', function () {
    //
})->middleware(CheckAge::class);

<a name=“middleware-groups”></a>

15.3.3 Middleware Groups

Sometimes you may want to group several middleware under a single key to make them easier to assign to routes. You may do this using the $middlewareGroups property of your HTTP kernel.

Out of the box, Laravel comes with web and api middleware groups that contains common middleware you may want to apply to your web UI and API routes:

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'auth:api',
    ],
];

Middleware groups may be assigned to routes and controller actions using the same syntax as individual middleware. Again, middleware groups simply make it more convenient to assign many middleware to a route at once:

Route::get('/', function () {
    //
})->middleware('web');

Route::group(['middleware' => ['web']], function () {
    //
});

{tip} Out of the box, the web middleware group is automatically applied to your routes/web.php file by the RouteServiceProvider.

<a name=“middleware-parameters”></a>

15.4 Middleware Parameters

Middleware can also receive additional parameters. For example, if your application needs to verify that the authenticated user has a given “role” before performing a given action, you could create a CheckRole middleware that receives a role name as an additional argument.

Additional middleware parameters will be passed to the middleware after the $next argument:

<?php

namespace App\Http\Middleware;

use Closure;

class CheckRole
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $role
     * @return mixed
     */
    public function handle($request, Closure $next, $role)
    {
        if (! $request->user()->hasRole($role)) {
            // Redirect...
        }

        return $next($request);
    }

}

Middleware parameters may be specified when defining the route by separating the middleware name and parameters with a :. Multiple parameters should be delimited by commas:

Route::put('post/{id}', function ($id) {
    //
})->middleware('role:editor');

<a name=“terminable-middleware”></a>

15.5 Terminable Middleware

Sometimes a middleware may need to do some work after the HTTP response has been sent to the browser. For example, the “session” middleware included with Laravel writes the session data to storage after the response has been sent to the browser. If you define a terminate method on your middleware, it will automatically be called after the response is sent to the browser.

<?php

namespace Illuminate\Session\Middleware;

use Closure;

class StartSession
{
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        // Store the session data...
    }
}

The terminate method should receive both the request and the response. Once you have defined a terminable middleware, you should add it to the list of route or global middleware in the app/Http/Kernel.php file.

When calling the terminate method on your middleware, Laravel will resolve a fresh instance of the middleware from the service container. If you would like to use the same middleware instance when the handle and terminate methods are called, register the middleware with the container using the container’s singleton method.

16 CSRF Protection

<a name=“csrf-introduction”></a>

16.1 Introduction

Laravel makes it easy to protect your application from cross-site request forgery (CSRF) attacks. Cross-site request forgeries are a type of malicious exploit whereby unauthorized commands are performed on behalf of an authenticated user.

Laravel automatically generates a CSRF “token” for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application.

Anytime you define a HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware can validate the request. You may use the csrf_field helper to generate the token field:

<form method="POST" action="/profile">
    {{ csrf_field() }}
    ...
</form>

The VerifyCsrfToken middleware, which is included in the web middleware group, will automatically verify that the token in the request input matches the token stored in the session.

16.1.0.1 CSRF Tokens & JavaScript

When building JavaScript driven applications, it is convenient to have your JavaScript HTTP library automatically attach the CSRF token to every outgoing request. By default, the resources/assets/js/bootstrap.js file registers the value of the csrf-token meta tag with the Axios HTTP library. If you are not using this library, you will need to manually configure this behavior for your application.

<a name=“csrf-excluding-uris”></a>

16.2 Excluding URIs From CSRF Protection

Sometimes you may wish to exclude a set of URIs from CSRF protection. For example, if you are using Stripe to process payments and are utilizing their webhook system, you will need to exclude your Stripe webhook handler route from CSRF protection since Stripe will not know what CSRF token to send to your routes.

Typically, you should place these kinds of routes outside of the web middleware group that the RouteServiceProvider applies to all routes in the routes/web.php file. However, you may also exclude the routes by adding their URIs to the $except property of the VerifyCsrfToken middleware:

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'stripe/*',
    ];
}

<a name=“csrf-x-csrf-token”></a>

16.3 X-CSRF-TOKEN

In addition to checking for the CSRF token as a POST parameter, the VerifyCsrfToken middleware will also check for the X-CSRF-TOKEN request header. You could, for example, store the token in a HTML meta tag:

<meta name="csrf-token" content="{{ csrf_token() }}">

Then, once you have created the meta tag, you can instruct a library like jQuery to automatically add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications:

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

{tip} By default, the resources/assets/js/bootstrap.js file registers the value of the csrf-token meta tag with the Axios HTTP library. If you are not using this library, you will need to manually configure this behavior for your application.

<a name=“csrf-x-xsrf-token”></a>

16.4 X-XSRF-TOKEN

Laravel stores the current CSRF token in a XSRF-TOKEN cookie that is included with each response generated by the framework. You can use the cookie value to set the X-XSRF-TOKEN request header.

This cookie is primarily sent as a convenience since some JavaScript frameworks and libraries, like Angular and Axios, automatically place its value in the X-XSRF-TOKEN header.

17 Controllers

<a name=“introduction”></a>

17.1 Introduction

Instead of defining all of your request handling logic as Closures in route files, you may wish to organize this behavior using Controller classes. Controllers can group related request handling logic into a single class. Controllers are stored in the app/Http/Controllers directory.

<a name=“basic-controllers”></a>

17.2 Basic Controllers

<a name=“defining-controllers”></a>

17.2.1 Defining Controllers

Below is an example of a basic controller class. Note that the controller extends the base controller class included with Laravel. The base class provides a few convenience methods such as the middleware method, which may be used to attach middleware to controller actions:

<?php

namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function show($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

You can define a route to this controller action like so:

Route::get('user/{id}', 'UserController@show');

Now, when a request matches the specified route URI, the show method on the UserController class will be executed. Of course, the route parameters will also be passed to the method.

{tip} Controllers are not required to extend a base class. However, you will not have access to convenience features such as the middleware, validate, and dispatch methods.

<a name=“controllers-and-namespaces”></a>

17.2.2 Controllers & Namespaces

It is very important to note that we did not need to specify the full controller namespace when defining the controller route. Since the RouteServiceProvider loads your route files within a route group that contains the namespace, we only specified the portion of the class name that comes after the App\Http\Controllers portion of the namespace.

If you choose to nest your controllers deeper into the App\Http\Controllers directory, simply use the specific class name relative to the App\Http\Controllers root namespace. So, if your full controller class is App\Http\Controllers\Photos\AdminController, you should register routes to the controller like so:

Route::get('foo', 'Photos\AdminController@method');

<a name=“single-action-controllers”></a>

17.2.3 Single Action Controllers

If you would like to define a controller that only handles a single action, you may place a single __invoke method on the controller:

<?php

namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;

class ShowProfile extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function __invoke($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

When registering routes for single action controllers, you do not need to specify a method:

Route::get('user/{id}', 'ShowProfile');

<a name=“controller-middleware”></a>

17.3 Controller Middleware

Middleware may be assigned to the controller’s routes in your route files:

Route::get('profile', 'UserController@show')->middleware('auth');

However, it is more convenient to specify middleware within your controller’s constructor. Using the middleware method from your controller’s constructor, you may easily assign middleware to the controller’s action. You may even restrict the middleware to only certain methods on the controller class:

class UserController extends Controller
{
    /**
     * Instantiate a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');

        $this->middleware('log')->only('index');

        $this->middleware('subscribed')->except('store');
    }
}

Controllers also allow you to register middleware using a Closure. This provides a convenient way to define a middleware for a single controller without defining an entire middleware class:

$this->middleware(function ($request, $next) {
    // ...

    return $next($request);
});

{tip} You may assign middleware to a subset of controller actions; however, it may indicate your controller is growing too large. Instead, consider breaking your controller into multiple, smaller controllers.

<a name=“resource-controllers”></a>

17.4 Resource Controllers

Laravel resource routing assigns the typical “CRUD” routes to a controller with a single line of code. For example, you may wish to create a controller that handles all HTTP requests for “photos” stored by your application. Using the make:controller Artisan command, we can quickly create such a controller:

php artisan make:controller PhotoController --resource

This command will generate a controller at app/Http/Controllers/PhotoController.php. The controller will contain a method for each of the available resource operations.

Next, you may register a resourceful route to the controller:

Route::resource('photos', 'PhotoController');

This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions, including notes informing you of the HTTP verbs and URIs they handle.

17.4.0.1 Actions Handled By Resource Controller

Verb URI Action Route Name
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

17.4.0.2 Specifying The Resource Model

If you are using route model binding and would like the resource controller’s methods to type-hint a model instance, you may use the --model option when generating the controller:

php artisan make:controller PhotoController --resource --model=Photo

17.4.0.3 Spoofing Form Methods

Since HTML forms can’t make PUT, PATCH, or DELETE requests, you will need to add a hidden _method field to spoof these HTTP verbs. The method_field helper can create this field for you:

{{ method_field('PUT') }}

<a name=“restful-partial-resource-routes”></a>

17.4.1 Partial Resource Routes

When declaring a resource route, you may specify a subset of actions the controller should handle instead of the full set of default actions:

Route::resource('photo', 'PhotoController', ['only' => [
    'index', 'show'
]]);

Route::resource('photo', 'PhotoController', ['except' => [
    'create', 'store', 'update', 'destroy'
]]);

<a name=“restful-naming-resource-routes”></a>

17.4.2 Naming Resource Routes

By default, all resource controller actions have a route name; however, you can override these names by passing a names array with your options:

Route::resource('photo', 'PhotoController', ['names' => [
    'create' => 'photo.build'
]]);

<a name=“restful-naming-resource-route-parameters”></a>

17.4.3 Naming Resource Route Parameters

By default, Route::resource will create the route parameters for your resource routes based on the “singularized” version of the resource name. You can easily override this on a per resource basis by passing parameters in the options array. The parameters array should be an associative array of resource names and parameter names:

Route::resource('user', 'AdminUserController', ['parameters' => [
    'user' => 'admin_user'
]]);

The example above generates the following URIs for the resource’s show route:

/user/{admin_user}

<a name=“restful-localizing-resource-uris”></a>

17.4.4 Localizing Resource URIs

By default, Route::resource will create resource URIs using English verbs. If you need to localize the create and edit action verbs, you may use the Route::resourceVerbs method. This may be done in the boot method of your AppServiceProvider:

use Illuminate\Support\Facades\Route;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Route::resourceVerbs([
        'create' => 'crear',
        'edit' => 'editar',
    ]);
}

Once the verbs have been customized, a resource route registration such as Route::resource('fotos', 'PhotoController') will produce the following URIs:

/fotos/crear

/fotos/{foto}/editar

<a name=“restful-supplementing-resource-controllers”></a>

17.4.5 Supplementing Resource Controllers

If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource; otherwise, the routes defined by the resource method may unintentionally take precedence over your supplemental routes:

Route::get('photos/popular', 'PhotoController@method');

Route::resource('photos', 'PhotoController');

{tip} Remember to keep your controllers focused. If you find yourself routinely needing methods outside of the typical set of resource actions, consider splitting your controller into two, smaller controllers.

<a name=“dependency-injection-and-controllers”></a>

17.5 Dependency Injection & Controllers

17.5.0.1 Constructor Injection

The Laravel service container is used to resolve all Laravel controllers. As a result, you are able to type-hint any dependencies your controller may need in its constructor. The declared dependencies will automatically be resolved and injected into the controller instance:

<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }
}

Of course, you may also type-hint any Laravel contract. If the container can resolve it, you can type-hint it. Depending on your application, injecting your dependencies into your controller may provide better testability.

17.5.0.2 Method Injection

In addition to constructor injection, you may also type-hint dependencies on your controller’s methods. A common use-case for method injection is injecting the Illuminate\Http\Request instance into your controller methods:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->name;

        //
    }
}

If your controller method is also expecting input from a route parameter, simply list your route arguments after your other dependencies. For example, if your route is defined like so:

Route::put('user/{id}', 'UserController@update');

You may still type-hint the Illuminate\Http\Request and access your id parameter by defining your controller method as follows:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Update the given user.
     *
     * @param  Request  $request
     * @param  string  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        //
    }
}

<a name=“route-caching”></a>

17.6 Route Caching

{note} Closure based routes cannot be cached. To use route caching, you must convert any Closure routes to controller classes.

If your application is exclusively using controller based routes, you should take advantage of Laravel’s route cache. Using the route cache will drastically decrease the amount of time it takes to register all of your application’s routes. In some cases, your route registration may even be up to 100x faster. To generate a route cache, just execute the route:cache Artisan command:

php artisan route:cache

After running this command, your cached routes file will be loaded on every request. Remember, if you add any new routes you will need to generate a fresh route cache. Because of this, you should only run the route:cache command during your project’s deployment.

You may use the route:clear command to clear the route cache:

php artisan route:clear

18 HTTP Requests

<a name=“accessing-the-request”></a>

18.1 Accessing The Request

To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Illuminate\Http\Request class on your controller method. The incoming request instance will automatically be injected by the service container:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }
}

18.1.0.1 Dependency Injection & Route Parameters

If your controller method is also expecting input from a route parameter you should list your route parameters after your other dependencies. For example, if your route is defined like so:

Route::put('user/{id}', 'UserController@update');

You may still type-hint the Illuminate\Http\Request and access your route parameter id by defining your controller method as follows:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Update the specified user.
     *
     * @param  Request  $request
     * @param  string  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        //
    }
}

18.1.0.2 Accessing The Request Via Route Closures

You may also type-hint the Illuminate\Http\Request class on a route Closure. The service container will automatically inject the incoming request into the Closure when it is executed:

use Illuminate\Http\Request;

Route::get('/', function (Request $request) {
    //
});

<a name=“request-path-and-method”></a>

18.1.1 Request Path & Method

The Illuminate\Http\Request instance provides a variety of methods for examining the HTTP request for your application and extends the Symfony\Component\HttpFoundation\Request class. We will discuss a few of the most important methods below.

18.1.1.1 Retrieving The Request Path

The path method returns the request’s path information. So, if the incoming request is targeted at http://domain.com/foo/bar, the path method will return foo/bar:

$uri = $request->path();

The is method allows you to verify that the incoming request path matches a given pattern. You may use the * character as a wildcard when utilizing this method:

if ($request->is('admin/*')) {
    //
}

18.1.1.2 Retrieving The Request URL

To retrieve the full URL for the incoming request you may use the url or fullUrl methods. The url method will return the URL without the query string, while the fullUrl method includes the query string:

// Without Query String...
$url = $request->url();

// With Query String...
$url = $request->fullUrl();

18.1.1.3 Retrieving The Request Method

The method method will return the HTTP verb for the request. You may use the isMethod method to verify that the HTTP verb matches a given string:

$method = $request->method();

if ($request->isMethod('post')) {
    //
}

<a name=“psr7-requests”></a>

18.1.2 PSR-7 Requests

The PSR-7 standard specifies interfaces for HTTP messages, including requests and responses. If you would like to obtain an instance of a PSR-7 request instead of a Laravel request, you will first need to install a few libraries. Laravel uses the Symfony HTTP Message Bridge component to convert typical Laravel requests and responses into PSR-7 compatible implementations:

composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros

Once you have installed these libraries, you may obtain a PSR-7 request by type-hinting the request interface on your route Closure or controller method:

use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
    //
});

{tip} If you return a PSR-7 response instance from a route or controller, it will automatically be converted back to a Laravel response instance and be displayed by the framework.

<a name=“input-trimming-and-normalization”></a>

18.2 Input Trimming & Normalization

By default, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your application’s global middleware stack. These middleware are listed in the stack by the App\Http\Kernel class. These middleware will automatically trim all incoming string fields on the request, as well as convert any empty string fields to null. This allows you to not have to worry about these normalization concerns in your routes and controllers.

If you would like to disable this behavior, you may remove the two middleware from your application’s middleware stack by removing them from the $middleware property of your App\Http\Kernel class.

<a name=“retrieving-input”></a>

18.3 Retrieving Input

18.3.0.1 Retrieving All Input Data

You may also retrieve all of the input data as an array using the all method:

$input = $request->all();

18.3.0.2 Retrieving An Input Value

Using a few simple methods, you may access all of the user input from your Illuminate\Http\Request instance without worrying about which HTTP verb was used for the request. Regardless of the HTTP verb, the input method may be used to retrieve user input:

$name = $request->input('name');

You may pass a default value as the second argument to the input method. This value will be returned if the requested input value is not present on the request:

$name = $request->input('name', 'Sally');

When working with forms that contain array inputs, use “dot” notation to access the arrays:

$name = $request->input('products.0.name');

$names = $request->input('products.*.name');

18.3.0.3 Retrieving Input From The Query String

While the input method retrieves values from entire request payload (including the query string), the query method will only retrieve values from the query string:

$name = $request->query('name');

If the requested query string value data is not present, the second argument to this method will be returned:

$name = $request->query('name', 'Helen');

You may call the query method without any arguments in order to retrieve all of the query string values as an associative array:

$query = $request->query();

18.3.0.4 Retrieving Input Via Dynamic Properties

You may also access user input using dynamic properties on the Illuminate\Http\Request instance. For example, if one of your application’s forms contains a name field, you may access the value of the field like so:

$name = $request->name;

When using dynamic properties, Laravel will first look for the parameter’s value in the request payload. If it is not present, Laravel will search for the field in the route parameters.

18.3.0.5 Retrieving JSON Input Values

When sending JSON requests to your application, you may access the JSON data via the input method as long as the Content-Type header of the request is properly set to application/json. You may even use “dot” syntax to dig into JSON arrays:

$name = $request->input('user.name');

18.3.0.6 Retrieving A Portion Of The Input Data

If you need to retrieve a subset of the input data, you may use the only and except methods. Both of these methods accept a single array or a dynamic list of arguments:

$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

{tip} The only method returns all of the key / value pairs that you request; however, it will not return key / values pairs that are not present on the request.

18.3.0.7 Determining If An Input Value Is Present

You should use the has method to determine if a value is present on the request. The has method returns true if the value is present on the request:

if ($request->has('name')) {
    //
}

When given an array, the has method will determine if all of the specified values are present:

if ($request->has(['name', 'email'])) {
    //
}

If you would like to determine if a value is present on the request and is not empty, you may use the filled method:

if ($request->filled('name')) {
    //
}

<a name=“old-input”></a>

18.3.1 Old Input

Laravel allows you to keep input from one request during the next request. This feature is particularly useful for re-populating forms after detecting validation errors. However, if you are using Laravel’s included validation features, it is unlikely you will need to manually use these methods, as some of Laravel’s built-in validation facilities will call them automatically.

18.3.1.1 Flashing Input To The Session

The flash method on the Illuminate\Http\Request class will flash the current input to the session so that it is available during the user’s next request to the application:

$request->flash();

You may also use the flashOnly and flashExcept methods to flash a subset of the request data to the session. These methods are useful for keeping sensitive information such as passwords out of the session:

$request->flashOnly(['username', 'email']);

$request->flashExcept('password');

18.3.1.2 Flashing Input Then Redirecting

Since you often will want to flash input to the session and then redirect to the previous page, you may easily chain input flashing onto a redirect using the withInput method:

return redirect('form')->withInput();

return redirect('form')->withInput(
    $request->except('password')
);

18.3.1.3 Retrieving Old Input

To retrieve flashed input from the previous request, use the old method on the Request instance. The old method will pull the previously flashed input data from the session:

$username = $request->old('username');

Laravel also provides a global old helper. If you are displaying old input within a Blade template, it is more convenient to use the old helper. If no old input exists for the given field, null will be returned:

<input type="text" name="username" value="{{ old('username') }}">

<a name=“cookies”></a>

18.3.2 Cookies

18.3.2.1 Retrieving Cookies From Requests

All cookies created by the Laravel framework are encrypted and signed with an authentication code, meaning they will be considered invalid if they have been changed by the client. To retrieve a cookie value from the request, use the cookie method on a Illuminate\Http\Request instance:

$value = $request->cookie('name');

18.3.2.2 Attaching Cookies To Responses

You may attach a cookie to an outgoing Illuminate\Http\Response instance using the cookie method. You should pass the name, value, and number of minutes the cookie should be considered valid to this method:

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

The cookie method also accepts a few more arguments which are used less frequently. Generally, these arguments have the same purpose and meaning as the arguments that would be given to PHP’s native setcookie method:

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

If you would like to generate a Symfony\Component\HttpFoundation\Cookie instance that can be given to a response instance at a later time, you may use the global cookie helper. This cookie will not be sent back to the client unless it is attached to a response instance:

$cookie = cookie('name', 'value', $minutes);

return response('Hello World')->cookie($cookie);

<a name=“files”></a>

18.4 Files

<a name=“retrieving-uploaded-files”></a>

18.4.1 Retrieving Uploaded Files

You may access uploaded files from a Illuminate\Http\Request instance using the file method or using dynamic properties. The file method returns an instance of the Illuminate\Http\UploadedFile class, which extends the PHP SplFileInfo class and provides a variety of methods for interacting with the file:

$file = $request->file('photo');

$file = $request->photo;

You may determine if a file is present on the request using the hasFile method:

if ($request->hasFile('photo')) {
    //
}

18.4.1.1 Validating Successful Uploads

In addition to checking if the file is present, you may verify that there were no problems uploading the file via the isValid method:

if ($request->file('photo')->isValid()) {
    //
}

18.4.1.2 File Paths & Extensions

The UploadedFile class also contains methods for accessing the file’s fully-qualified path and its extension. The extension method will attempt to guess the file’s extension based on its contents. This extension may be different from the extension that was supplied by the client:

$path = $request->photo->path();

$extension = $request->photo->extension();

18.4.1.3 Other File Methods

There are a variety of other methods available on UploadedFile instances. Check out the API documentation for the class for more information regarding these methods.

<a name=“storing-uploaded-files”></a>

18.4.2 Storing Uploaded Files

To store an uploaded file, you will typically use one of your configured filesystems. The UploadedFile class has a store method which will move an uploaded file to one of your disks, which may be a location on your local filesystem or even a cloud storage location like Amazon S3.

The store method accepts the path where the file should be stored relative to the filesystem’s configured root directory. This path should not contain a file name, since a unique ID will automatically be generated to serve as the file name.

The store method also accepts an optional second argument for the name of the disk that should be used to store the file. The method will return the path of the file relative to the disk’s root:

$path = $request->photo->store('images');

$path = $request->photo->store('images', 's3');

If you do not want a file name to be automatically generated, you may use the storeAs method, which accepts the path, file name, and disk name as its arguments:

$path = $request->photo->storeAs('images', 'filename.jpg');

$path = $request->photo->storeAs('images', 'filename.jpg', 's3');

<a name=“configuring-trusted-proxies”></a>

18.5 Configuring Trusted Proxies

When running your applications behind a load balancer that terminates TLS / SSL certificates, you may notice your application sometimes does not generate HTTPS links. Typically this is because your application is being forwarded traffic from your load balancer on port 80 and does not know it should generate secure links.

To solve this, you may use the App\Http\Middleware\TrustProxies middleware that is included in your Laravel application, which allows you to quickly customize the load balancers or proxies that should be trusted by your application. Your trusted proxies should be listed as an array on the $proxies property of this middleware. In addition to configuring the trusted proxies, you may configure the headers that are being sent by your proxy with information about the original request:

<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = [
        '192.168.1.1',
        '192.168.1.2',
    ];

    /**
     * The current proxy header mappings.
     *
     * @var array
     */
    protected $headers = [
        Request::HEADER_FORWARDED => 'FORWARDED',
        Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
        Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
        Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
        Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
    ];
}

18.5.0.1 Trusting All Proxies

If you are using Amazon AWS or another “cloud” load balancer provider, you may not know the IP addresses of your actual balancers. In this case, you may use ** to trust all proxies:

/**
 * The trusted proxies for this application.
 *
 * @var array
 */
protected $proxies = '**';

19 HTTP Responses

<a name=“creating-responses”></a>

19.1 Creating Responses

19.1.0.1 Strings & Arrays

All routes and controllers should return a response to be sent back to the user’s browser. Laravel provides several different ways to return responses. The most basic response is simply returning a string from a route or controller. The framework will automatically convert the string into a full HTTP response:

Route::get('/', function () {
    return 'Hello World';
});

In addition to returning strings from your routes and controllers, you may also return arrays. The framework will automatically convert the array into a JSON response:

Route::get('/', function () {
    return [1, 2, 3];
});

{tip} Did you know you can also return Eloquent collections from your routes or controllers? They will automatically be converted to JSON. Give it a shot!

19.1.0.2 Response Objects

Typically, you won’t just be returning simple strings or arrays from your route actions. Instead, you will be returning full Illuminate\Http\Response instances or views.

Returning a full Response instance allows you to customize the response’s HTTP status code and headers. A Response instance inherits from the Symfony\Component\HttpFoundation\Response class, which provides a variety of methods for building HTTP responses:

Route::get('home', function () {
    return response('Hello World', 200)
                  ->header('Content-Type', 'text/plain');
});

<a name=“attaching-headers-to-responses”></a>

19.1.0.3 Attaching Headers To Responses

Keep in mind that most response methods are chainable, allowing for the fluent construction of response instances. For example, you may use the header method to add a series of headers to the response before sending it back to the user:

return response($content)
            ->header('Content-Type', $type)
            ->header('X-Header-One', 'Header Value')
            ->header('X-Header-Two', 'Header Value');

Or, you may use the withHeaders method to specify an array of headers to be added to the response:

return response($content)
            ->withHeaders([
                'Content-Type' => $type,
                'X-Header-One' => 'Header Value',
                'X-Header-Two' => 'Header Value',
            ]);

<a name=“attaching-cookies-to-responses”></a>

19.1.0.4 Attaching Cookies To Responses

The cookie method on response instances allows you to easily attach cookies to the response. For example, you may use the cookie method to generate a cookie and fluently attach it to the response instance like so:

return response($content)
                ->header('Content-Type', $type)
                ->cookie('name', 'value', $minutes);

The cookie method also accepts a few more arguments which are used less frequently. Generally, these arguments have the same purpose and meaning as the arguments that would be given to PHP’s native setcookie method:

->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)

<a name=“cookies-and-encryption”></a>

19.1.0.5 Cookies & Encryption

By default, all cookies generated by Laravel are encrypted and signed so that they can’t be modified or read by the client. If you would like to disable encryption for a subset of cookies generated by your application, you may use the $except property of the App\Http\Middleware\EncryptCookies middleware, which is located in the app/Http/Middleware directory:

/**
 * The names of the cookies that should not be encrypted.
 *
 * @var array
 */
protected $except = [
    'cookie_name',
];

<a name=“redirects”></a>

19.2 Redirects

Redirect responses are instances of the Illuminate\Http\RedirectResponse class, and contain the proper headers needed to redirect the user to another URL. There are several ways to generate a RedirectResponse instance. The simplest method is to use the global redirect helper:

Route::get('dashboard', function () {
    return redirect('home/dashboard');
});

Sometimes you may wish to redirect the user to their previous location, such as when a submitted form is invalid. You may do so by using the global back helper function. Since this feature utilizes the session, make sure the route calling the back function is using the web middleware group or has all of the session middleware applied:

Route::post('user/profile', function () {
    // Validate the request...

    return back()->withInput();
});

<a name=“redirecting-named-routes”></a>

19.2.1 Redirecting To Named Routes

When you call the redirect helper with no parameters, an instance of Illuminate\Routing\Redirector is returned, allowing you to call any method on the Redirector instance. For example, to generate a RedirectResponse to a named route, you may use the route method:

return redirect()->route('login');

If your route has parameters, you may pass them as the second argument to the route method:

// For a route with the following URI: profile/{id}

return redirect()->route('profile', ['id' => 1]);

19.2.1.1 Populating Parameters Via Eloquent Models

If you are redirecting to a route with an “ID” parameter that is being populated from an Eloquent model, you may simply pass the model itself. The ID will be extracted automatically:

// For a route with the following URI: profile/{id}

return redirect()->route('profile', [$user]);

If you would like to customize the value that is placed in the route parameter, you should override the getRouteKey method on your Eloquent model:

/**
 * Get the value of the model's route key.
 *
 * @return mixed
 */
public function getRouteKey()
{
    return $this->slug;
}

<a name=“redirecting-controller-actions”></a>

19.2.2 Redirecting To Controller Actions

You may also generate redirects to controller actions. To do so, pass the controller and action name to the action method. Remember, you do not need to specify the full namespace to the controller since Laravel’s RouteServiceProvider will automatically set the base controller namespace:

return redirect()->action('HomeController@index');

If your controller route requires parameters, you may pass them as the second argument to the action method:

return redirect()->action(
    'UserController@profile', ['id' => 1]
);

<a name=“redirecting-with-flashed-session-data”></a>

19.2.3 Redirecting With Flashed Session Data

Redirecting to a new URL and flashing data to the session are usually done at the same time. Typically, this is done after successfully performing an action when you flash a success message to the session. For convenience, you may create a RedirectResponse instance and flash data to the session in a single, fluent method chain:

Route::post('user/profile', function () {
    // Update the user's profile...

    return redirect('dashboard')->with('status', 'Profile updated!');
});

After the user is redirected, you may display the flashed message from the session. For example, using Blade syntax:

@if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
@endif

<a name=“other-response-types”></a>

19.3 Other Response Types

The response helper may be used to generate other types of response instances. When the response helper is called without arguments, an implementation of the Illuminate\Contracts\Routing\ResponseFactory contract is returned. This contract provides several helpful methods for generating responses.

<a name=“view-responses”></a>

19.3.1 View Responses

If you need control over the response’s status and headers but also need to return a view as the response’s content, you should use the view method:

return response()
            ->view('hello', $data, 200)
            ->header('Content-Type', $type);

Of course, if you do not need to pass a custom HTTP status code or custom headers, you should use the global view helper function.

<a name=“json-responses”></a>

19.3.2 JSON Responses

The json method will automatically set the Content-Type header to application/json, as well as convert the given array to JSON using the json_encode PHP function:

return response()->json([
    'name' => 'Abigail',
    'state' => 'CA'
]);

If you would like to create a JSONP response, you may use the json method in combination with the withCallback method:

return response()
            ->json(['name' => 'Abigail', 'state' => 'CA'])
            ->withCallback($request->input('callback'));

<a name=“file-downloads”></a>

19.3.3 File Downloads

The download method may be used to generate a response that forces the user’s browser to download the file at the given path. The download method accepts a file name as the second argument to the method, which will determine the file name that is seen by the user downloading the file. Finally, you may pass an array of HTTP headers as the third argument to the method:

return response()->download($pathToFile);

return response()->download($pathToFile, $name, $headers);

return response()->download($pathToFile)->deleteFileAfterSend(true);

{note} Symfony HttpFoundation, which manages file downloads, requires the file being downloaded to have an ASCII file name.

<a name=“file-responses”></a>

19.3.4 File Responses

The file method may be used to display a file, such as an image or PDF, directly in the user’s browser instead of initiating a download. This method accepts the path to the file as its first argument and an array of headers as its second argument:

return response()->file($pathToFile);

return response()->file($pathToFile, $headers);

<a name=“response-macros”></a>

19.4 Response Macros

If you would like to define a custom response that you can re-use in a variety of your routes and controllers, you may use the macro method on the Response facade. For example, from a service provider’s boot method:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class ResponseMacroServiceProvider extends ServiceProvider
{
    /**
     * Register the application's response macros.
     *
     * @return void
     */
    public function boot()
    {
        Response::macro('caps', function ($value) {
            return Response::make(strtoupper($value));
        });
    }
}

The macro function accepts a name as its first argument, and a Closure as its second. The macro’s Closure will be executed when calling the macro name from a ResponseFactory implementation or the response helper:

return response()->caps('foo');

20 Views

<a name=“creating-views”></a>

20.1 Creating Views

{tip} Looking for more information on how to write Blade templates? Check out the full Blade documentation to get started.

Views contain the HTML served by your application and separate your controller / application logic from your presentation logic. Views are stored in the resources/views directory. A simple view might look something like this:

<!-- View stored in resources/views/greeting.blade.php -->

<html>
    <body>
        <h1>Hello, {{ $name }}</h1>
    </body>
</html>

Since this view is stored at resources/views/greeting.blade.php, we may return it using the global view helper like so:

Route::get('/', function () {
    return view('greeting', ['name' => 'James']);
});

As you can see, the first argument passed to the view helper corresponds to the name of the view file in the resources/views directory. The second argument is an array of data that should be made available to the view. In this case, we are passing the name variable, which is displayed in the view using Blade syntax.

Of course, views may also be nested within sub-directories of the resources/views directory. “Dot” notation may be used to reference nested views. For example, if your view is stored at resources/views/admin/profile.blade.php, you may reference it like so:

return view('admin.profile', $data);

20.1.0.1 Determining If A View Exists

If you need to determine if a view exists, you may use the View facade. The exists method will return true if the view exists:

use Illuminate\Support\Facades\View;

if (View::exists('emails.customer')) {
    //
}

<a name=“passing-data-to-views”></a>

20.2 Passing Data To Views

As you saw in the previous examples, you may pass an array of data to views:

return view('greetings', ['name' => 'Victoria']);

When passing information in this manner, the data should be an array with key / value pairs. Inside your view, you can then access each value using its corresponding key, such as <?php echo $key; ?>. As an alternative to passing a complete array of data to the view helper function, you may use the with method to add individual pieces of data to the view:

return view('greeting')->with('name', 'Victoria');

<a name=“sharing-data-with-all-views”></a>

20.2.0.1 Sharing Data With All Views

Occasionally, you may need to share a piece of data with all views that are rendered by your application. You may do so using the view facade’s share method. Typically, you should place calls to share within a service provider’s boot method. You are free to add them to the AppServiceProvider or generate a separate service provider to house them:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\View;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        View::share('key', 'value');
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

<a name=“view-composers”></a>

20.3 View Composers

View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.

For this example, let’s register the view composers within a service provider. We’ll use the View facade to access the underlying Illuminate\Contracts\View\Factory contract implementation. Remember, Laravel does not include a default directory for view composers. You are free to organize them however you wish. For example, you could create an app/Http/ViewComposers directory:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function boot()
    {
        // Using class based composers...
        View::composer(
            'profile', 'App\Http\ViewComposers\ProfileComposer'
        );

        // Using Closure based composers...
        View::composer('dashboard', function ($view) {
            //
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

{note} Remember, if you create a new service provider to contain your view composer registrations, you will need to add the service provider to the providers array in the config/app.php configuration file.

Now that we have registered the composer, the ProfileComposer@compose method will be executed each time the profile view is being rendered. So, let’s define the composer class:

<?php

namespace App\Http\ViewComposers;

use Illuminate\View\View;
use App\Repositories\UserRepository;

class ProfileComposer
{
    /**
     * The user repository implementation.
     *
     * @var UserRepository
     */
    protected $users;

    /**
     * Create a new profile composer.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        // Dependencies automatically resolved by service container...
        $this->users = $users;
    }

    /**
     * Bind data to the view.
     *
     * @param  View  $view
     * @return void
     */
    public function compose(View $view)
    {
        $view->with('count', $this->users->count());
    }
}

Just before the view is rendered, the composer’s compose method is called with the Illuminate\View\View instance. You may use the with method to bind data to the view.

{tip} All view composers are resolved via the service container, so you may type-hint any dependencies you need within a composer’s constructor.

20.3.0.1 Attaching A Composer To Multiple Views

You may attach a view composer to multiple views at once by passing an array of views as the first argument to the composer method:

View::composer(
    ['profile', 'dashboard'],
    'App\Http\ViewComposers\MyViewComposer'
);

The composer method also accepts the * character as a wildcard, allowing you to attach a composer to all views:

View::composer('*', function ($view) {
    //
});

20.3.0.2 View Creators

View creators are very similar to view composers; however, they are executed immediately after the view is instantiated instead of waiting until the view is about to render. To register a view creator, use the creator method:

View::creator('profile', 'App\Http\ViewCreators\ProfileCreator');

21 HTTP Redirects

<a name=“creating-redirects”></a>

21.1 Creating Redirects

Redirect responses are instances of the Illuminate\Http\RedirectResponse class, and contain the proper headers needed to redirect the user to another URL. There are several ways to generate a RedirectResponse instance. The simplest method is to use the global redirect helper:

Route::get('dashboard', function () {
    return redirect('home/dashboard');
});

Sometimes you may wish to redirect the user to their previous location, such as when a submitted form is invalid. You may do so by using the global back helper function. Since this feature utilizes the session, make sure the route calling the back function is using the web middleware group or has all of the session middleware applied:

Route::post('user/profile', function () {
    // Validate the request...

    return back()->withInput();
});

<a name=“redirecting-named-routes”></a>

21.2 Redirecting To Named Routes

When you call the redirect helper with no parameters, an instance of Illuminate\Routing\Redirector is returned, allowing you to call any method on the Redirector instance. For example, to generate a RedirectResponse to a named route, you may use the route method:

return redirect()->route('login');

If your route has parameters, you may pass them as the second argument to the route method:

// For a route with the following URI: profile/{id}

return redirect()->route('profile', ['id' => 1]);

21.2.0.1 Populating Parameters Via Eloquent Models

If you are redirecting to a route with an “ID” parameter that is being populated from an Eloquent model, you may simply pass the model itself. The ID will be extracted automatically:

// For a route with the following URI: profile/{id}

return redirect()->route('profile', [$user]);

If you would like to customize the value that is placed in the route parameter, you should override the getRouteKey method on your Eloquent model:

/**
 * Get the value of the model's route key.
 *
 * @return mixed
 */
public function getRouteKey()
{
    return $this->slug;
}

<a name=“redirecting-controller-actions”></a>

21.3 Redirecting To Controller Actions

You may also generate redirects to controller actions. To do so, pass the controller and action name to the action method. Remember, you do not need to specify the full namespace to the controller since Laravel’s RouteServiceProvider will automatically set the base controller namespace:

return redirect()->action('HomeController@index');

If your controller route requires parameters, you may pass them as the second argument to the action method:

return redirect()->action(
    'UserController@profile', ['id' => 1]
);

<a name=“redirecting-with-flashed-session-data”></a>

21.4 Redirecting With Flashed Session Data

Redirecting to a new URL and flashing data to the session are usually done at the same time. Typically, this is done after successfully performing an action when you flash a success message to the session. For convenience, you may create a RedirectResponse instance and flash data to the session in a single, fluent method chain:

Route::post('user/profile', function () {
    // Update the user's profile...

    return redirect('dashboard')->with('status', 'Profile updated!');
});

After the user is redirected, you may display the flashed message from the session. For example, using Blade syntax:

@if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
@endif

22 HTTP Session

<a name=“introduction”></a>

22.1 Introduction

Since HTTP driven applications are stateless, sessions provide a way to store information about the user across multiple requests. Laravel ships with a variety of session backends that are accessed through an expressive, unified API. Support for popular backends such as Memcached, Redis, and databases is included out of the box.

<a name=“configuration”></a>

22.1.1 Configuration

The session configuration file is stored at config/session.php. Be sure to review the options available to you in this file. By default, Laravel is configured to use the file session driver, which will work well for many applications. In production applications, you may consider using the memcached or redis drivers for even faster session performance.

The session driver configuration option defines where session data will be stored for each request. Laravel ships with several great drivers out of the box:

<div class=“content-list” markdown=“1”>

  • file - sessions are stored in storage/framework/sessions.
  • cookie - sessions are stored in secure, encrypted cookies.
  • database - sessions are stored in a relational database.
  • memcached / redis - sessions are stored in one of these fast, cache based stores.
  • array - sessions are stored in a PHP array and will not be persisted.
    </div>

{tip} The array driver is used during testing and prevents the data stored in the session from being persisted.

<a name=“driver-prerequisites”></a>

22.1.2 Driver Prerequisites

22.1.2.1 Database

When using the database session driver, you will need to create a table to contain the session items. Below is an example Schema declaration for the table:

Schema::create('sessions', function ($table) {
    $table->string('id')->unique();
    $table->unsignedInteger('user_id')->nullable();
    $table->string('ip_address', 45)->nullable();
    $table->text('user_agent')->nullable();
    $table->text('payload');
    $table->integer('last_activity');
});

You may use the session:table Artisan command to generate this migration:

php artisan session:table

php artisan migrate

22.1.2.2 Redis

Before using Redis sessions with Laravel, you will need to install the predis/predis package (~1.0) via Composer. You may configure your Redis connections in the database configuration file. In the session configuration file, the connection option may be used to specify which Redis connection is used by the session.

<a name=“using-the-session”></a>

22.2 Using The Session

<a name=“retrieving-data”></a>

22.2.1 Retrieving Data

There are two primary ways of working with session data in Laravel: the global session helper and via a Request instance. First, let’s look at accessing the session via a Request instance, which can be type-hinted on a controller method. Remember, controller method dependencies are automatically injected via the Laravel service container:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function show(Request $request, $id)
    {
        $value = $request->session()->get('key');

        //
    }
}

When you retrieve a value from the session, you may also pass a default value as the second argument to the get method. This default value will be returned if the specified key does not exist in the session. If you pass a Closure as the default value to the get method and the requested key does not exist, the Closure will be executed and its result returned:

$value = $request->session()->get('key', 'default');

$value = $request->session()->get('key', function () {
    return 'default';
});

22.2.1.1 The Global Session Helper

You may also use the global session PHP function to retrieve and store data in the session. When the session helper is called with a single, string argument, it will return the value of that session key. When the helper is called with an array of key / value pairs, those values will be stored in the session:

Route::get('home', function () {
    // Retrieve a piece of data from the session...
    $value = session('key');

    // Specifying a default value...
    $value = session('key', 'default');

    // Store a piece of data in the session...
    session(['key' => 'value']);
});

{tip} There is little practical difference between using the session via an HTTP request instance versus using the global session helper. Both methods are testable via the assertSessionHas method which is available in all of your test cases.

22.2.1.2 Retrieving All Session Data

If you would like to retrieve all the data in the session, you may use the all method:

$data = $request->session()->all();

22.2.1.3 Determining If An Item Exists In The Session

To determine if a value is present in the session, you may use the has method. The has method returns true if the value is present and is not null:

if ($request->session()->has('users')) {
    //
}

To determine if a value is present in the session, even if its value is null, you may use the exists method. The exists method returns true if the value is present:

if ($request->session()->exists('users')) {
    //
}

<a name=“storing-data”></a>

22.2.2 Storing Data

To store data in the session, you will typically use the put method or the session helper:

// Via a request instance...
$request->session()->put('key', 'value');

// Via the global helper...
session(['key' => 'value']);

22.2.2.1 Pushing To Array Session Values

The push method may be used to push a new value onto a session value that is an array. For example, if the user.teams key contains an array of team names, you may push a new value onto the array like so:

$request->session()->push('user.teams', 'developers');

22.2.2.2 Retrieving & Deleting An Item

The pull method will retrieve and delete an item from the session in a single statement:

$value = $request->session()->pull('key', 'default');

<a name=“flash-data”></a>

22.2.3 Flash Data

Sometimes you may wish to store items in the session only for the next request. You may do so using the flash method. Data stored in the session using this method will only be available during the subsequent HTTP request, and then will be deleted. Flash data is primarily useful for short-lived status messages:

$request->session()->flash('status', 'Task was successful!');

If you need to keep your flash data around for several requests, you may use the reflash method, which will keep all of the flash data for an additional request. If you only need to keep specific flash data, you may use the keep method:

$request->session()->reflash();

$request->session()->keep(['username', 'email']);

<a name=“deleting-data”></a>

22.2.4 Deleting Data

The forget method will remove a piece of data from the session. If you would like to remove all data from the session, you may use the flush method:

$request->session()->forget('key');

$request->session()->flush();

<a name=“regenerating-the-session-id”></a>

22.2.5 Regenerating The Session ID

Regenerating the session ID is often done in order to prevent malicious users from exploiting a session fixation attack on your application.

Laravel automatically regenerates the session ID during authentication if you are using the built-in LoginController; however, if you need to manually regenerate the session ID, you may use the regenerate method.

$request->session()->regenerate();

<a name=“adding-custom-session-drivers”></a>

22.3 Adding Custom Session Drivers

<a name=“implementing-the-driver”></a>

22.3.0.1 Implementing The Driver

Your custom session driver should implement the SessionHandlerInterface. This interface contains just a few simple methods we need to implement. A stubbed MongoDB implementation looks something like this:

<?php

namespace App\Extensions;

class MongoHandler implements SessionHandlerInterface
{
    public function open($savePath, $sessionName) {}
    public function close() {}
    public function read($sessionId) {}
    public function write($sessionId, $data) {}
    public function destroy($sessionId) {}
    public function gc($lifetime) {}
}

{tip} Laravel does not ship with a directory to contain your extensions. You are free to place them anywhere you like. In this example, we have created an Extensions directory to house the MongoHandler.

Since the purpose of these methods is not readily understandable, let’s quickly cover what each of the methods do:

<div class=“content-list” markdown=“1”>

  • The open method would typically be used in file based session store systems. Since Laravel ships with a file session driver, you will almost never need to put anything in this method. You can leave it as an empty stub. It is simply a fact of poor interface design (which we’ll discuss later) that PHP requires us to implement this method.
  • The close method, like the open method, can also usually be disregarded. For most drivers, it is not needed.
  • The read method should return the string version of the session data associated with the given $sessionId. There is no need to do any serialization or other encoding when retrieving or storing session data in your driver, as Laravel will perform the serialization for you.
  • The write method should write the given $data string associated with the $sessionId to some persistent storage system, such as MongoDB, Dynamo, etc. Again, you should not perform any serialization - Laravel will have already handled that for you.
  • The destroy method should remove the data associated with the $sessionId from persistent storage.
  • The gc method should destroy all session data that is older than the given $lifetime, which is a UNIX timestamp. For self-expiring systems like Memcached and Redis, this method may be left empty.
    </div>

<a name=“registering-the-driver”></a>

22.3.0.2 Registering The Driver

Once your driver has been implemented, you are ready to register it with the framework. To add additional drivers to Laravel’s session backend, you may use the extend method on the Session facade. You should call the extend method from the boot method of a service provider. You may do this from the existing AppServiceProvider or create an entirely new provider:

<?php

namespace App\Providers;

use App\Extensions\MongoSessionStore;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;

class SessionServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Session::extend('mongo', function ($app) {
            // Return implementation of SessionHandlerInterface...
            return new MongoSessionStore;
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Once the session driver has been registered, you may use the mongo driver in your config/session.php configuration file.

23 Validation

<a name=“introduction”></a>

23.1 Introduction

Laravel provides several different approaches to validate your application’s incoming data. By default, Laravel’s base controller class uses a ValidatesRequests trait which provides a convenient method to validate incoming HTTP request with a variety of powerful validation rules.

<a name=“validation-quickstart”></a>

23.2 Validation Quickstart

To learn about Laravel’s powerful validation features, let’s look at a complete example of validating a form and displaying the error messages back to the user.

<a name=“quick-defining-the-routes”></a>

23.2.1 Defining The Routes

First, let’s assume we have the following routes defined in our routes/web.php file:

Route::get('post/create', 'PostController@create');

Route::post('post', 'PostController@store');

Of course, the GET route will display a form for the user to create a new blog post, while the POST route will store the new blog post in the database.

<a name=“quick-creating-the-controller”></a>

23.2.2 Creating The Controller

Next, let’s take a look at a simple controller that handles these routes. We’ll leave the store method empty for now:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Show the form to create a new blog post.
     *
     * @return Response
     */
    public function create()
    {
        return view('post.create');
    }

    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Validate and store the blog post...
    }
}

<a name=“quick-writing-the-validation-logic”></a>

23.2.3 Writing The Validation Logic

Now we are ready to fill in our store method with the logic to validate the new blog post. To do this, we will use the validate method provided by the Illuminate\Http\Request object. If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user. In the case of a traditional HTTP request, a redirect response will be generated, while a JSON response will be sent for AJAX requests.

To get a better understanding of the validate method, let’s jump back into the store method:

/**
 * Store a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid, store in database...
}

As you can see, we simply pass the desired validation rules into the validate method. Again, if the validation fails, the proper response will automatically be generated. If the validation passes, our controller will continue executing normally.

23.2.3.1 Stopping On First Validation Failure

Sometimes you may wish to stop running validation rules on an attribute after the first validation failure. To do so, assign the bail rule to the attribute:

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

In this example, if the unique rule on the title attribute fails, the max rule will not be checked. Rules will be validated in the order they are assigned.

23.2.3.2 A Note On Nested Attributes

If your HTTP request contains “nested” parameters, you may specify them in your validation rules using “dot” syntax:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

<a name=“quick-displaying-the-validation-errors”></a>

23.2.4 Displaying The Validation Errors

So, what if the incoming request parameters do not pass the given validation rules? As mentioned previously, Laravel will automatically redirect the user back to their previous location. In addition, all of the validation errors will automatically be flashed to the session.

Again, notice that we did not have to explicitly bind the error messages to the view in our GET route. This is because Laravel will check for errors in the session data, and automatically bind them to the view if they are available. The $errors variable will be an instance of Illuminate\Support\MessageBag. For more information on working with this object, check out its documentation.

{tip} The $errors variable is bound to the view by the Illuminate\View\Middleware\ShareErrorsFromSession middleware, which is provided by the web middleware group. When this middleware is applied an $errors variable will always be available in your views, allowing you to conveniently assume the $errors variable is always defined and can be safely used.

So, in our example, the user will be redirected to our controller’s create method when validation fails, allowing us to display the error messages in the view:

<!-- /resources/views/post/create.blade.php -->

<h1>Create Post</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Create Post Form -->

<a name=“a-note-on-optional-fields”></a>

23.2.5 A Note On Optional Fields

By default, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your application’s global middleware stack. These middleware are listed in the stack by the App\Http\Kernel class. Because of this, you will often need to mark your “optional” request fields as nullable if you do not want the validator to consider null values as invalid. For example:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

In this example, we are specifying that the publish_at field may be either null or a valid date representation. If the nullable modifier is not added to the rule definition, the validator would consider null an invalid date.

<a name=“quick-ajax-requests-and-validation”></a>

23.2.5.1 AJAX Requests & Validation

In this example, we used a traditional form to send data to the application. However, many applications use AJAX requests. When using the validate method during an AJAX request, Laravel will not generate a redirect response. Instead, Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.

<a name=“form-request-validation”></a>

23.3 Form Request Validation

<a name=“creating-form-requests”></a>

23.3.1 Creating Form Requests

For more complex validation scenarios, you may wish to create a “form request”. Form requests are custom request classes that contain validation logic. To create a form request class, use the make:request Artisan CLI command:

php artisan make:request StoreBlogPost

The generated class will be placed in the app/Http/Requests directory. If this directory does not exist, it will be created when you run the make:request command. Let’s add a few validation rules to the rules method:

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

So, how are the validation rules evaluated? All you need to do is type-hint the request on your controller method. The incoming form request is validated before the controller method is called, meaning you do not need to clutter your controller with any validation logic:

/**
 * Store the incoming blog post.
 *
 * @param  StoreBlogPost  $request
 * @return Response
 */
public function store(StoreBlogPost $request)
{
    // The incoming request is valid...
}

If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.

23.3.1.1 Adding After Hooks To Form Requests

If you would like to add an “after” hook to a form request, you may use the withValidator method. This method receives the fully constructed validator, allowing you to call any of its methods before the validation rules are actually evaluated:

/**
 * Configure the validator instance.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}

<a name=“authorizing-form-requests”></a>

23.3.2 Authorizing Form Requests

The form request class also contains an authorize method. Within this method, you may check if the authenticated user actually has the authority to update a given resource. For example, you may determine if a user actually owns a blog comment they are attempting to update:

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}

Since all form requests extend the base Laravel request class, we may use the user method to access the currently authenticated user. Also note the call to the route method in the example above. This method grants you access to the URI parameters defined on the route being called, such as the {comment} parameter in the example below:

Route::post('comment/{comment}');

If the authorize method returns false, a HTTP response with a 403 status code will automatically be returned and your controller method will not execute.

If you plan to have authorization logic in another part of your application, simply return true from the authorize method:

/**
 * Determine if the user is authorized to make this request.
 *
 * @return bool
 */
public function authorize()
{
    return true;
}

<a name=“customizing-the-error-messages”></a>

23.3.3 Customizing The Error Messages

You may customize the error messages used by the form request by overriding the messages method. This method should return an array of attribute / rule pairs and their corresponding error messages:

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        'title.required' => 'A title is required',
        'body.required'  => 'A message is required',
    ];
}

<a name=“manually-creating-validators”></a>

23.4 Manually Creating Validators

If you do not want to use the validate method on the request, you may create a validator instance manually using the Validator facade. The make method on the facade generates a new validator instance:

<?php

namespace App\Http\Controllers;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // Store the blog post...
    }
}

The first argument passed to the make method is the data under validation. The second argument is the validation rules that should be applied to the data.

After checking if the request validation failed, you may use the withErrors method to flash the error messages to the session. When using this method, the $errors variable will automatically be shared with your views after redirection, allowing you to easily display them back to the user. The withErrors method accepts a validator, a MessageBag, or a PHP array.

<a name=“automatic-redirection”></a>

23.4.1 Automatic Redirection

If you would like to create a validator instance manually but still take advantage of the automatic redirection offered by the requests’s validate method, you may call the validate method on an existing validator instance. If validation fails, the user will automatically be redirected or, in the case of an AJAX request, a JSON response will be returned:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validate();

<a name=“named-error-bags”></a>

23.4.2 Named Error Bags

If you have multiple forms on a single page, you may wish to name the MessageBag of errors, allowing you to retrieve the error messages for a specific form. Simply pass a name as the second argument to withErrors:

return redirect('register')
            ->withErrors($validator, 'login');

You may then access the named MessageBag instance from the $errors variable:

{{ $errors->login->first('email') }}

<a name=“after-validation-hook”></a>

23.4.3 After Validation Hook

The validator also allows you to attach callbacks to be run after validation is completed. This allows you to easily perform further validation and even add more error messages to the message collection. To get started, use the after method on a validator instance:

$validator = Validator::make(...);

$validator->after(function ($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails()) {
    //
}

<a name=“working-with-error-messages”></a>

23.5 Working With Error Messages

After calling the errors method on a Validator instance, you will receive an Illuminate\Support\MessageBag instance, which has a variety of convenient methods for working with error messages. The $errors variable that is automatically made available to all views is also an instance of the MessageBag class.

23.5.0.1 Retrieving The First Error Message For A Field

To retrieve the first error message for a given field, use the first method:

$errors = $validator->errors();

echo $errors->first('email');

23.5.0.2 Retrieving All Error Messages For A Field

If you need to retrieve an array of all the messages for a given field, use the get method:

foreach ($errors->get('email') as $message) {
    //
}

If you are validating an array form field, you may retrieve all of the messages for each of the array elements using the * character:

foreach ($errors->get('attachments.*') as $message) {
    //
}

23.5.0.3 Retrieving All Error Messages For All Fields

To retrieve an array of all messages for all fields, use the all method:

foreach ($errors->all() as $message) {
    //
}

23.5.0.4 Determining If Messages Exist For A Field

The has method may be used to determine if any error messages exist for a given field:

if ($errors->has('email')) {
    //
}

<a name=“custom-error-messages”></a>

23.5.1 Custom Error Messages

If needed, you may use custom error messages for validation instead of the defaults. There are several ways to specify custom messages. First, you may pass the custom messages as the third argument to the Validator::make method:

$messages = [
    'required' => 'The :attribute field is required.',
];

$validator = Validator::make($input, $rules, $messages);

In this example, the :attribute place-holder will be replaced by the actual name of the field under validation. You may also utilize other place-holders in validation messages. For example:

$messages = [
    'same'    => 'The :attribute and :other must match.',
    'size'    => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute must be between :min - :max.',
    'in'      => 'The :attribute must be one of the following types: :values',
];

23.5.1.1 Specifying A Custom Message For A Given Attribute

Sometimes you may wish to specify a custom error messages only for a specific field. You may do so using “dot” notation. Specify the attribute’s name first, followed by the rule:

$messages = [
    'email.required' => 'We need to know your e-mail address!',
];

<a name=“localization”></a>

23.5.1.2 Specifying Custom Messages In Language Files

In most cases, you will probably specify your custom messages in a language file instead of passing them directly to the Validator. To do so, add your messages to custom array in the resources/lang/xx/validation.php language file.

'custom' => [
    'email' => [
        'required' => 'We need to know your e-mail address!',
    ],
],

23.5.1.3 Specifying Custom Attributes In Language Files

If you would like the :attribute portion of your validation message to be replaced with a custom attribute name, you may specify the custom name in the attributes array of your resources/lang/xx/validation.php language file:

'attributes' => [
    'email' => 'email address',
],

<a name=“available-validation-rules”></a>

23.6 Available Validation Rules

Below is a list of all available validation rules and their function:

<style>
.collection-method-list > p {
column-count: 3; -moz-column-count: 3; -webkit-column-count: 3;
column-gap: 2em; -moz-column-gap: 2em; -webkit-column-gap: 2em;
}

.collection-method-list a {
    display: block;
}

</style>

<div class=“collection-method-list” markdown=“1”>

Accepted
Active URL
After (Date)
After Or Equal (Date)
Alpha
Alpha Dash
Alpha Numeric
Array
Before (Date)
Before Or Equal (Date)
Between
Boolean
Confirmed
Date
Date Format
Different
Digits
Digits Between
Dimensions (Image Files)
Distinct
E-Mail
Exists (Database)
File
Filled
Image (File)
In
In Array
Integer
IP Address
JSON
Max
MIME Types
MIME Type By File Extension
Min
Nullable
Not In
Numeric
Present
Regular Expression
Required
Required If
Required Unless
Required With
Required With All
Required Without
Required Without All
Same
Size
String
Timezone
Unique (Database)
URL

</div>

<a name=“rule-accepted”></a>

23.6.0.1 accepted

The field under validation must be yes, on, 1, or true. This is useful for validating “Terms of Service” acceptance.

<a name=“rule-active-url”></a>

23.6.0.2 active_url

The field under validation must have a valid A or AAAA record according to the dns_get_record PHP function.

<a name=“rule-after”></a>

23.6.0.3 after:date

The field under validation must be a value after a given date. The dates will be passed into the strtotime PHP function:

'start_date' => 'required|date|after:tomorrow'

Instead of passing a date string to be evaluated by strtotime, you may specify another field to compare against the date:

'finish_date' => 'required|date|after:start_date'

<a name=“rule-after-or-equal”></a>

23.6.0.4 after_or_equal:date

The field under validation must be a value after or equal to the given date. For more information, see the after rule.

<a name=“rule-alpha”></a>

23.6.0.5 alpha

The field under validation must be entirely alphabetic characters.

<a name=“rule-alpha-dash”></a>

23.6.0.6 alpha_dash

The field under validation may have alpha-numeric characters, as well as dashes and underscores.

<a name=“rule-alpha-num”></a>

23.6.0.7 alpha_num

The field under validation must be entirely alpha-numeric characters.

<a name=“rule-array”></a>

23.6.0.8 array

The field under validation must be a PHP array.

<a name=“rule-before”></a>

23.6.0.9 before:date

The field under validation must be a value preceding the given date. The dates will be passed into the PHP strtotime function.

<a name=“rule-before-or-equal”></a>

23.6.0.10 before_or_equal:date

The field under validation must be a value preceding or equal to the given date. The dates will be passed into the PHP strtotime function.

<a name=“rule-between”></a>

23.6.0.11 between:min,max

The field under validation must have a size between the given min and max. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.

<a name=“rule-boolean”></a>

23.6.0.12 boolean

The field under validation must be able to be cast as a boolean. Accepted input are true, false, 1, 0, "1", and "0".

<a name=“rule-confirmed”></a>

23.6.0.13 confirmed

The field under validation must have a matching field of foo_confirmation. For example, if the field under validation is password, a matching password_confirmation field must be present in the input.

<a name=“rule-date”></a>

23.6.0.14 date

The field under validation must be a valid date according to the strtotime PHP function.

<a name=“rule-date-format”></a>

23.6.0.15 date_format:format

The field under validation must match the given format. You should use either date or date_format when validating a field, not both.

<a name=“rule-different”></a>

23.6.0.16 different:field

The field under validation must have a different value than field.

<a name=“rule-digits”></a>

23.6.0.17 digits:value

The field under validation must be numeric and must have an exact length of value.

<a name=“rule-digits-between”></a>

23.6.0.18 digits_between:min,max

The field under validation must have a length between the given min and max.

<a name=“rule-dimensions”></a>

23.6.0.19 dimensions

The file under validation must be an image meeting the dimension constraints as specified by the rule’s parameters:

'avatar' => 'dimensions:min_width=100,min_height=200'

Available constraints are: min_width, max_width, min_height, max_height, width, height, ratio.

A ratio constraint should be represented as width divided by height. This can be specified either by a statement like 3/2 or a float like 1.5:

'avatar' => 'dimensions:ratio=3/2'

Since this rule requires several arguments, you may use the Rule::dimensions method to fluently construct the rule:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);

<a name=“rule-distinct”></a>

23.6.0.20 distinct

When working with arrays, the field under validation must not have any duplicate values.

'foo.*.id' => 'distinct'

<a name=“rule-email”></a>

23.6.0.21 email

The field under validation must be formatted as an e-mail address.

<a name=“rule-exists”></a>

23.6.0.22 exists:table,column

The field under validation must exist on a given database table.

23.6.0.23 Basic Usage Of Exists Rule

'state' => 'exists:states'

23.6.0.24 Specifying A Custom Column Name

'state' => 'exists:states,abbreviation'

Occasionally, you may need to specify a specific database connection to be used for the exists query. You can accomplish this by prepending the connection name to the table name using “dot” syntax:

'email' => 'exists:connection.staff,email'

If you would like to customize the query executed by the validation rule, you may use the Rule class to fluently define the rule. In this example, we’ll also specify the validation rules as an array instead of using the | character to delimit them:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);

<a name=“rule-file”></a>

23.6.0.25 file

The field under validation must be a successfully uploaded file.

<a name=“rule-filled”></a>

23.6.0.26 filled

The field under validation must not be empty when it is present.

<a name=“rule-image”></a>

23.6.0.27 image

The file under validation must be an image (jpeg, png, bmp, gif, or svg)

<a name=“rule-in”></a>

23.6.0.28 in:foo,bar,…

The field under validation must be included in the given list of values. Since this rule often requires you to implode an array, the Rule::in method may be used to fluently construct the rule:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
]);

<a name=“rule-in-array”></a>

23.6.0.29 in_array:anotherfield

The field under validation must exist in anotherfield’s values.

<a name=“rule-integer”></a>

23.6.0.30 integer

The field under validation must be an integer.

<a name=“rule-ip”></a>

23.6.0.31 ip

The field under validation must be an IP address.

23.6.0.32 ipv4

The field under validation must be an IPv4 address.

23.6.0.33 ipv6

The field under validation must be an IPv6 address.

<a name=“rule-json”></a>

23.6.0.34 json

The field under validation must be a valid JSON string.

<a name=“rule-max”></a>

23.6.0.35 max:value

The field under validation must be less than or equal to a maximum value. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.

<a name=“rule-mimetypes”></a>

23.6.0.36 mimetypes:text/plain,…

The file under validation must match one of the given MIME types:

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

To determine the MIME type of the uploaded file, the file’s contents will be read and the framework will attempt to guess the MIME type, which may be different from the client provided MIME type.

<a name=“rule-mimes”></a>

23.6.0.37 mimes:foo,bar,…

The file under validation must have a MIME type corresponding to one of the listed extensions.

23.6.0.38 Basic Usage Of MIME Rule

'photo' => 'mimes:jpeg,bmp,png'

Even though you only need to specify the extensions, this rule actually validates against the MIME type of the file by reading the file’s contents and guessing its MIME type.

A full listing of MIME types and their corresponding extensions may be found at the following location: https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

<a name=“rule-min”></a>

23.6.0.39 min:value

The field under validation must have a minimum value. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.

<a name=“rule-nullable”></a>

23.6.0.40 nullable

The field under validation may be null. This is particularly useful when validating primitive such as strings and integers that can contain null values.

<a name=“rule-not-in”></a>

23.6.0.41 not_in:foo,bar,…

The field under validation must not be included in the given list of values. The Rule::notIn method may be used to fluently construct the rule:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
]);

<a name=“rule-numeric”></a>

23.6.0.42 numeric

The field under validation must be numeric.

<a name=“rule-present”></a>

23.6.0.43 present

The field under validation must be present in the input data but can be empty.

<a name=“rule-regex”></a>

23.6.0.44 regex:pattern

The field under validation must match the given regular expression.

Note: When using the regex pattern, it may be necessary to specify rules in an array instead of using pipe delimiters, especially if the regular expression contains a pipe character.

<a name=“rule-required”></a>

23.6.0.45 required

The field under validation must be present in the input data and not empty. A field is considered “empty” if one of the following conditions are true:

<div class=“content-list” markdown=“1”>

  • The value is null.
  • The value is an empty string.
  • The value is an empty array or empty Countable object.
  • The value is an uploaded file with no path.

</div>

<a name=“rule-required-if”></a>

23.6.0.46 required_if:anotherfield,value,…

The field under validation must be present and not empty if the anotherfield field is equal to any value.

<a name=“rule-required-unless”></a>

23.6.0.47 required_unless:anotherfield,value,…

The field under validation must be present and not empty unless the anotherfield field is equal to any value.

<a name=“rule-required-with”></a>

23.6.0.48 required_with:foo,bar,…

The field under validation must be present and not empty only if any of the other specified fields are present.

<a name=“rule-required-with-all”></a>

23.6.0.49 required_with_all:foo,bar,…

The field under validation must be present and not empty only if all of the other specified fields are present.

<a name=“rule-required-without”></a>

23.6.0.50 required_without:foo,bar,…

The field under validation must be present and not empty only when any of the other specified fields are not present.

<a name=“rule-required-without-all”></a>

23.6.0.51 required_without_all:foo,bar,…

The field under validation must be present and not empty only when all of the other specified fields are not present.

<a name=“rule-same”></a>

23.6.0.52 same:field

The given field must match the field under validation.

<a name=“rule-size”></a>

23.6.0.53 size:value

The field under validation must have a size matching the given value. For string data, value corresponds to the number of characters. For numeric data, value corresponds to a given integer value. For an array, size corresponds to the count of the array. For files, size corresponds to the file size in kilobytes.

<a name=“rule-string”></a>

23.6.0.54 string

The field under validation must be a string. If you would like to allow the field to also be null, you should assign the nullable rule to the field.

<a name=“rule-timezone”></a>

23.6.0.55 timezone

The field under validation must be a valid timezone identifier according to the timezone_identifiers_list PHP function.

<a name=“rule-unique”></a>

23.6.0.56 unique:table,column,except,idColumn

The field under validation must be unique in a given database table. If the column option is not specified, the field name will be used.

Specifying A Custom Column Name:

'email' => 'unique:users,email_address'

Custom Database Connection

Occasionally, you may need to set a custom connection for database queries made by the Validator. As seen above, setting unique:users as a validation rule will use the default database connection to query the database. To override this, specify the connection and the table name using “dot” syntax:

'email' => 'unique:connection.users,email_address'

Forcing A Unique Rule To Ignore A Given ID:

Sometimes, you may wish to ignore a given ID during the unique check. For example, consider an “update profile” screen that includes the user’s name, e-mail address, and location. Of course, you will want to verify that the e-mail address is unique. However, if the user only changes the name field and not the e-mail field, you do not want a validation error to be thrown because the user is already the owner of the e-mail address.

To instruct the validator to ignore the user’s ID, we’ll use the Rule class to fluently define the rule. In this example, we’ll also specify the validation rules as an array instead of using the | character to delimit the rules:

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

If your table uses a primary key column name other than id, you may specify the name of the column when calling the ignore method:

'email' => Rule::unique('users')->ignore($user->id, 'user_id')

Adding Additional Where Clauses:

You may also specify additional query constraints by customizing the query using the where method. For example, let’s add a constraint that verifies the account_id is 1:

'email' => Rule::unique('users')->where(function ($query) {
    $query->where('account_id', 1);
})

<a name=“rule-url”></a>

23.6.0.57 url

The field under validation must be a valid URL.

<a name=“conditionally-adding-rules”></a>

23.7 Conditionally Adding Rules

23.7.0.1 Validating When Present

In some situations, you may wish to run validation checks against a field only if that field is present in the input array. To quickly accomplish this, add the sometimes rule to your rule list:

$v = Validator::make($data, [
    'email' => 'sometimes|required|email',
]);

In the example above, the email field will only be validated if it is present in the $data array.

{tip} If you are attempting to validate a field that should always be present but may be empty, check out this note on optional fields

23.7.0.2 Complex Conditional Validation

Sometimes you may wish to add validation rules based on more complex conditional logic. For example, you may wish to require a given field only if another field has a greater value than 100. Or, you may need two fields to have a given value only when another field is present. Adding these validation rules doesn’t have to be a pain. First, create a Validator instance with your static rules that never change:

$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

Let’s assume our web application is for game collectors. If a game collector registers with our application and they own more than 100 games, we want them to explain why they own so many games. For example, perhaps they run a game resale shop, or maybe they just enjoy collecting. To conditionally add this requirement, we can use the sometimes method on the Validator instance.

$v->sometimes('reason', 'required|max:500', function ($input) {
    return $input->games >= 100;
});

The first argument passed to the sometimes method is the name of the field we are conditionally validating. The second argument is the rules we want to add. If the Closure passed as the third argument returns true, the rules will be added. This method makes it a breeze to build complex conditional validations. You may even add conditional validations for several fields at once:

$v->sometimes(['reason', 'cost'], 'required', function ($input) {
    return $input->games >= 100;
});

{tip} The $input parameter passed to your Closure will be an instance of Illuminate\Support\Fluent and may be used to access your input and files.

<a name=“validating-arrays”></a>

23.8 Validating Arrays

Validating array based form input fields doesn’t have to be a pain. You may use “dot notation” to validate attributes within an array. For example, if the incoming HTTP request contains a photos[profile] field, you may validate it like so:

$validator = Validator::make($request->all(), [
    'photos.profile' => 'required|image',
]);

You may also validate each element of an array. For example, to validate that each e-mail in a given array input field is unique, you may do the following:

$validator = Validator::make($request->all(), [
    'person.*.email' => 'email|unique:users',
    'person.*.first_name' => 'required_with:person.*.last_name',
]);

Likewise, you may use the * character when specifying your validation messages in your language files, making it a breeze to use a single validation message for array based fields:

'custom' => [
    'person.*.email' => [
        'unique' => 'Each person must have a unique e-mail address',
    ]
],

<a name=“custom-validation-rules”></a>

23.9 Custom Validation Rules

<a name=“using-rule-objects”></a>

23.9.1 Using Rule Objects

Laravel provides a variety of helpful validation rules; however, you may wish to specify some of your own. One method of registering custom validation rules is using rule objects. To generate a new rule object, you may use the make:rule Artisan command. Let’s use this command to generate a rule that verifies a string is uppercase. Laravel will place the new rule in the app/Rules directory:

php artisan make:rule Uppercase

Once the rule has been created, we are ready to define its behavior. A rule object contains two methods: passes and message. The passes method receives the attribute value and name, and should return true or false depending on whether the attribute value is valid or not. The message method should return the validation error message that should be used when validation fails:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Uppercase implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return strtoupper($value) === $value;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

Of course, you may call the trans helper from your message method if you would like to return an error message from your translation files:

/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()
{
    return trans('validation.uppercase');
}

Once the rule has been defined, you may attach it to a validator by passing an instance of the rule object with your other validation rules:

use App\Rules\Uppercase;

$request->validate([
    'name' => ['required', new Uppercase],
]);

<a name=“using-extensions”></a>

23.9.2 Using Extensions

Another method of registering custom validation rules is using the extend method on the Validator facade. Let’s use this method within a service provider to register a custom validation rule:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
            return $value == 'foo';
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

The custom validator Closure receives four arguments: the name of the $attribute being validated, the $value of the attribute, an array of $parameters passed to the rule, and the Validator instance.

You may also pass a class and method to the extend method instead of a Closure:

Validator::extend('foo', 'FooValidator@validate');

23.9.2.1 Defining The Error Message

You will also need to define an error message for your custom rule. You can do so either using an inline custom message array or by adding an entry in the validation language file. This message should be placed in the first level of the array, not within the custom array, which is only for attribute-specific error messages:

"foo" => "Your input was invalid!",

"accepted" => "The :attribute must be accepted.",

// The rest of the validation error messages...

When creating a custom validation rule, you may sometimes need to define custom place-holder replacements for error messages. You may do so by creating a custom Validator as described above then making a call to the replacer method on the Validator facade. You may do this within the boot method of a service provider:

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Validator::extend(...);

    Validator::replacer('foo', function ($message, $attribute, $rule, $parameters) {
        return str_replace(...);
    });
}

23.9.2.2 Implicit Extensions

By default, when an attribute being validated is not present or contains an empty value as defined by the required rule, normal validation rules, including custom extensions, are not run. For example, the unique rule will not be run against a null value:

$rules = ['name' => 'unique'];

$input = ['name' => null];

Validator::make($input, $rules)->passes(); // true

For a rule to run even when an attribute is empty, the rule must imply that the attribute is required. To create such an “implicit” extension, use the Validator::extendImplicit() method:

Validator::extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});

{note} An “implicit” extension only implies that the attribute is required. Whether it actually invalidates a missing or empty attribute is up to you.

24 Errors & Logging

<a name=“introduction”></a>

24.1 Introduction

When you start a new Laravel project, error and exception handling is already configured for you. The App\Exceptions\Handler class is where all exceptions triggered by your application are logged and then rendered back to the user. We’ll dive deeper into this class throughout this documentation.

For logging, Laravel utilizes the Monolog library, which provides support for a variety of powerful log handlers. Laravel configures several of these handlers for you, allowing you to choose between a single log file, rotating log files, or writing error information to the system log.

<a name=“configuration”></a>

24.2 Configuration

<a name=“error-detail”></a>

24.2.1 Error Detail

The debug option in your config/app.php configuration file determines how much information about an error is actually displayed to the user. By default, this option is set to respect the value of the APP_DEBUG environment variable, which is stored in your .env file.

For local development, you should set the APP_DEBUG environment variable to true. In your production environment, this value should always be false. If the value is set to true in production, you risk exposing sensitive configuration values to your application’s end users.

<a name=“log-storage”></a>

24.2.2 Log Storage

Out of the box, Laravel supports writing log information to single files, daily files, the syslog, and the errorlog. To configure which storage mechanism Laravel uses, you should modify the log option in your config/app.php configuration file. For example, if you wish to use daily log files instead of a single file, you should set the log value in your app configuration file to daily:

'log' => 'daily'

24.2.2.1 Maximum Daily Log Files

When using the daily log mode, Laravel will only retain five days of log files by default. If you want to adjust the number of retained files, you may add a log_max_files configuration value to your app configuration file:

'log_max_files' => 30

<a name=“log-severity-levels”></a>

24.2.3 Log Severity Levels

When using Monolog, log messages may have different levels of severity. By default, Laravel writes all log levels to storage. However, in your production environment, you may wish to configure the minimum severity that should be logged by adding the log_level option to your app.php configuration file.

Once this option has been configured, Laravel will log all levels greater than or equal to the specified severity. For example, a default log_level of error will log error, critical, alert, and emergency messages:

'log_level' => env('APP_LOG_LEVEL', 'error'),

{tip} Monolog recognizes the following severity levels - from least severe to most severe: debug, info, notice, warning, error, critical, alert, emergency.

<a name=“custom-monolog-configuration”></a>

24.2.4 Custom Monolog Configuration

If you would like to have complete control over how Monolog is configured for your application, you may use the application’s configureMonologUsing method. You should place a call to this method in your bootstrap/app.php file right before the $app variable is returned by the file:

$app->configureMonologUsing(function ($monolog) {
    $monolog->pushHandler(...);
});

return $app;

24.2.4.1 Customizing The Channel Name

By default, Monolog is instantiated with name that matches the current environment, such as production or local. To change this value, add the log_channel option to your app.php configuration file:

'log_channel' => env('APP_LOG_CHANNEL', 'my-app-name'),

<a name=“the-exception-handler”></a>

24.3 The Exception Handler

<a name=“report-method”></a>

24.3.1 The Report Method

All exceptions are handled by the App\Exceptions\Handler class. This class contains two methods: report and render. We’ll examine each of these methods in detail. The report method is used to log exceptions or send them to an external service like Bugsnag or Sentry. By default, the report method simply passes the exception to the base class where the exception is logged. However, you are free to log exceptions however you wish.

For example, if you need to report different types of exceptions in different ways, you may use the PHP instanceof comparison operator:

/**
 * Report or log an exception.
 *
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
 *
 * @param  \Exception  $exception
 * @return void
 */
public function report(Exception $exception)
{
    if ($exception instanceof CustomException) {
        //
    }

    return parent::report($exception);
}

24.3.1.1 The report Helper

Sometimes you may need to report an exception but continue handling the current request. The report helper function allows you to quickly report an exception using your exception handler’s report method without rendering an error page:

public function isValid($value)
{
    try {
        // Validate the value...
    } catch (Exception $e) {
        report($e);

        return false;
    }
}

24.3.1.2 Ignoring Exceptions By Type

The $dontReport property of the exception handler contains an array of exception types that will not be logged. For example, exceptions resulting from 404 errors, as well as several other types of errors, are not written to your log files. You may add other exception types to this array as needed:

/**
 * A list of the exception types that should not be reported.
 *
 * @var array
 */
protected $dontReport = [
    \Illuminate\Auth\AuthenticationException::class,
    \Illuminate\Auth\Access\AuthorizationException::class,
    \Symfony\Component\HttpKernel\Exception\HttpException::class,
    \Illuminate\Database\Eloquent\ModelNotFoundException::class,
    \Illuminate\Validation\ValidationException::class,
];

<a name=“render-method”></a>

24.3.2 The Render Method

The render method is responsible for converting a given exception into an HTTP response that should be sent back to the browser. By default, the exception is passed to the base class which generates a response for you. However, you are free to check the exception type or return your own custom response:

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $exception
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $exception)
{
    if ($exception instanceof CustomException) {
        return response()->view('errors.custom', [], 500);
    }

    return parent::render($request, $exception);
}

<a name=“renderable-exceptions”></a>

24.3.3 Reportable & Renderable Exceptions

Instead of type-checking exceptions in the exception handler’s report and render methods, you may define report and render methods directly on your custom exception. When these methods exist, they will be called automatically by the framework:

<?php

namespace App\Exceptions;

use Exception;

class RenderException extends Exception
{
    /**
     * Report the exception.
     *
     * @return void
     */
    public function report()
    {
        //
    }

    /**
     * Report the exception.
     *
     * @param  \Illuminate\Http\Request
     * @return void
     */
    public function render($request)
    {
        return response(...);
    }
}

<a name=“http-exceptions”></a>

24.4 HTTP Exceptions

Some exceptions describe HTTP error codes from the server. For example, this may be a “page not found” error (404), an “unauthorized error” (401) or even a developer generated 500 error. In order to generate such a response from anywhere in your application, you may use the abort helper:

abort(404);

The abort helper will immediately raise an exception which will be rendered by the exception handler. Optionally, you may provide the response text:

abort(403, 'Unauthorized action.');

<a name=“custom-http-error-pages”></a>

24.4.1 Custom HTTP Error Pages

Laravel makes it easy to display custom error pages for various HTTP status codes. For example, if you wish to customize the error page for 404 HTTP status codes, create a resources/views/errors/404.blade.php. This file will be served on all 404 errors generated by your application. The views within this directory should be named to match the HTTP status code they correspond to. The HttpException instance raised by the abort function will be passed to the view as an $exception variable:

<h2>{{ $exception->getMessage() }}</h2>

<a name=“logging”></a>

24.5 Logging

Laravel provides a simple abstraction layer on top of the powerful Monolog library. By default, Laravel is configured to create a log file for your application in the storage/logs directory. You may write information to the logs using the Log facade:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        Log::info('Showing user profile for user: '.$id);

        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

The logger provides the eight logging levels defined in RFC 5424: emergency, alert, critical, error, warning, notice, info and debug.

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

24.5.0.1 Contextual Information

An array of contextual data may also be passed to the log methods. This contextual data will be formatted and displayed with the log message:

Log::info('User failed to login.', ['id' => $user->id]);

24.5.0.2 Accessing The Underlying Monolog Instance

Monolog has a variety of additional handlers you may use for logging. If needed, you may access the underlying Monolog instance being used by Laravel:

$monolog = Log::getMonolog();

25 Blade Templates

<a name=“introduction”></a>

25.1 Introduction

Blade is the simple, yet powerful templating engine provided with Laravel. Unlike other popular PHP templating engines, Blade does not restrict you from using plain PHP code in your views. In fact, all Blade views are compiled into plain PHP code and cached until they are modified, meaning Blade adds essentially zero overhead to your application. Blade view files use the .blade.php file extension and are typically stored in the resources/views directory.

<a name=“template-inheritance”></a>

25.2 Template Inheritance

<a name=“defining-a-layout”></a>

25.2.1 Defining A Layout

Two of the primary benefits of using Blade are template inheritance and sections. To get started, let’s take a look at a simple example. First, we will examine a “master” page layout. Since most web applications maintain the same general layout across various pages, it’s convenient to define this layout as a single Blade view:

<!-- Stored in resources/views/layouts/app.blade.php -->

<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

As you can see, this file contains typical HTML mark-up. However, take note of the @section and @yield directives. The @section directive, as the name implies, defines a section of content, while the @yield directive is used to display the contents of a given section.

Now that we have defined a layout for our application, let’s define a child page that inherits the layout.

<a name=“extending-a-layout”></a>

25.2.2 Extending A Layout

When defining a child view, use the Blade @extends directive to specify which layout the child view should “inherit”. Views which extend a Blade layout may inject content into the layout’s sections using @section directives. Remember, as seen in the example above, the contents of these sections will be displayed in the layout using @yield:

<!-- Stored in resources/views/child.blade.php -->

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @@parent

    <p>This is appended to the master sidebar.</p>
@endsection

@section('content')
    <p>This is my body content.</p>
@endsection

In this example, the sidebar section is utilizing the @@parent directive to append (rather than overwriting) content to the layout’s sidebar. The @@parent directive will be replaced by the content of the layout when the view is rendered.

{tip} Contrary to the previous example, this sidebar section ends with @endsection instead of @show. The @endsection directive will only define a section while @show will define and immediately yield the section.

Blade views may be returned from routes using the global view helper:

Route::get('blade', function () {
    return view('child');
});

<a name=“components-and-slots”></a>

25.3 Components & Slots

Components and slots provide similar benefits to sections and layouts; however, some may find the mental model of components and slots easier to understand. First, let’s imagine a reusable “alert” component we would like to reuse throughout our application:

<!-- /resources/views/alert.blade.php -->

<div class="alert alert-danger">
    {{ $slot }}
</div>

The {{ $slot }} variable will contain the content we wish to inject into the component. Now, to construct this component, we can use the @component Blade directive:

@component('alert')
    <strong>Whoops!</strong> Something went wrong!
@endcomponent

Sometimes it is helpful to define multiple slots for a component. Let’s modify our alert component to allow for the injection of a “title”. Named slots may be displayed by simply “echoing” the variable that matches their name:

<!-- /resources/views/alert.blade.php -->

<div class="alert alert-danger">
    <div class="alert-title">{{ $title }}</div>

    {{ $slot }}
</div>

Now, we can inject content into the named slot using the @slot directive. Any content not within a @slot directive will be passed to the component in the $slot variable:

@component('alert')
    @slot('title')
        Forbidden
    @endslot

    You are not allowed to access this resource!
@endcomponent

25.3.0.1 Passing Additional Data To Components

Sometimes you may need to pass additional data to a component. For this reason, you can pass an array of data as the second argument to the @component directive. All of the data will be made available to the component template as variables:

@component('alert', ['foo' => 'bar'])
    ...
@endcomponent

<a name=“displaying-data”></a>

25.4 Displaying Data

You may display data passed to your Blade views by wrapping the variable in curly braces. For example, given the following route:

Route::get('greeting', function () {
    return view('welcome', ['name' => 'Samantha']);
});

You may display the contents of the name variable like so:

Hello, {{ $name }}.

Of course, you are not limited to displaying the contents of the variables passed to the view. You may also echo the results of any PHP function. In fact, you can put any PHP code you wish inside of a Blade echo statement:

The current UNIX timestamp is {{ time() }}.

{note} Blade {{ }} statements are automatically sent through PHP’s htmlspecialchars function to prevent XSS attacks.

25.4.0.1 Displaying Unescaped Data

By default, Blade {{ }} statements are automatically sent through PHP’s htmlspecialchars function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:

Hello, {!! $name !!}.

{note} Be very careful when echoing content that is supplied by users of your application. Always use the escaped, double curly brace syntax to prevent XSS attacks when displaying user supplied data.

<a name=“blade-and-javascript-frameworks”></a>

25.4.1 Blade & JavaScript Frameworks

Since many JavaScript frameworks also use “curly” braces to indicate a given expression should be displayed in the browser, you may use the @ symbol to inform the Blade rendering engine an expression should remain untouched. For example:

<h1>Laravel</h1>

Hello, @{{ name }}.

In this example, the @ symbol will be removed by Blade; however, {{ name }} expression will remain untouched by the Blade engine, allowing it to instead be rendered by your JavaScript framework.

25.4.1.1 The @verbatim Directive

If you are displaying JavaScript variables in a large portion of your template, you may wrap the HTML in the @verbatim directive so that you do not have to prefix each Blade echo statement with an @ symbol:

@verbatim
    <div class="container">
        Hello, {{ name }}.
    </div>
@endverbatim

<a name=“control-structures”></a>

25.5 Control Structures

In addition to template inheritance and displaying data, Blade also provides convenient shortcuts for common PHP control structures, such as conditional statements and loops. These shortcuts provide a very clean, terse way of working with PHP control structures, while also remaining familiar to their PHP counterparts.

<a name=“if-statements”></a>

25.5.1 If Statements

You may construct if statements using the @if, @elseif, @else, and @endif directives. These directives function identically to their PHP counterparts:

@if (count($records) === 1)
    I have one record!
@elseif (count($records) > 1)
    I have multiple records!
@else
    I don't have any records!
@endif

For convenience, Blade also provides an @unless directive:

@unless (Auth::check())
    You are not signed in.
@endunless

In addition to the conditional directives already discussed, the @isset and @empty directives may be used as convenient shortcuts for their respective PHP functions:

@isset($records)
    // $records is defined and is not null...
@endisset

@empty($records)
    // $records is "empty"...
@endempty

25.5.1.1 Authentication Shortcuts

The @auth and @guest directives may be used to quickly determine if the current user is authenticated or is a guest:

@auth
    // The user is authenticated...
@endauth

@guest
    // The user is not authenticated...
@endguest

<a name=“switch-statements”></a>

25.5.2 Switch Statements

Switch statements can be constructed using the @switch, @case, @break, @default and @endswitch directives:

@switch($i)
    @case(1)
        First case...
        @break

    @case(2)
        Second case...
        @break

    @default
        Default case...
@endswitch

<a name=“loops”></a>

25.5.3 Loops

In addition to conditional statements, Blade provides simple directives for working with PHP’s loop structures. Again, each of these directives functions identically to their PHP counterparts:

@for ($i = 0; $i < 10; $i++)
    The current value is {{ $i }}
@endfor

@foreach ($users as $user)
    <p>This is user {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse

@while (true)
    <p>I'm looping forever.</p>
@endwhile

{tip} When looping, you may use the loop variable to gain valuable information about the loop, such as whether you are in the first or last iteration through the loop.

When using loops you may also end the loop or skip the current iteration:

@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

    <li>{{ $user->name }}</li>

    @if ($user->number == 5)
        @break
    @endif
@endforeach

You may also include the condition with the directive declaration in one line:

@foreach ($users as $user)
    @continue($user->type == 1)

    <li>{{ $user->name }}</li>

    @break($user->number == 5)
@endforeach

<a name=“the-loop-variable”></a>

25.5.4 The Loop Variable

When looping, a $loop variable will be available inside of your loop. This variable provides access to some useful bits of information such as the current loop index and whether this is the first or last iteration through the loop:

@foreach ($users as $user)
    @if ($loop->first)
        This is the first iteration.
    @endif

    @if ($loop->last)
        This is the last iteration.
    @endif

    <p>This is user {{ $user->id }}</p>
@endforeach

If you are in a nested loop, you may access the parent loop’s $loop variable via the parent property:

@foreach ($users as $user)
    @foreach ($user->posts as $post)
        @if ($loop->parent->first)
            This is first iteration of the parent loop.
        @endif
    @endforeach
@endforeach

The $loop variable also contains a variety of other useful properties:

Property Description
$loop->index The index of the current loop iteration (starts at 0).
$loop->iteration The current loop iteration (starts at 1).
$loop->remaining The iteration remaining in the loop.
$loop->count The total number of items in the array being iterated.
$loop->first Whether this is the first iteration through the loop.
$loop->last Whether this is the last iteration through the loop.
$loop->depth The nesting level of the current loop.
$loop->parent When in a nested loop, the parent’s loop variable.

<a name=“comments”></a>

25.5.5 Comments

Blade also allows you to define comments in your views. However, unlike HTML comments, Blade comments are not included in the HTML returned by your application:

{{-- This comment will not be present in the rendered HTML --}}

<a name=“php”></a>

25.5.6 PHP

In some situations, it’s useful to embed PHP code into your views. You can use the Blade @php directive to execute a block of plain PHP within your template:

@php
    //
@endphp

{tip} While Blade provides this feature, using it frequently may be a signal that you have too much logic embedded within your template.

<a name=“including-sub-views”></a>

25.6 Including Sub-Views

Blade’s @include directive allows you to include a Blade view from within another view. All variables that are available to the parent view will be made available to the included view:

<div>
    @include('shared.errors')

    <form>
        <!-- Form Contents -->
    </form>
</div>

Even though the included view will inherit all data available in the parent view, you may also pass an array of extra data to the included view:

@include('view.name', ['some' => 'data'])

Of course, if you attempt to @include a view which does not exist, Laravel will throw an error. If you would like to include a view that may or may not be present, you should use the @includeIf directive:

@includeIf('view.name', ['some' => 'data'])

If you would like to @include a view depending on a given boolean condition, you may use the @includeWhen directive:

@includeWhen($boolean, 'view.name', ['some' => 'data'])

{note} You should avoid using the __DIR__ and __FILE__ constants in your Blade views, since they will refer to the location of the cached, compiled view.

<a name=“rendering-views-for-collections”></a>

25.6.1 Rendering Views For Collections

You may combine loops and includes into one line with Blade’s @each directive:

@each('view.name', $jobs, 'job')

The first argument is the view partial to render for each element in the array or collection. The second argument is the array or collection you wish to iterate over, while the third argument is the variable name that will be assigned to the current iteration within the view. So, for example, if you are iterating over an array of jobs, typically you will want to access each job as a job variable within your view partial. The key for the current iteration will be available as the key variable within your view partial.

You may also pass a fourth argument to the @each directive. This argument determines the view that will be rendered if the given array is empty.

@each('view.name', $jobs, 'job', 'view.empty')

{note} Views rendered via @each do not inherit the variables from the parent view. If the child view requires these variables, you should use @foreach and @include instead.

<a name=“stacks”></a>

25.7 Stacks

Blade allows you to push to named stacks which can be rendered somewhere else in another view or layout. This can be particularly useful for specifying any JavaScript libraries required by your child views:

@push('scripts')
    <script src="/example.js"></script>
@endpush

You may push to a stack as many times as needed. To render the complete stack contents, pass the name of the stack to the @stack directive:

<head>
    <!-- Head Contents -->

    @stack('scripts')
</head>

<a name=“service-injection”></a>

25.8 Service Injection

The @inject directive may be used to retrieve a service from the Laravel service container. The first argument passed to @inject is the name of the variable the service will be placed into, while the second argument is the class or interface name of the service you wish to resolve:

@inject('metrics', 'App\Services\MetricsService')

<div>
    Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>

<a name=“extending-blade”></a>

25.9 Extending Blade

Blade allows you to define your own custom directives using the directive method. When the Blade compiler encounters the custom directive, it will call the provided callback with the expression that the directive contains.

The following example creates a @datetime($var) directive which formats a given $var, which should be an instance of DateTime:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Blade::directive('datetime', function ($expression) {
            return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

As you can see, we will chain the format method onto whatever expression is passed into the directive. So, in this example, the final PHP generated by this directive will be:

<?php echo ($var)->format('m/d/Y H:i'); ?>

{note} After updating the logic of a Blade directive, you will need to delete all of the cached Blade views. The cached Blade views may be removed using the view:clear Artisan command.

<a name=“custom-if-statements”></a>

25.9.1 Custom If Statements

Programming a custom directive is sometimes more complex than necessary when defining simple, custom conditional statements. For that reason, Blade provides a Blade::if method which allows you to quickly define custom conditional directives using Closures. For example, let’s define a custom conditional that checks the current application environment. We may do this in the boot method of our AppServiceProvider:

use Illuminate\Support\Facades\Blade;

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    Blade::if('env', function ($environment) {
        return app()->environment($environment);
    });
}

Once the custom conditional has been defined, we can easily use it on our templates:

@env('local')
    // The application is in the local environment...
@else
    // The application is not in the local environment...
@endenv

26 Localization

<a name=“introduction”></a>

26.1 Introduction

Laravel’s localization features provide a convenient way to retrieve strings in various languages, allowing you to easily support multiple languages within your application. Language strings are stored in files within the resources/lang directory. Within this directory there should be a subdirectory for each language supported by the application:

/resources
    /lang
        /en
            messages.php
        /es
            messages.php

All language files simply return an array of keyed strings. For example:

<?php

return [
    'welcome' => 'Welcome to our application'
];

26.1.1 Configuring The Locale

The default language for your application is stored in the config/app.php configuration file. Of course, you may modify this value to suit the needs of your application. You may also change the active language at runtime using the setLocale method on the App facade:

Route::get('welcome/{locale}', function ($locale) {
    App::setLocale($locale);

    //
});

You may configure a “fallback language”, which will be used when the active language does not contain a given translation string. Like the default language, the fallback language is also configured in the config/app.php configuration file:

'fallback_locale' => 'en',

26.1.1.1 Determining The Current Locale

You may use the getLocale and isLocale methods on the App facade to determine the current locale or check if the locale is a given value:

$locale = App::getLocale();

if (App::isLocale('en')) {
    //
}

<a name=“defining-translation-strings”></a>

26.2 Defining Translation Strings

<a name=“using-short-keys”></a>

26.2.1 Using Short Keys

Typically, translation strings are stored in files within the resources/lang directory. Within this directory there should be a subdirectory for each language supported by the application:

/resources
    /lang
        /en
            messages.php
        /es
            messages.php

All language files simply return an array of keyed strings. For example:

<?php

// resources/lang/en/messages.php

return [
    'welcome' => 'Welcome to our application'
];

<a name=“using-translation-strings-as-keys”></a>

26.2.2 Using Translation Strings As Keys

For applications with heavy translation requirements, defining every string with a “short key” can become quickly confusing when referencing them in your views. For this reason, Laravel also provides support for defining translation strings using the “default” translation of the string as the key.

Translation files that use translation strings as keys are stored as JSON files in the resources/lang directory. For example, if your application has a Spanish translation, you should create a resources/lang/es.json file:

{
    "I love programming.": "Me encanta programar."
}

<a name=“retrieving-translation-strings”></a>

26.3 Retrieving Translation Strings

You may retrieve lines from language files using the __ helper function. The __ method accepts the file and key of the translation string as its first argument. For example, let’s retrieve the welcome translation string from the resources/lang/messages.php language file:

echo __('messages.welcome');

echo __('I love programming.');

Of course if you are using the Blade templating engine, you may use the {{ }} syntax to echo the translation string or use the @lang directive:

{{ __('messages.welcome') }}

@lang('messages.welcome')

If the specified translation string does not exist, the __ function will simply return the translation string key. So, using the example above, the __ function would return messages.welcome if the translation string does not exist.

<a name=“replacing-parameters-in-translation-strings”></a>

26.3.1 Replacing Parameters In Translation Strings

If you wish, you may define place-holders in your translation strings. All place-holders are prefixed with a :. For example, you may define a welcome message with a place-holder name:

'welcome' => 'Welcome, :name',

To replace the place-holders when retrieving a translation string, pass an array of replacements as the second argument to the __ function:

echo __('messages.welcome', ['name' => 'dayle']);

If your place-holder contains all capital letters, or only has its first letter capitalized, the translated value will be capitalized accordingly:

'welcome' => 'Welcome, :NAME', // Welcome, DAYLE
'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle

<a name=“pluralization”></a>

26.3.2 Pluralization

Pluralization is a complex problem, as different languages have a variety of complex rules for pluralization. By using a “pipe” character, you may distinguish singular and plural forms of a string:

'apples' => 'There is one apple|There are many apples',

You may even create more complex pluralization rules which specify translation strings for multiple number ranges:

'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',

After defining a translation string that has pluralization options, you may use the trans_choice function to retrieve the line for a given “count”. In this example, since the count is greater than one, the plural form of the translation string is returned:

echo trans_choice('messages.apples', 10);

<a name=“overriding-package-language-files”></a>

26.4 Overriding Package Language Files

Some packages may ship with their own language files. Instead of changing the package’s core files to tweak these lines, you may override them by placing files in the resources/lang/vendor/{package}/{locale} directory.

So, for example, if you need to override the English translation strings in messages.php for a package named skyrim/hearthfire, you should place a language file at: resources/lang/vendor/hearthfire/en/messages.php. Within this file, you should only define the translation strings you wish to override. Any translation strings you don’t override will still be loaded from the package’s original language files.

27 JavaScript & CSS Scaffolding

<a name=“introduction”></a>

27.1 Introduction

While Laravel does not dictate which JavaScript or CSS pre-processors you use, it does provide a basic starting point using Bootstrap and Vue that will be helpful for many applications. By default, Laravel uses NPM to install both of these frontend packages.

27.1.0.1 CSS

Laravel Mix provides a clean, expressive API over compiling SASS or Less, which are extensions of plain CSS that add variables, mixins, and other powerful features that make working with CSS much more enjoyable. In this document, we will briefly discuss CSS compilation in general; however, you should consult the full Laravel Mix documentation for more information on compiling SASS or Less.

27.1.0.2 JavaScript

Laravel does not require you to use a specific JavaScript framework or library to build your applications. In fact, you don’t have to use JavaScript at all. However, Laravel does include some basic scaffolding to make it easier to get started writing modern JavaScript using the Vue library. Vue provides an expressive API for building robust JavaScript applications using components. As with CSS, we may use Laravel Mix to easily compile JavaScript components into a single, browser-ready JavaScript file.

27.1.0.3 Removing The Frontend Scaffolding

If you would like to remove the frontend scaffolding from your application, you may use the preset Artisan command. This command, when combined with the none option, will remove the Bootstrap and Vue scaffolding from your application, leaving only a blank SASS file and a few common JavaScript utility libraries:

php artisan preset none

<a name=“writing-css”></a>

27.2 Writing CSS

Laravel’s package.json file includes the bootstrap-sass package to help you get started prototyping your application’s frontend using Bootstrap. However, feel free to add or remove packages from the package.json file as needed for your own application. You are not required to use the Bootstrap framework to build your Laravel application - it is simply provided as a good starting point for those who choose to use it.

Before compiling your CSS, install your project’s frontend dependencies using the Node package manager (NPM):

npm install

Once the dependencies have been installed using npm install, you can compile your SASS files to plain CSS using Laravel Mix. The npm run dev command will process the instructions in your webpack.mix.js file. Typically, your compiled CSS will be placed in the public/css directory:

npm run dev

The default webpack.mix.js included with Laravel will compile the resources/assets/sass/app.scss SASS file. This app.scss file imports a file of SASS variables and loads Bootstrap, which provides a good starting point for most applications. Feel free to customize the app.scss file however you wish or even use an entirely different pre-processor by configuring Laravel Mix.

<a name=“writing-javascript”></a>

27.3 Writing JavaScript

All of the JavaScript dependencies required by your application can be found in the package.json file in the project’s root directory. This file is similar to a composer.json file except it specifies JavaScript dependencies instead of PHP dependencies. You can install these dependencies using the Node package manager (NPM):

npm install

{tip} By default, the Laravel package.json file includes a few packages such as vue and axios to help you get started building your JavaScript application. Feel free to add or remove from the package.json file as needed for your own application.

Once the packages are installed, you can use the npm run dev command to compile your assets. Webpack is a module bundler for modern JavaScript applications. When you run the npm run dev command, Webpack will execute the instructions in your webpack.mix.js file:

npm run dev

By default, the Laravel webpack.mix.js file compiles your SASS and the resources/assets/js/app.js file. Within the app.js file you may register your Vue components or, if you prefer a different framework, configure your own JavaScript application. Your compiled JavaScript will typically be placed in the public/js directory.

{tip} The app.js file will load the resources/assets/js/bootstrap.js file which bootstraps and configures Vue, Axios, jQuery, and all other JavaScript dependencies. If you have additional JavaScript dependencies to configure, you may do so in this file.

<a name=“writing-vue-components”></a>

27.3.1 Writing Vue Components

By default, fresh Laravel applications contain an Example.vue Vue component located in the resources/assets/js/components directory. The Example.vue file is an example of a single file Vue component which defines its JavaScript and HTML template in the same file. Single file components provide a very convenient approach to building JavaScript driven applications. The example component is registered in your app.js file:

Vue.component('example', require('./components/Example.vue'));

To use the component in your application, you may simply drop it into one of your HTML templates. For example, after running the make:auth Artisan command to scaffold your application’s authentication and registration screens, you could drop the component into the home.blade.php Blade template:

@extends('layouts.app')

@section('content')
    <example></example>
@endsection

{tip} Remember, you should run the npm run dev command each time you change a Vue component. Or, you may run the npm run watch command to monitor and automatically recompile your components each time they are modified.

Of course, if you are interested in learning more about writing Vue components, you should read the Vue documentation, which provides a thorough, easy-to-read overview of the entire Vue framework.

<a name=“using-react”></a>

27.3.2 Using React

If you prefer to use React to build your JavaScript application, Laravel makes it a cinch to swap the Vue scaffolding with React scaffolding. On any fresh Laravel application, you may use the preset command with the react option:

php artisan preset react

This single command will remove the Vue scaffolding and replace it with React scaffolding, including an example component.

28 Compiling Assets (Laravel Mix)

<a name=“introduction”></a>

28.1 Introduction

Laravel Mix provides a fluent API for defining Webpack build steps for your Laravel application using several common CSS and JavaScript pre-processors. Through simple method chaining, you can fluently define your asset pipeline. For example:

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

If you’ve ever been confused and overwhelmed about getting started with Webpack and asset compilation, you will love Laravel Mix. However, you are not required to use it while developing your application. Of course, you are free to use any asset pipeline tool you wish, or even none at all.

<a name=“installation”></a>

28.2 Installation & Setup

28.2.0.1 Installing Node

Before triggering Mix, you must first ensure that Node.js and NPM are installed on your machine.

node -v
npm -v

By default, Laravel Homestead includes everything you need; however, if you aren’t using Vagrant, then you can easily install the latest version of Node and NPM using simple graphical installers from their download page.

28.2.0.2 Laravel Mix

The only remaining step is to install Laravel Mix. Within a fresh installation of Laravel, you’ll find a package.json file in the root of your directory structure. The default package.json file includes everything you need to get started. Think of this like your composer.json file, except it defines Node dependencies instead of PHP. You may install the dependencies it references by running:

npm install

If you are developing on a Windows system or you are running your VM on a Windows host system, you may need to run the npm install command with the --no-bin-links switch enabled:

npm install --no-bin-links

<a name=“running-mix”></a>

28.3 Running Mix

Mix is a configuration layer on top of Webpack, so to run your Mix tasks you only need to execute one of the NPM scripts that is included with the default Laravel package.json file:

// Run all Mix tasks...
npm run dev

// Run all Mix tasks and minify output...
npm run production

28.3.0.1 Watching Assets For Changes

The npm run watch command will continue running in your terminal and watch all relevant files for changes. Webpack will then automatically recompile your assets when it detects a change:

npm run watch

You may find that in certain environments Webpack isn’t updating when your files change. If this is the case on your system, consider using the watch-poll command:

npm run watch-poll

<a name=“working-with-stylesheets”></a>

28.4 Working With Stylesheets

The webpack.mix.js file is your entry point for all asset compilation. Think of it as a light configuration wrapper around Webpack. Mix tasks can be chained together to define exactly how your assets should be compiled.

<a name=“less”></a>

28.4.1 Less

The less method may be used to compile Less into CSS. Let’s compile our primary app.less file to public/css/app.css.

mix.less('resources/assets/less/app.less', 'public/css');

Multiple calls to the less method may be used to compile multiple files:

mix.less('resources/assets/less/app.less', 'public/css')
   .less('resources/assets/less/admin.less', 'public/css');

If you wish to customize the file name of the compiled CSS, you may pass a full file path as the second argument to the less method:

mix.less('resources/assets/less/app.less', 'public/stylesheets/styles.css');

If you need to override the underlying Less plug-in options, you may pass an object as the third argument to mix.less():

mix.less('resources/assets/less/app.less', 'public/css', {
    strictMath: true
});

<a name=“sass”></a>

28.4.2 Sass

The sass method allows you to compile Sass into CSS. You may use the method like so:

mix.sass('resources/assets/sass/app.scss', 'public/css');

Again, like the less method, you may compile multiple Sass files into their own respective CSS files and even customize the output directory of the resulting CSS:

mix.sass('resources/assets/sass/app.sass', 'public/css')
   .sass('resources/assets/sass/admin.sass', 'public/css/admin');

Additional Node-Sass plug-in options may be provided as the third argument:

mix.sass('resources/assets/sass/app.sass', 'public/css', {
    precision: 5
});

<a name=“stylus”></a>

28.4.3 Stylus

Similar to Less and Sass, the stylus method allows you to compile Stylus into CSS:

mix.stylus('resources/assets/stylus/app.styl', 'public/css');

You may also install additional Stylus plug-ins, such as Rupture. First, install the plug-in in question through NPM (npm install rupture) and then require it in your call to mix.stylus():

mix.stylus('resources/assets/stylus/app.styl', 'public/css', {
    use: [
        require('rupture')()
    ]
});

<a name=“postcss”></a>

28.4.4 PostCSS

PostCSS, a powerful tool for transforming your CSS, is included with Laravel Mix out of the box. By default, Mix leverages the popular Autoprefixer plug-in to automatically apply all necessary CSS3 vendor prefixes. However, you’re free to add any additional plug-ins that are appropriate for your application. First, install the desired plug-in through NPM and then reference it in your webpack.mix.js file:

mix.sass('resources/assets/sass/app.scss', 'public/css')
   .options({
        postCss: [
            require('postcss-css-variables')()
        ]
   });

<a name=“plain-css”></a>

28.4.5 Plain CSS

If you would just like to concatenate some plain CSS stylesheets into a single file, you may use the styles method.

mix.styles([
    'public/css/vendor/normalize.css',
    'public/css/vendor/videojs.css'
], 'public/css/all.css');

<a name=“url-processing”></a>

28.4.6 URL Processing

Because Laravel Mix is built on top of Webpack, it’s important to understand a few Webpack concepts. For CSS compilation, Webpack will rewrite and optimize any url() calls within your stylesheets. While this might initially sound strange, it’s an incredibly powerful piece of functionality. Imagine that we want to compile Sass that includes a relative URL to an image:

.example {
    background: url('../images/example.png');
}

{note} Absolute paths for any given url() will be excluded from URL-rewriting. For example, url('/images/thing.png') or url('http://example.com/images/thing.png') won’t be modified.

By default, Laravel Mix and Webpack will find example.png, copy it to your public/images folder, and then rewrite the url() within your generated stylesheet. As such, your compiled CSS will be:

.example {
  background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
}

As useful as this feature may be, it’s possible that your existing folder structure is already configured in a way you like. If this is the case, you may disable url() rewriting like so:

mix.sass('resources/assets/app/app.scss', 'public/css')
   .options({
      processCssUrls: false
   });

With this addition to your webpack.mix.js file, Mix will no longer match any url() or copy assets to your public directory. In other words, the compiled CSS will look just like how you originally typed it:

.example {
    background: url("../images/thing.png");
}

<a name=“css-source-maps”></a>

28.4.7 Source Maps

Though disabled by default, source maps may be activated by calling the mix.sourceMaps() method in your webpack.mix.js file. Though it comes with a compile/performance cost, this will provide extra debugging information to your browser’s developer tools when using compiled assets.

mix.js('resources/assets/js/app.js', 'public/js')
   .sourceMaps();

<a name=“working-with-scripts”></a>

28.5 Working With JavaScript

Mix provides several features to help you work with your JavaScript files, such as compiling ECMAScript 2015, module bundling, minification, and simply concatenating plain JavaScript files. Even better, this all works seamlessly, without requiring an ounce of custom configuration:

mix.js('resources/assets/js/app.js', 'public/js');

With this single line of code, you may now take advantage of:

<div class=“content-list” markdown=“1”>

  • ES2015 syntax.
  • Modules
  • Compilation of .vue files.
  • Minification for production environments.
    </div>

<a name=“vendor-extraction”></a>

28.5.1 Vendor Extraction

One potential downside to bundling all application-specific JavaScript with your vendor libraries is that it makes long-term caching more difficult. For example, a single update to your application code will force the browser to re-download all of your vendor libraries even if they haven’t changed.

If you intend to make frequent updates to your application’s JavaScript, you should consider extracting all of your vendor libraries into their own file. This way, a change to your application code will not affect the caching of your large vendor.js file. Mix’s extract method makes this a breeze:

mix.js('resources/assets/js/app.js', 'public/js')
   .extract(['vue'])

The extract method accepts an array of all libraries or modules that you wish to extract into a vendor.js file. Using the above snippet as an example, Mix will generate the following files:

<div class=“content-list” markdown=“1”>

  • public/js/manifest.js: The Webpack manifest runtime
  • public/js/vendor.js: Your vendor libraries
  • public/js/app.js: Your application code
    </div>

To avoid JavaScript errors, be sure to load these files in the proper order:

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>

<a name=“react”></a>

28.5.2 React

Mix can automatically install the Babel plug-ins necessary for React support. To get started, replace your mix.js() call with mix.react():

mix.react('resources/assets/js/app.jsx', 'public/js');

Behind the scenes, Mix will download and include the appropriate babel-preset-react Babel plug-in.

<a name=“vanilla-js”></a>

28.5.3 Vanilla JS

Similar to combining stylesheets with mix.styles(), you may also combine and minify any number of JavaScript files with the scripts() method:

mix.scripts([
    'public/js/admin.js',
    'public/js/dashboard.js'
], 'public/js/all.js');

This option is particularly useful for legacy projects where you don’t require Webpack compilation for your JavaScript.

{tip} A slight variation of mix.scripts() is mix.babel(). Its method signature is identical to scripts; however, the concatenated file will receive Babel compilation, which translates any ES2015 code to vanilla JavaScript that all browsers will understand.

<a name=“custom-webpack-configuration”></a>

28.5.4 Custom Webpack Configuration

Behind the scenes, Laravel Mix references a pre-configured webpack.config.js file to get you up and running as quickly as possible. Occasionally, you may need to manually modify this file. You might have a special loader or plug-in that needs to be referenced, or maybe you prefer to use Stylus instead of Sass. In such instances, you have two choices:

28.5.4.1 Merging Custom Configuration

Mix provides a useful webpackConfig method that allows you to merge any short Webpack configuration overrides. This is a particularly appealing choice, as it doesn’t require you to copy and maintain your own copy of the webpack.config.js file. The webpackConfig method accepts an object, which should contain any Webpack-specific configuration that you wish to apply.

mix.webpackConfig({
    resolve: {
        modules: [
            path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
        ]
    }
});

28.5.4.2 Custom Configuration Files

If you would like completely customize your Webpack configuration, copy the node_modules/laravel-mix/setup/webpack.config.js file to your project’s root directory. Next, point all of the --config references in your package.json file to the newly copied configuration file. If you choose to take this approach to customization, any future upstream updates to Mix’s webpack.config.js must be manually merged into your customized file.

<a name=“copying-files-and-directories”></a>

28.6 Copying Files & Directories

The copy method may be used to copy files and directories to new locations. This can be useful when a particular asset within your node_modules directory needs to be relocated to your public folder.

mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');

When copying a directory, the copy method will flatten the directory’s structure. To maintain the directory’s original structure, you should use the copyDirectory method instead:

mix.copyDirectory('assets/img', 'public/img');

<a name=“versioning-and-cache-busting”></a>

28.7 Versioning / Cache Busting

Many developers suffix their compiled assets with a timestamp or unique token to force browsers to load the fresh assets instead of serving stale copies of the code. Mix can handle this for you using the version method.

The version method will automatically append a unique hash to the filenames of all compiled files, allowing for more convenient cache busting:

mix.js('resources/assets/js/app.js', 'public/js')
   .version();

After generating the versioned file, you won’t know the exact file name. So, you should use Laravel’s global mix function within your views to load the appropriately hashed asset. The mix function will automatically determine the current name of the hashed file:

<link rel="stylesheet" href="{{ mix('/css/app.css') }}">

Because versioned files are usually unnecessary in development, you may instruct the versioning process to only run during npm run production:

mix.js('resources/assets/js/app.js', 'public/js');

if (mix.inProduction()) {
    mix.version();
}

<a name=“browsersync-reloading”></a>

28.8 Browsersync Reloading

BrowserSync can automatically monitor your files for changes, and inject your changes into the browser without requiring a manual refresh. You may enable support by calling the mix.browserSync() method:

mix.browserSync('my-domain.dev');

// Or...

// https://browsersync.io/docs/options
mix.browserSync({
    proxy: 'my-domain.dev'
});

You may pass either a string (proxy) or object (BrowserSync settings) to this method. Next, start Webpack’s dev server using the npm run watch command. Now, when you modify a script or PHP file, watch as the browser instantly refreshes the page to reflect your changes.

<a name=“environment-variables”></a>

28.9 Environment Variables

You may inject environment variables into Mix by prefixing a key in your .env file with MIX_:

MIX_SENTRY_DSN_PUBLIC=http://example.com

After the variable has been defined in your .env file, you may access via the process.env object. If the value changes while you are running a watch task, you will need to restart the task:

process.env.MIX_SENTRY_DSN_PUBLIC

<a name=“notifications”></a>

28.10 Notifications

When available, Mix will automatically display OS notifications for each bundle. This will give you instant feedback, as to whether the compilation was successful or not. However, there may be instances when you’d prefer to disable these notifications. One such example might be triggering Mix on your production server. Notifications may be deactivated, via the disableNotifications method.

mix.disableNotifications();

29 Authentication

<a name=“introduction”></a>

29.1 Introduction

{tip} Want to get started fast? Just run php artisan make:auth and php artisan migrate in a fresh Laravel application. Then, navigate your browser to http://your-app.dev/register or any other URL that is assigned to your application. These two commands will take care of scaffolding your entire authentication system!

Laravel makes implementing authentication very simple. In fact, almost everything is configured for you out of the box. The authentication configuration file is located at config/auth.php, which contains several well documented options for tweaking the behavior of the authentication services.

At its core, Laravel’s authentication facilities are made up of “guards” and “providers”. Guards define how users are authenticated for each request. For example, Laravel ships with a session guard which maintains state using session storage and cookies.

Providers define how users are retrieved from your persistent storage. Laravel ships with support for retrieving users using Eloquent and the database query builder. However, you are free to define additional providers as needed for your application.

Don’t worry if this all sounds confusing now! Many applications will never need to modify the default authentication configuration.

<a name=“introduction-database-considerations”></a>

29.1.1 Database Considerations

By default, Laravel includes an App\User Eloquent model in your app directory. This model may be used with the default Eloquent authentication driver. If your application is not using Eloquent, you may use the database authentication driver which uses the Laravel query builder.

When building the database schema for the App\User model, make sure the password column is at least 60 characters in length. Maintaining the default string column length of 255 characters would be a good choice.

Also, you should verify that your users (or equivalent) table contains a nullable, string remember_token column of 100 characters. This column will be used to store a token for users that select the “remember me” option when logging into your application.

<a name=“authentication-quickstart”></a>

29.2 Authentication Quickstart

Laravel ships with several pre-built authentication controllers, which are located in the App\Http\Controllers\Auth namespace. The RegisterController handles new user registration, the LoginController handles authentication, the ForgotPasswordController handles e-mailing links for resetting passwords, and the ResetPasswordController contains the logic to reset passwords. Each of these controllers uses a trait to include their necessary methods. For many applications, you will not need to modify these controllers at all.

<a name=“included-routing”></a>

29.2.1 Routing

Laravel provides a quick way to scaffold all of the routes and views you need for authentication using one simple command:

php artisan make:auth

This command should be used on fresh applications and will install a layout view, registration and login views, as well as routes for all authentication end-points. A HomeController will also be generated to handle post-login requests to your application’s dashboard.

<a name=“included-views”></a>

29.2.2 Views

As mentioned in the previous section, the php artisan make:auth command will create all of the views you need for authentication and place them in the resources/views/auth directory.

The make:auth command will also create a resources/views/layouts directory containing a base layout for your application. All of these views use the Bootstrap CSS framework, but you are free to customize them however you wish.

<a name=“included-authenticating”></a>

29.2.3 Authenticating

Now that you have routes and views setup for the included authentication controllers, you are ready to register and authenticate new users for your application! You may simply access your application in a browser since the authentication controllers already contain the logic (via their traits) to authenticate existing users and store new users in the database.

29.2.3.1 Path Customization

When a user is successfully authenticated, they will be redirected to the /home URI. You can customize the post-authentication redirect location by defining a redirectTo property on the LoginController, RegisterController, and ResetPasswordController:

protected $redirectTo = '/';

If the redirect path needs custom generation logic you may define a redirectTo method instead of a redirectTo property:

protected function redirectTo()
{
    return '/path';
}

{tip} The redirectTo method will take precedence over the redirectTo attribute.

29.2.3.2 Username Customization

By default, Laravel uses the email field for authentication. If you would like to customize this, you may define a username method on your LoginController:

public function username()
{
    return 'username';
}

29.2.3.3 Guard Customization

You may also customize the “guard” that is used to authenticate and register users. To get started, define a guard method on your LoginController, RegisterController, and ResetPasswordController. The method should return a guard instance:

use Illuminate\Support\Facades\Auth;

protected function guard()
{
    return Auth::guard('guard-name');
}

29.2.3.4 Validation / Storage Customization

To modify the form fields that are required when a new user registers with your application, or to customize how new users are stored into your database, you may modify the RegisterController class. This class is responsible for validating and creating new users of your application.

The validator method of the RegisterController contains the validation rules for new users of the application. You are free to modify this method as you wish.

The create method of the RegisterController is responsible for creating new App\User records in your database using the Eloquent ORM. You are free to modify this method according to the needs of your database.

<a name=“retrieving-the-authenticated-user”></a>

29.2.4 Retrieving The Authenticated User

You may access the authenticated user via the Auth facade:

use Illuminate\Support\Facades\Auth;

// Get the currently authenticated user...
$user = Auth::user();

// Get the currently authenticated user's ID...
$id = Auth::id();

Alternatively, once a user is authenticated, you may access the authenticated user via an Illuminate\Http\Request instance. Remember, type-hinted classes will automatically be injected into your controller methods:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProfileController extends Controller
{
    /**
     * Update the user's profile.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        // $request->user() returns an instance of the authenticated user...
    }
}

29.2.4.1 Determining If The Current User Is Authenticated

To determine if the user is already logged into your application, you may use the check method on the Auth facade, which will return true if the user is authenticated:

use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
    // The user is logged in...
}

{tip} Even though it is possible to determine if a user is authenticated using the check method, you will typically use a middleware to verify that the user is authenticated before allowing the user access to certain routes / controllers. To learn more about this, check out the documentation on protecting routes.

<a name=“protecting-routes”></a>

29.2.5 Protecting Routes

Route middleware can be used to only allow authenticated users to access a given route. Laravel ships with an auth middleware, which is defined at Illuminate\Auth\Middleware\Authenticate. Since this middleware is already registered in your HTTP kernel, all you need to do is attach the middleware to a route definition:

Route::get('profile', function () {
    // Only authenticated users may enter...
})->middleware('auth');

Of course, if you are using controllers, you may call the middleware method from the controller’s constructor instead of attaching it in the route definition directly:

public function __construct()
{
    $this->middleware('auth');
}

29.2.5.1 Specifying A Guard

When attaching the auth middleware to a route, you may also specify which guard should be used to authenticate the user. The guard specified should correspond to one of the keys in the guards array of your auth.php configuration file:

public function __construct()
{
    $this->middleware('auth:api');
}

<a name=“login-throttling”></a>

29.2.6 Login Throttling

If you are using Laravel’s built-in LoginController class, the Illuminate\Foundation\Auth\ThrottlesLogins trait will already be included in your controller. By default, the user will not be able to login for one minute if they fail to provide the correct credentials after several attempts. The throttling is unique to the user’s username / e-mail address and their IP address.

<a name=“authenticating-users”></a>

29.3 Manually Authenticating Users

Of course, you are not required to use the authentication controllers included with Laravel. If you choose to remove these controllers, you will need to manage user authentication using the Laravel authentication classes directly. Don’t worry, it’s a cinch!

We will access Laravel’s authentication services via the Auth facade, so we’ll need to make sure to import the Auth facade at the top of the class. Next, let’s check out the attempt method:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    /**
     * Handle an authentication attempt.
     *
     * @return Response
     */
    public function authenticate()
    {
        if (Auth::attempt(['email' => $email, 'password' => $password])) {
            // Authentication passed...
            return redirect()->intended('dashboard');
        }
    }
}

The attempt method accepts an array of key / value pairs as its first argument. The values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the email column. If the user is found, the hashed password stored in the database will be compared with the hashed password value passed to the method via the array. If the two hashed passwords match an authenticated session will be started for the user.

The attempt method will return true if authentication was successful. Otherwise, false will be returned.

The intended method on the redirector will redirect the user to the URL they were attempting to access before being intercepted by the authentication middleware. A fallback URI may be given to this method in case the intended destination is not available.

29.3.0.1 Specifying Additional Conditions

If you wish, you may also add extra conditions to the authentication query in addition to the user’s e-mail and password. For example, we may verify that user is marked as “active”:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
}

{note} In these examples, email is not a required option, it is merely used as an example. You should use whatever column name corresponds to a “username” in your database.

29.3.0.2 Accessing Specific Guard Instances

You may specify which guard instance you would like to utilize using the guard method on the Auth facade. This allows you to manage authentication for separate parts of your application using entirely separate authenticatable models or user tables.

The guard name passed to the guard method should correspond to one of the guards configured in your auth.php configuration file:

if (Auth::guard('admin')->attempt($credentials)) {
    //
}

29.3.0.3 Logging Out

To log users out of your application, you may use the logout method on the Auth facade. This will clear the authentication information in the user’s session:

Auth::logout();

<a name=“remembering-users”></a>

29.3.1 Remembering Users

If you would like to provide “remember me” functionality in your application, you may pass a boolean value as the second argument to the attempt method, which will keep the user authenticated indefinitely, or until they manually logout. Of course, your users table must include the string remember_token column, which will be used to store the “remember me” token.

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
    // The user is being remembered...
}

{tip} If you are using the built-in LoginController that is shipped with Laravel, the proper logic to “remember” users is already implemented by the traits used by the controller.

If you are “remembering” users, you may use the viaRemember method to determine if the user was authenticated using the “remember me” cookie:

if (Auth::viaRemember()) {
    //
}

<a name=“other-authentication-methods”></a>

29.3.2 Other Authentication Methods

29.3.2.1 Authenticate A User Instance

If you need to log an existing user instance into your application, you may call the login method with the user instance. The given object must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract. Of course, the App\User model included with Laravel already implements this interface:

Auth::login($user);

// Login and "remember" the given user...
Auth::login($user, true);

Of course, you may specify the guard instance you would like to use:

Auth::guard('admin')->login($user);

29.3.2.2 Authenticate A User By ID

To log a user into the application by their ID, you may use the loginUsingId method. This method simply accepts the primary key of the user you wish to authenticate:

Auth::loginUsingId(1);

// Login and "remember" the given user...
Auth::loginUsingId(1, true);

29.3.2.3 Authenticate A User Once

You may use the once method to log a user into the application for a single request. No sessions or cookies will be utilized, which means this method may be helpful when building a stateless API:

if (Auth::once($credentials)) {
    //
}

<a name=“http-basic-authentication”></a>

29.4 HTTP Basic Authentication

HTTP Basic Authentication provides a quick way to authenticate users of your application without setting up a dedicated “login” page. To get started, attach the auth.basic middleware to your route. The auth.basic middleware is included with the Laravel framework, so you do not need to define it:

Route::get('profile', function () {
    // Only authenticated users may enter...
})->middleware('auth.basic');

Once the middleware has been attached to the route, you will automatically be prompted for credentials when accessing the route in your browser. By default, the auth.basic middleware will use the email column on the user record as the “username”.

29.4.0.1 A Note On FastCGI

If you are using PHP FastCGI, HTTP Basic authentication may not work correctly out of the box. The following lines should be added to your .htaccess file:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

<a name=“stateless-http-basic-authentication”></a>

29.4.1 Stateless HTTP Basic Authentication

You may also use HTTP Basic Authentication without setting a user identifier cookie in the session, which is particularly useful for API authentication. To do so, define a middleware that calls the onceBasic method. If no response is returned by the onceBasic method, the request may be passed further into the application:

<?php

namespace Illuminate\Auth\Middleware;

use Illuminate\Support\Facades\Auth;

class AuthenticateOnceWithBasicAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, $next)
    {
        return Auth::onceBasic() ?: $next($request);
    }

}

Next, register the route middleware and attach it to a route:

Route::get('api/user', function () {
    // Only authenticated users may enter...
})->middleware('auth.basic.once');

<a name=“adding-custom-guards”></a>

29.5 Adding Custom Guards

You may define your own authentication guards using the extend method on the Auth facade. You should place this call to provider within a service provider. Since Laravel already ships with an AuthServiceProvider, we can place the code in that provider:

<?php

namespace App\Providers;

use App\Services\Auth\JwtGuard;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Auth::extend('jwt', function ($app, $name, array $config) {
            // Return an instance of Illuminate\Contracts\Auth\Guard...

            return new JwtGuard(Auth::createUserProvider($config['provider']));
        });
    }
}

As you can see in the example above, the callback passed to the extend method should return an implementation of Illuminate\Contracts\Auth\Guard. This interface contains a few methods you will need to implement to define a custom guard. Once your custom guard has been defined, you may use this guard in the guards configuration of your auth.php configuration file:

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

<a name=“adding-custom-user-providers”></a>

29.6 Adding Custom User Providers

If you are not using a traditional relational database to store your users, you will need to extend Laravel with your own authentication user provider. We will use the provider method on the Auth facade to define a custom user provider:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Auth;
use App\Extensions\RiakUserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Auth::provider('riak', function ($app, array $config) {
            // Return an instance of Illuminate\Contracts\Auth\UserProvider...

            return new RiakUserProvider($app->make('riak.connection'));
        });
    }
}

After you have registered the provider using the provider method, you may switch to the new user provider in your auth.php configuration file. First, define a provider that uses your new driver:

'providers' => [
    'users' => [
        'driver' => 'riak',
    ],
],

Finally, you may use this provider in your guards configuration:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
],

<a name=“the-user-provider-contract”></a>

29.6.1 The User Provider Contract

The Illuminate\Contracts\Auth\UserProvider implementations are only responsible for fetching a Illuminate\Contracts\Auth\Authenticatable implementation out of a persistent storage system, such as MySQL, Riak, etc. These two interfaces allow the Laravel authentication mechanisms to continue functioning regardless of how the user data is stored or what type of class is used to represent it.

Let’s take a look at the Illuminate\Contracts\Auth\UserProvider contract:

<?php

namespace Illuminate\Contracts\Auth;

interface UserProvider {

    public function retrieveById($identifier);
    public function retrieveByToken($identifier, $token);
    public function updateRememberToken(Authenticatable $user, $token);
    public function retrieveByCredentials(array $credentials);
    public function validateCredentials(Authenticatable $user, array $credentials);

}

The retrieveById function typically receives a key representing the user, such as an auto-incrementing ID from a MySQL database. The Authenticatable implementation matching the ID should be retrieved and returned by the method.

The retrieveByToken function retrieves a user by their unique $identifier and “remember me” $token, stored in a field remember_token. As with the previous method, the Authenticatable implementation should be returned.

The updateRememberToken method updates the $user field remember_token with the new $token. The new token can be either a fresh token, assigned on a successful “remember me” login attempt, or when the user is logging out.

The retrieveByCredentials method receives the array of credentials passed to the Auth::attempt method when attempting to sign into an application. The method should then “query” the underlying persistent storage for the user matching those credentials. Typically, this method will run a query with a “where” condition on $credentials['username']. The method should then return an implementation of Authenticatable. This method should not attempt to do any password validation or authentication.

The validateCredentials method should compare the given $user with the $credentials to authenticate the user. For example, this method should probably use Hash::check to compare the value of $user->getAuthPassword() to the value of $credentials['password']. This method should return true or false indicating on whether the password is valid.

<a name=“the-authenticatable-contract”></a>

29.6.2 The Authenticatable Contract

Now that we have explored each of the methods on the UserProvider, let’s take a look at the Authenticatable contract. Remember, the provider should return implementations of this interface from the retrieveById and retrieveByCredentials methods:

<?php

namespace Illuminate\Contracts\Auth;

interface Authenticatable {

    public function getAuthIdentifierName();
    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();

}

This interface is simple. The getAuthIdentifierName method should return the name of the “primary key” field of the user and the getAuthIdentifier method should return the “primary key” of the user. In a MySQL back-end, again, this would be the auto-incrementing primary key. The getAuthPassword should return the user’s hashed password. This interface allows the authentication system to work with any User class, regardless of what ORM or storage abstraction layer you are using. By default, Laravel includes a User class in the app directory which implements this interface, so you may consult this class for an implementation example.

<a name=“events”></a>

29.7 Events

Laravel raises a variety of events during the authentication process. You may attach listeners to these events in your EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Auth\Events\Registered' => [
        'App\Listeners\LogRegisteredUser',
    ],

    'Illuminate\Auth\Events\Attempting' => [
        'App\Listeners\LogAuthenticationAttempt',
    ],

    'Illuminate\Auth\Events\Authenticated' => [
        'App\Listeners\LogAuthenticated',
    ],

    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LogSuccessfulLogin',
    ],

    'Illuminate\Auth\Events\Failed' => [
        'App\Listeners\LogFailedLogin',
    ],

    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogSuccessfulLogout',
    ],

    'Illuminate\Auth\Events\Lockout' => [
        'App\Listeners\LogLockout',
    ],
];

30 API Authentication (Passport)

<a name=“introduction”></a>

30.1 Introduction

Laravel already makes it easy to perform authentication via traditional login forms, but what about APIs? APIs typically use tokens to authenticate users and do not maintain session state between requests. Laravel makes API authentication a breeze using Laravel Passport, which provides a full OAuth2 server implementation for your Laravel application in a matter of minutes. Passport is built on top of the League OAuth2 server that is maintained by Alex Bilbie.

{note} This documentation assumes you are already familiar with OAuth2. If you do not know anything about OAuth2, consider familiarizing yourself with the general terminology and features of OAuth2 before continuing.

<a name=“installation”></a>

30.2 Installation

To get started, install Passport via the Composer package manager:

composer require laravel/passport

Next, register the Passport service provider in the providers array of your config/app.php configuration file:

Laravel\Passport\PassportServiceProvider::class,

The Passport service provider registers its own database migration directory with the framework, so you should migrate your database after registering the provider. The Passport migrations will create the tables your application needs to store clients and access tokens:

php artisan migrate

{note} If you are not going to use Passport’s default migrations, you should call the Passport::ignoreMigrations method in the register method of your AppServiceProvider. You may export the default migrations using php artisan vendor:publish --tag=passport-migrations.

Next, you should run the passport:install command. This command will create the encryption keys needed to generate secure access tokens. In addition, the command will create “personal access” and “password grant” clients which will be used to generate access tokens:

php artisan passport:install

After running this command, add the Laravel\Passport\HasApiTokens trait to your App\User model. This trait will provide a few helper methods to your model which allow you to inspect the authenticated user’s token and scopes:

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

Next, you should call the Passport::routes method within the boot method of your AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:

<?php

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}

Finally, in your config/auth.php configuration file, you should set the driver option of the api authentication guard to passport. This will instruct your application to use Passport’s TokenGuard when authenticating incoming API requests:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

<a name=“frontend-quickstart”></a>

30.2.1 Frontend Quickstart

{note} In order to use the Passport Vue components, you must be using the Vue JavaScript framework. These components also use the Bootstrap CSS framework. However, even if you are not using these tools, the components serve as a valuable reference for your own frontend implementation.

Passport ships with a JSON API that you may use to allow your users to create clients and personal access tokens. However, it can be time consuming to code a frontend to interact with these APIs. So, Passport also includes pre-built Vue components you may use as an example implementation or starting point for your own implementation.

To publish the Passport Vue components, use the vendor:publish Artisan command:

php artisan vendor:publish --tag=passport-components

The published components will be placed in your resources/assets/js/components directory. Once the components have been published, you should register them in your resources/assets/js/app.js file:

Vue.component(
    'passport-clients',
    require('./components/passport/Clients.vue')
);

Vue.component(
    'passport-authorized-clients',
    require('./components/passport/AuthorizedClients.vue')
);

Vue.component(
    'passport-personal-access-tokens',
    require('./components/passport/PersonalAccessTokens.vue')
);

After registering the components, make sure to run npm run dev to recompile your assets. Once you have recompiled your assets, you may drop the components into one of your application’s templates to get started creating clients and personal access tokens:

<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>

<a name=“deploying-passport”></a>

30.2.2 Deploying Passport

When deploying Passport to your production servers for the first time, you will likely need to run the passport:keys command. This command generates the encryption keys Passport needs in order to generate access token. The generated keys are not typically kept in source control:

php artisan passport:keys

<a name=“configuration”></a>

30.3 Configuration

<a name=“token-lifetimes”></a>

30.3.1 Token Lifetimes

By default, Passport issues long-lived access tokens that never need to be refreshed. If you would like to configure a shorter token lifetime, you may use the tokensExpireIn and refreshTokensExpireIn methods. These methods should be called from the boot method of your AuthServiceProvider:

use Carbon\Carbon;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::tokensExpireIn(Carbon::now()->addDays(15));

    Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}

<a name=“issuing-access-tokens”></a>

30.4 Issuing Access Tokens

Using OAuth2 with authorization codes is how most developers are familiar with OAuth2. When using authorization codes, a client application will redirect a user to your server where they will either approve or deny the request to issue an access token to the client.

<a name=“managing-clients”></a>

30.4.1 Managing Clients

First, developers building applications that need to interact with your application’s API will need to register their application with yours by creating a “client”. Typically, this consists of providing the name of their application and a URL that your application can redirect to after users approve their request for authorization.

30.4.1.1 The passport:client Command

The simplest way to create a client is using the passport:client Artisan command. This command may be used to create your own clients for testing your OAuth2 functionality. When you run the client command, Passport will prompt you for more information about your client and will provide you with a client ID and secret:

php artisan passport:client

30.4.1.2 JSON API

Since your users will not be able to utilize the client command, Passport provides a JSON API that you may use to create clients. This saves you the trouble of having to manually code controllers for creating, updating, and deleting clients.

However, you will need to pair Passport’s JSON API with your own frontend to provide a dashboard for your users to manage their clients. Below, we’ll review all of the API endpoints for managing clients. For convenience, we’ll use Axios to demonstrate making HTTP requests to the endpoints.

{tip} If you don’t want to implement the entire client management frontend yourself, you can use the frontend quickstart to have a fully functional frontend in a matter of minutes.

30.4.1.3 GET /oauth/clients

This route returns all of the clients for the authenticated user. This is primarily useful for listing all of the user’s clients so that they may edit or delete them:

axios.get('/oauth/clients')
    .then(response => {
        console.log(response.data);
    });

30.4.1.4 POST /oauth/clients

This route is used to create new clients. It requires two pieces of data: the client’s name and a redirect URL. The redirect URL is where the user will be redirected after approving or denying a request for authorization.

When a client is created, it will be issued a client ID and client secret. These values will be used when requesting access tokens from your application. The client creation route will return the new client instance:

const data = {
    name: 'Client Name',
    redirect: 'http://example.com/callback'
};

axios.post('/oauth/clients', data)
    .then(response => {
        console.log(response.data);
    })
    .catch (response => {
        // List errors on response...
    });

30.4.1.5 PUT /oauth/clients/{client-id}

This route is used to update clients. It requires two pieces of data: the client’s name and a redirect URL. The redirect URL is where the user will be redirected after approving or denying a request for authorization. The route will return the updated client instance:

const data = {
    name: 'New Client Name',
    redirect: 'http://example.com/callback'
};

axios.put('/oauth/clients/' + clientId, data)
    .then(response => {
        console.log(response.data);
    })
    .catch (response => {
        // List errors on response...
    });

30.4.1.6 DELETE /oauth/clients/{client-id}

This route is used to delete clients:

axios.delete('/oauth/clients/' + clientId)
    .then(response => {
        //
    });

<a name=“requesting-tokens”></a>

30.4.2 Requesting Tokens

30.4.2.1 Redirecting For Authorization

Once a client has been created, developers may use their client ID and secret to request an authorization code and access token from your application. First, the consuming application should make a redirect request to your application’s /oauth/authorize route like so:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => 'http://example.com/callback',
        'response_type' => 'code',
        'scope' => '',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

{tip} Remember, the /oauth/authorize route is already defined by the Passport::routes method. You do not need to manually define this route.

30.4.2.2 Approving The Request

When receiving authorization requests, Passport will automatically display a template to the user allowing them to approve or deny the authorization request. If they approve the request, they will be redirected back to the redirect_uri that was specified by the consuming application. The redirect_uri must match the redirect URL that was specified when the client was created.

If you would like to customize the authorization approval screen, you may publish Passport’s views using the vendor:publish Artisan command. The published views will be placed in resources/views/vendor/passport:

php artisan vendor:publish --tag=passport-views

30.4.2.3 Converting Authorization Codes To Access Tokens

If the user approves the authorization request, they will be redirected back to the consuming application. The consumer should then issue a POST request to your application to request an access token. The request should include the authorization code that was issued by your application when the user approved the authorization request. In this example, we’ll use the Guzzle HTTP library to make the POST request:

Route::get('/callback', function (Request $request) {
    $http = new GuzzleHttp\Client;

    $response = $http->post('http://your-app.com/oauth/token', [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
            'redirect_uri' => 'http://example.com/callback',
            'code' => $request->code,
        ],
    ]);

    return json_decode((string) $response->getBody(), true);
});

This /oauth/token route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.

{tip} Like the /oauth/authorize route, the /oauth/token route is defined for you by the Passport::routes method. There is no need to manually define this route.

<a name=“refreshing-tokens”></a>

30.4.3 Refreshing Tokens

If your application issues short-lived access tokens, users will need to refresh their access tokens via the refresh token that was provided to them when the access token was issued. In this example, we’ll use the Guzzle HTTP library to refresh the token:

$http = new GuzzleHttp\Client;

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'refresh_token',
        'refresh_token' => 'the-refresh-token',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'scope' => '',
    ],
]);

return json_decode((string) $response->getBody(), true);

This /oauth/token route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.

<a name=“password-grant-tokens”></a>

30.5 Password Grant Tokens

The OAuth2 password grant allows your other first-party clients, such as a mobile application, to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire OAuth2 authorization code redirect flow.

<a name=“creating-a-password-grant-client”></a>

30.5.1 Creating A Password Grant Client

Before your application can issue tokens via the password grant, you will need to create a password grant client. You may do this using the passport:client command with the --password option. If you have already run the passport:install command, you do not need to run this command:

php artisan passport:client --password

<a name=“requesting-password-grant-tokens”></a>

30.5.2 Requesting Tokens

Once you have created a password grant client, you may request an access token by issuing a POST request to the /oauth/token route with the user’s email address and password. Remember, this route is already registered by the Passport::routes method so there is no need to define it manually. If the request is successful, you will receive an access_token and refresh_token in the JSON response from the server:

$http = new GuzzleHttp\Client;

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'taylor@laravel.com',
        'password' => 'my-password',
        'scope' => '',
    ],
]);

return json_decode((string) $response->getBody(), true);

{tip} Remember, access tokens are long-lived by default. However, you are free to configure your maximum access token lifetime if needed.

<a name=“requesting-all-scopes”></a>

30.5.3 Requesting All Scopes

When using the password grant, you may wish to authorize the token for all of the scopes supported by your application. You can do this by requesting the * scope. If you request the * scope, the can method on the token instance will always return true. This scope may only be assigned to a token that is issued using the password grant:

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'taylor@laravel.com',
        'password' => 'my-password',
        'scope' => '*',
    ],
]);

<a name=“implicit-grant-tokens”></a>

30.6 Implicit Grant Tokens

The implicit grant is similar to the authorization code grant; however, the token is returned to the client without exchanging an authorization code. This grant is most commonly used for JavaScript or mobile applications where the client credentials can’t be securely stored. To enable the grant, call the enableImplicitGrant method in your AuthServiceProvider:

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    Passport::enableImplicitGrant();
}

Once a grant has been enabled, developers may use their client ID to request an access token from your application. The consuming application should make a redirect request to your application’s /oauth/authorize route like so:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => 'http://example.com/callback',
        'response_type' => 'token',
        'scope' => '',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

{tip} Remember, the /oauth/authorize route is already defined by the Passport::routes method. You do not need to manually define this route.

<a name=“client-credentials-grant-tokens”></a>

30.7 Client Credentials Grant Tokens

The client credentials grant is suitable for machine-to-machine authentication. For example, you might use this grant in a scheduled job which is performing maintenance tasks over an API. To use this method you first need to add new middleware to your $routeMiddleware in app/Http/Kernel.php:

use Laravel\Passport\Http\Middleware\CheckClientCredentials;

protected $routeMiddleware = [
    'client' => CheckClientCredentials::class,
];

Then attach this middleware to a route:

Route::get('/user', function(Request $request) {
    ...
})->middleware('client');

To retrieve a token, make a request to the oauth/token endpoint:

$guzzle = new GuzzleHttp\Client;

$response = $guzzle->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'client_credentials',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'scope' => 'your-scope',
    ],
]);

echo json_decode((string) $response->getBody(), true);

<a name=“personal-access-tokens”></a>

30.8 Personal Access Tokens

Sometimes, your users may want to issue access tokens to themselves without going through the typical authorization code redirect flow. Allowing users to issue tokens to themselves via your application’s UI can be useful for allowing users to experiment with your API or may serve as a simpler approach to issuing access tokens in general.

{note} Personal access tokens are always long-lived. Their lifetime is not modified when using the tokensExpireIn or refreshTokensExpireIn methods.

<a name=“creating-a-personal-access-client”></a>

30.8.1 Creating A Personal Access Client

Before your application can issue personal access tokens, you will need to create a personal access client. You may do this using the passport:client command with the --personal option. If you have already run the passport:install command, you do not need to run this command:

php artisan passport:client --personal

<a name=“managing-personal-access-tokens”></a>

30.8.2 Managing Personal Access Tokens

Once you have created a personal access client, you may issue tokens for a given user using the createToken method on the User model instance. The createToken method accepts the name of the token as its first argument and an optional array of scopes as its second argument:

$user = App\User::find(1);

// Creating a token without scopes...
$token = $user->createToken('Token Name')->accessToken;

// Creating a token with scopes...
$token = $user->createToken('My Token', ['place-orders'])->accessToken;

30.8.2.1 JSON API

Passport also includes a JSON API for managing personal access tokens. You may pair this with your own frontend to offer your users a dashboard for managing personal access tokens. Below, we’ll review all of the API endpoints for managing personal access tokens. For convenience, we’ll use Axios to demonstrate making HTTP requests to the endpoints.

{tip} If you don’t want to implement the personal access token frontend yourself, you can use the frontend quickstart to have a fully functional frontend in a matter of minutes.

30.8.2.2 GET /oauth/scopes

This route returns all of the scopes defined for your application. You may use this route to list the scopes a user may assign to a personal access token:

axios.get('/oauth/scopes')
    .then(response => {
        console.log(response.data);
    });

30.8.2.3 GET /oauth/personal-access-tokens

This route returns all of the personal access tokens that the authenticated user has created. This is primarily useful for listing all of the user’s tokens so that they may edit or delete them:

axios.get('/oauth/personal-access-tokens')
    .then(response => {
        console.log(response.data);
    });

30.8.2.4 POST /oauth/personal-access-tokens

This route creates new personal access tokens. It requires two pieces of data: the token’s name and the scopes that should be assigned to the token:

const data = {
    name: 'Token Name',
    scopes: []
};

axios.post('/oauth/personal-access-tokens', data)
    .then(response => {
        console.log(response.data.accessToken);
    })
    .catch (response => {
        // List errors on response...
    });

30.8.2.5 DELETE /oauth/personal-access-tokens/{token-id}

This route may be used to delete personal access tokens:

axios.delete('/oauth/personal-access-tokens/' + tokenId);

<a name=“protecting-routes”></a>

30.9 Protecting Routes

<a name=“via-middleware”></a>

30.9.1 Via Middleware

Passport includes an authentication guard that will validate access tokens on incoming requests. Once you have configured the api guard to use the passport driver, you only need to specify the auth:api middleware on any routes that require a valid access token:

Route::get('/user', function () {
    //
})->middleware('auth:api');

<a name=“passing-the-access-token”></a>

30.9.2 Passing The Access Token

When calling routes that are protected by Passport, your application’s API consumers should specify their access token as a Bearer token in the Authorization header of their request. For example, when using the Guzzle HTTP library:

$response = $client->request('GET', '/api/user', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

<a name=“token-scopes”></a>

30.10 Token Scopes

<a name=“defining-scopes”></a>

30.10.1 Defining Scopes

Scopes allow your API clients to request a specific set of permissions when requesting authorization to access an account. For example, if you are building an e-commerce application, not all API consumers will need the ability to place orders. Instead, you may allow the consumers to only request authorization to access order shipment statuses. In other words, scopes allow your application’s users to limit the actions a third-party application can perform on their behalf.

You may define your API’s scopes using the Passport::tokensCan method in the boot method of your AuthServiceProvider. The tokensCan method accepts an array of scope names and scope descriptions. The scope description may be anything you wish and will be displayed to users on the authorization approval screen:

use Laravel\Passport\Passport;

Passport::tokensCan([
    'place-orders' => 'Place orders',
    'check-status' => 'Check order status',
]);

<a name=“assigning-scopes-to-tokens”></a>

30.10.2 Assigning Scopes To Tokens

30.10.2.1 When Requesting Authorization Codes

When requesting an access token using the authorization code grant, consumers should specify their desired scopes as the scope query string parameter. The scope parameter should be a space-delimited list of scopes:

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => 'http://example.com/callback',
        'response_type' => 'code',
        'scope' => 'place-orders check-status',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

30.10.2.2 When Issuing Personal Access Tokens

If you are issuing personal access tokens using the User model’s createToken method, you may pass the array of desired scopes as the second argument to the method:

$token = $user->createToken('My Token', ['place-orders'])->accessToken;

<a name=“checking-scopes”></a>

30.10.3 Checking Scopes

Passport includes two middleware that may be used to verify that an incoming request is authenticated with a token that has been granted a given scope. To get started, add the following middleware to the $routeMiddleware property of your app/Http/Kernel.php file:

'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,

30.10.3.1 Check For All Scopes

The scopes middleware may be assigned to a route to verify that the incoming request’s access token has all of the listed scopes:

Route::get('/orders', function () {
    // Access token has both "check-status" and "place-orders" scopes...
})->middleware('scopes:check-status,place-orders');

30.10.3.2 Check For Any Scopes

The scope middleware may be assigned to a route to verify that the incoming request’s access token has at least one of the listed scopes:

Route::get('/orders', function () {
    // Access token has either "check-status" or "place-orders" scope...
})->middleware('scope:check-status,place-orders');

30.10.3.3 Checking Scopes On A Token Instance

Once an access token authenticated request has entered your application, you may still check if the token has a given scope using the tokenCan method on the authenticated User instance:

use Illuminate\Http\Request;

Route::get('/orders', function (Request $request) {
    if ($request->user()->tokenCan('place-orders')) {
        //
    }
});

<a name=“consuming-your-api-with-javascript”></a>

30.11 Consuming Your API With JavaScript

When building an API, it can be extremely useful to be able to consume your own API from your JavaScript application. This approach to API development allows your own application to consume the same API that you are sharing with the world. The same API may be consumed by your web application, mobile applications, third-party applications, and any SDKs that you may publish on various package managers.

Typically, if you want to consume your API from your JavaScript application, you would need to manually send an access token to the application and pass it with each request to your application. However, Passport includes a middleware that can handle this for you. All you need to do is add the CreateFreshApiToken middleware to your web middleware group:

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

This Passport middleware will attach a laravel_token cookie to your outgoing responses. This cookie contains an encrypted JWT that Passport will use to authenticate API requests from your JavaScript application. Now, you may make requests to your application’s API without explicitly passing an access token:

axios.get('/api/user')
    .then(response => {
        console.log(response.data);
    });

When using this method of authentication, Axios will automatically send the X-CSRF-TOKEN header. In addition, the default Laravel JavaScript scaffolding instructs Axios to send the X-Requested-With header:

window.axios.defaults.headers.common = {
    'X-Requested-With': 'XMLHttpRequest',
};

{note} If you are using a different JavaScript framework, you should make sure it is configured to send the X-CSRF-TOKEN and X-Requested-With headers with every outgoing request.

<a name=“events”></a>

30.12 Events

Passport raises events when issuing access tokens and refresh tokens. You may use these events to prune or revoke other access tokens in your database. You may attach listeners to these events in your application’s EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Laravel\Passport\Events\AccessTokenCreated' => [
        'App\Listeners\RevokeOldTokens',
    ],

    'Laravel\Passport\Events\RefreshTokenCreated' => [
        'App\Listeners\PruneOldTokens',
    ],
];

<a name=“testing”></a>

30.13 Testing

Passport’s actingAs method may be used to specify the currently authenticated user as well as its scopes. The first argument given to the actingAs method is the user instance and the second is an array of scopes that should be granted to the user’s token:

public function testServerCreation()
{
    Passport::actingAs(
        factory(User::class)->create(),
        ['create-servers']
    );

    $response = $this->post('/api/create-server');

    $response->assertStatus(200);
}

31 Authorization

<a name=“introduction”></a>

31.1 Introduction

In addition to providing authentication services out of the box, Laravel also provides a simple way to authorize user actions against a given resource. Like authentication, Laravel’s approach to authorization is simple, and there are two primary ways of authorizing actions: gates and policies.

Think of gates and policies like routes and controllers. Gates provide a simple, Closure based approach to authorization while policies, like controllers, group their logic around a particular model or resource. We’ll explore gates first and then examine policies.

You do not need to choose between exclusively using gates or exclusively using policies when building an application. Most applications will most likely contain a mixture of gates and policies, and that is perfectly fine! Gates are most applicable to actions which are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.

<a name=“gates”></a>

31.2 Gates

<a name=“writing-gates”></a>

31.2.1 Writing Gates

Gates are Closures that determine if a user is authorized to perform a given action and are typically defined in the App\Providers\AuthServiceProvider class using the Gate facade. Gates always receive a user instance as their first argument, and may optionally receive additional arguments such as a relevant Eloquent model:

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Gate::define('update-post', function ($user, $post) {
        return $user->id == $post->user_id;
    });
}

Gates may also be defined using a Class@method style callback string, like controllers:

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    Gate::define('update-post', 'PostPolicy@update');
}

31.2.1.1 Resource Gates

You may also define multiple Gate abilities at once using the resource method:

Gate::resource('posts', 'PostPolicy');

This is identical to manually defining the following Gate definitions:

Gate::define('posts.view', 'PostPolicy@view');
Gate::define('posts.create', 'PostPolicy@create');
Gate::define('posts.update', 'PostPolicy@update');
Gate::define('posts.delete', 'PostPolicy@delete');

By default, the view, create, update, and delete abilities will be defined. You may override or add to the default abilities by passing an array as a third argument to the resource method. The keys of the array define the names of the abilities while the values define the method names. For example, the following code will create two new Gate definitions - posts.image and posts.photo:

Gate::resource('posts', 'PostPolicy', [
    'image' => 'updateImage',
    'photo' => 'updatePhoto',
]);

<a name=“authorizing-actions-via-gates”></a>

31.2.2 Authorizing Actions

To authorize an action using gates, you should use the allows or denies methods. Note that you are not required to pass the currently authenticated user to these methods. Laravel will automatically take care of passing the user into the gate Closure:

if (Gate::allows('update-post', $post)) {
    // The current user can update the post...
}

if (Gate::denies('update-post', $post)) {
    // The current user can't update the post...
}

If you would like to determine if a particular user is authorized to perform an action, you may use the forUser method on the Gate facade:

if (Gate::forUser($user)->allows('update-post', $post)) {
    // The user can update the post...
}

if (Gate::forUser($user)->denies('update-post', $post)) {
    // The user can't update the post...
}

<a name=“creating-policies”></a>

31.3 Creating Policies

<a name=“generating-policies”></a>

31.3.1 Generating Policies

Policies are classes that organize authorization logic around a particular model or resource. For example, if your application is a blog, you may have a Post model and a corresponding PostPolicy to authorize user actions such as creating or updating posts.

You may generate a policy using the make:policy artisan command. The generated policy will be placed in the app/Policies directory. If this directory does not exist in your application, Laravel will create it for you:

php artisan make:policy PostPolicy

The make:policy command will generate an empty policy class. If you would like to generate a class with the basic “CRUD” policy methods already included in the class, you may specify a --model when executing the command:

php artisan make:policy PostPolicy --model=Post

{tip} All policies are resolved via the Laravel service container, allowing you to type-hint any needed dependencies in the policy’s constructor to have them automatically injected.

<a name=“registering-policies”></a>

31.3.2 Registering Policies

Once the policy exists, it needs to be registered. The AuthServiceProvider included with fresh Laravel applications contains a policies property which maps your Eloquent models to their corresponding policies. Registering a policy will instruct Laravel which policy to utilize when authorizing actions against a given model:

<?php

namespace App\Providers;

use App\Post;
use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Post::class => PostPolicy::class,
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

<a name=“writing-policies”></a>

31.4 Writing Policies

<a name=“policy-methods”></a>

31.4.1 Policy Methods

Once the policy has been registered, you may add methods for each action it authorizes. For example, let’s define an update method on our PostPolicy which determines if a given User can update a given Post instance.

The update method will receive a User and a Post instance as its arguments, and should return true or false indicating whether the user is authorized to update the given Post. So, for this example, let’s verify that the user’s id matches the user_id on the post:

<?php

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

You may continue to define additional methods on the policy as needed for the various actions it authorizes. For example, you might define view or delete methods to authorize various Post actions, but remember you are free to give your policy methods any name you like.

{tip} If you used the --model option when generating your policy via the Artisan console, it will already contain methods for the view, create, update, and delete actions.

<a name=“methods-without-models”></a>

31.4.2 Methods Without Models

Some policy methods only receive the currently authenticated user and not an instance of the model they authorize. This situation is most common when authorizing create actions. For example, if you are creating a blog, you may wish to check if a user is authorized to create any posts at all.

When defining policy methods that will not receive a model instance, such as a create method, it will not receive a model instance. Instead, you should define the method as only expecting the authenticated user:

/**
 * Determine if the given user can create posts.
 *
 * @param  \App\User  $user
 * @return bool
 */
public function create(User $user)
{
    //
}

<a name=“policy-filters”></a>

31.4.3 Policy Filters

For certain users, you may wish to authorize all actions within a given policy. To accomplish this, define a before method on the policy. The before method will be executed before any other methods on the policy, giving you an opportunity to authorize the action before the intended policy method is actually called. This feature is most commonly used for authorizing application administrators to perform any action:

public function before($user, $ability)
{
    if ($user->isSuperAdmin()) {
        return true;
    }
}

If you would like to deny all authorizations for a user you should return false from the before method. If null is returned, the authorization will fall through to the policy method.

<a name=“authorizing-actions-using-policies”></a>

31.5 Authorizing Actions Using Policies

<a name=“via-the-user-model”></a>

31.5.1 Via The User Model

The User model that is included with your Laravel application includes two helpful methods for authorizing actions: can and cant. The can method receives the action you wish to authorize and the relevant model. For example, let’s determine if a user is authorized to update a given Post model:

if ($user->can('update', $post)) {
    //
}

If a policy is registered for the given model, the can method will automatically call the appropriate policy and return the boolean result. If no policy is registered for the model, the can method will attempt to call the Closure based Gate matching the given action name.

31.5.1.1 Actions That Don’t Require Models

Remember, some actions like create may not require a model instance. In these situations, you may pass a class name to the can method. The class name will be used to determine which policy to use when authorizing the action:

use App\Post;

if ($user->can('create', Post::class)) {
    // Executes the "create" method on the relevant policy...
}

<a name=“via-middleware”></a>

31.5.2 Via Middleware

Laravel includes a middleware that can authorize actions before the incoming request even reaches your routes or controllers. By default, the Illuminate\Auth\Middleware\Authorize middleware is assigned the can key in your App\Http\Kernel class. Let’s explore an example of using the can middleware to authorize that a user can update a blog post:

use App\Post;

Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post');

In this example, we’re passing the can middleware two arguments. The first is the name of the action we wish to authorize and the second is the route parameter we wish to pass to the policy method. In this case, since we are using implicit model binding, a Post model will be passed to the policy method. If the user is not authorized to perform the given action, a HTTP response with a 403 status code will be generated by the middleware.

31.5.2.1 Actions That Don’t Require Models

Again, some actions like create may not require a model instance. In these situations, you may pass a class name to the middleware. The class name will be used to determine which policy to use when authorizing the action:

Route::post('/post', function () {
    // The current user may create posts...
})->middleware('can:create,App\Post');

<a name=“via-controller-helpers”></a>

31.5.3 Via Controller Helpers

In addition to helpful methods provided to the User model, Laravel provides a helpful authorize method to any of your controllers which extend the App\Http\Controllers\Controller base class. Like the can method, this method accepts the name of the action you wish to authorize and the relevant model. If the action is not authorized, the authorize method will throw an Illuminate\Auth\Access\AuthorizationException, which the default Laravel exception handler will convert to an HTTP response with a 403 status code:

<?php

namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Update the given blog post.
     *
     * @param  Request  $request
     * @param  Post  $post
     * @return Response
     */
    public function update(Request $request, Post $post)
    {
        $this->authorize('update', $post);

        // The current user can update the blog post...
    }
}

31.5.3.1 Actions That Don’t Require Models

As previously discussed, some actions like create may not require a model instance. In these situations, you may pass a class name to the authorize method. The class name will be used to determine which policy to use when authorizing the action:

/**
 * Create a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function create(Request $request)
{
    $this->authorize('create', Post::class);

    // The current user can create blog posts...
}

<a name=“via-blade-templates”></a>

31.5.4 Via Blade Templates

When writing Blade templates, you may wish to display a portion of the page only if the user is authorized to perform a given action. For example, you may wish to show an update form for a blog post only if the user can actually update the post. In this situation, you may use the @can and @cannot family of directives:

@can('update', $post)
    <!-- The Current User Can Update The Post -->
@elsecan('create', $post)
    <!-- The Current User Can Create New Post -->
@endcan

@cannot('update', $post)
    <!-- The Current User Can't Update The Post -->
@elsecannot('create', $post)
    <!-- The Current User Can't Create New Post -->
@endcannot

These directives are convenient shortcuts for writing @if and @unless statements. The @can and @cannot statements above respectively translate to the following statements:

@if (Auth::user()->can('update', $post))
    <!-- The Current User Can Update The Post -->
@endif

@unless (Auth::user()->can('update', $post))
    <!-- The Current User Can't Update The Post -->
@endunless

31.5.4.1 Actions That Don’t Require Models

Like most of the other authorization methods, you may pass a class name to the @can and @cannot directives if the action does not require a model instance:

@can('create', App\Post::class)
    <!-- The Current User Can Create Posts -->
@endcan

@cannot('create', App\Post::class)
    <!-- The Current User Can't Create Posts -->
@endcannot

32 Encryption

<a name=“introduction”></a>

32.1 Introduction

Laravel’s encrypter uses OpenSSL to provide AES-256 and AES-128 encryption. You are strongly encouraged to use Laravel’s built-in encryption facilities and not attempt to roll your own “home grown” encryption algorithms. All of Laravel’s encrypted values are signed using a message authentication code (MAC) so that their underlying value can not be modified once encrypted.

<a name=“configuration”></a>

32.2 Configuration

Before using Laravel’s encrypter, you must set a key option in your config/app.php configuration file. You should use the php artisan key:generate command to generate this key since this Artisan command will use PHP’s secure random bytes generator to build your key. If this value is not properly set, all values encrypted by Laravel will be insecure.

<a name=“using-the-encrypter”></a>

32.3 Using The Encrypter

32.3.0.1 Encrypting A Value

You may encrypt a value using the encrypt helper. All encrypted values are encrypted using OpenSSL and the AES-256-CBC cipher. Furthermore, all encrypted values are signed with a message authentication code (MAC) to detect any modifications to the encrypted string:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Store a secret message for the user.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function storeSecret(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $user->fill([
            'secret' => encrypt($request->secret)
        ])->save();
    }
}

32.3.0.2 Encrypting Without Serialization

Encrypted values are passed through serialize during encryption, which allows for encryption of objects and arrays. Thus, non-PHP clients receiving encrypted values will need to unserialize the data. If you would like to encrypt and decrypt values without serialization, you may use the encryptString and decryptString methods of the Crypt facade:

use Illuminate\Support\Facades\Crypt;

$encrypted = Crypt::encryptString('Hello world.');

$decrypted = Crypt::decryptString($encrypted);

32.3.0.3 Decrypting A Value

You may decrypt values using the decrypt helper. If the value can not be properly decrypted, such as when the MAC is invalid, an Illuminate\Contracts\Encryption\DecryptException will be thrown:

use Illuminate\Contracts\Encryption\DecryptException;

try {
    $decrypted = decrypt($encryptedValue);
} catch (DecryptException $e) {
    //
}

33 Hashing

<a name=“introduction”></a>

33.1 Introduction

The Laravel Hash facade provides secure Bcrypt hashing for storing user passwords. If you are using the built-in LoginController and RegisterController classes that are included with your Laravel application, they will automatically use Bcrypt for registration and authentication.

{tip} Bcrypt is a great choice for hashing passwords because its “work factor” is adjustable, which means that the time it takes to generate a hash can be increased as hardware power increases.

<a name=“basic-usage”></a>

33.2 Basic Usage

You may hash a password by calling the make method on the Hash facade:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;

class UpdatePasswordController extends Controller
{
    /**
     * Update the password for the user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        // Validate the new password length...

        $request->user()->fill([
            'password' => Hash::make($request->newPassword)
        ])->save();
    }
}

The make method also allows you to manage the work factor of the bcrypt hashing algorithm using the rounds option; however, the default is acceptable for most applications:

$hashed = Hash::make('password', [
    'rounds' => 12
]);

33.2.0.1 Verifying A Password Against A Hash

The check method allows you to verify that a given plain-text string corresponds to a given hash. However, if you are using the LoginController included with Laravel, you will probably not need to use this directly, as this controller automatically calls this method:

if (Hash::check('plain-text', $hashedPassword)) {
    // The passwords match...
}

33.2.0.2 Checking If A Password Needs To Be Rehashed

The needsRehash function allows you to determine if the work factor used by the hasher has changed since the password was hashed:

if (Hash::needsRehash($hashed)) {
    $hashed = Hash::make('plain-text');
}

34 Resetting Passwords

<a name=“introduction”></a>

34.1 Introduction

{tip} Want to get started fast? Just run php artisan make:auth in a fresh Laravel application and navigate your browser to http://your-app.dev/register or any other URL that is assigned to your application. This single command will take care of scaffolding your entire authentication system, including resetting passwords!

Most web applications provide a way for users to reset their forgotten passwords. Rather than forcing you to re-implement this on each application, Laravel provides convenient methods for sending password reminders and performing password resets.

{note} Before using the password reset features of Laravel, your user must use the Illuminate\Notifications\Notifiable trait.

<a name=“resetting-database”></a>

34.2 Database Considerations

To get started, verify that your App\User model implements the Illuminate\Contracts\Auth\CanResetPassword contract. Of course, the App\User model included with the framework already implements this interface, and uses the Illuminate\Auth\Passwords\CanResetPassword trait to include the methods needed to implement the interface.

34.2.0.1 Generating The Reset Token Table Migration

Next, a table must be created to store the password reset tokens. The migration for this table is included with Laravel out of the box, and resides in the database/migrations directory. So, all you need to do is run your database migrations:

php artisan migrate

<a name=“resetting-routing”></a>

34.3 Routing

Laravel includes Auth\ForgotPasswordController and Auth\ResetPasswordController classes that contains the logic necessary to e-mail password reset links and reset user passwords. All of the routes needed to perform password resets may be generated using the make:auth Artisan command:

php artisan make:auth

<a name=“resetting-views”></a>

34.4 Views

Again, Laravel will generate all of the necessary views for password reset when the make:auth command is executed. These views are placed in resources/views/auth/passwords. You are free to customize them as needed for your application.

<a name=“after-resetting-passwords”></a>

34.5 After Resetting Passwords

Once you have defined the routes and views to reset your user’s passwords, you may simply access the route in your browser at /password/reset. The ForgotPasswordController included with the framework already includes the logic to send the password reset link e-mails, while the ResetPasswordController includes the logic to reset user passwords.

After a password is reset, the user will automatically be logged into the application and redirected to /home. You can customize the post password reset redirect location by defining a redirectTo property on the ResetPasswordController:

protected $redirectTo = '/dashboard';

{note} By default, password reset tokens expire after one hour. You may change this via the password reset expire option in your config/auth.php file.

<a name=“password-customization”></a>

34.6 Customization

34.6.0.1 Authentication Guard Customization

In your auth.php configuration file, you may configure multiple “guards”, which may be used to define authentication behavior for multiple user tables. You can customize the included ResetPasswordController to use the guard of your choice by overriding the guard method on the controller. This method should return a guard instance:

use Illuminate\Support\Facades\Auth;

protected function guard()
{
    return Auth::guard('guard-name');
}

34.6.0.2 Password Broker Customization

In your auth.php configuration file, you may configure multiple password “brokers”, which may be used to reset passwords on multiple user tables. You can customize the included ForgotPasswordController and ResetPasswordController to use the broker of your choice by overriding the broker method:

use Illuminate\Support\Facades\Password;

/**
 * Get the broker to be used during password reset.
 *
 * @return PasswordBroker
 */
protected function broker()
{
    return Password::broker('name');
}

34.6.0.3 Reset Email Customization

You may easily modify the notification class used to send the password reset link to the user. To get started, override the sendPasswordResetNotification method on your User model. Within this method, you may send the notification using any notification class you choose. The password reset $token is the first argument received by the method:

/**
 * Send the password reset notification.
 *
 * @param  string  $token
 * @return void
 */
public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}

35 Artisan Console

<a name=“introduction”></a>

35.1 Introduction

Artisan is the command-line interface included with Laravel. It provides a number of helpful commands that can assist you while you build your application. To view a list of all available Artisan commands, you may use the list command:

php artisan list

Every command also includes a “help” screen which displays and describes the command’s available arguments and options. To view a help screen, simply precede the name of the command with help:

php artisan help migrate

35.1.0.1 Laravel REPL

All Laravel applications include Tinker, a REPL powered by the PsySH package. Tinker allows you to interact with your entire Laravel application on the command line, including the Eloquent ORM, jobs, events, and more. To enter the Tinker environment, run the tinker Artisan command:

php artisan tinker

<a name=“writing-commands”></a>

35.2 Writing Commands

In addition to the commands provided with Artisan, you may also build your own custom commands. Commands are typically stored in the app/Console/Commands directory; however, you are free to choose your own storage location as long as your commands can be loaded by Composer.

<a name=“generating-commands”></a>

35.2.1 Generating Commands

To create a new command, use the make:command Artisan command. This command will create a new command class in the app/Console/Commands directory. Don’t worry if this directory does not exist in your application, since it will be created the first time you run the make:command Artisan command. The generated command will include the default set of properties and methods that are present on all commands:

php artisan make:command SendEmails

<a name=“command-structure”></a>

35.2.2 Command Structure

After generating your command, you should fill in the signature and description properties of the class, which will be used when displaying your command on the list screen. The handle method will be called when your command is executed. You may place your command logic in this method.

{tip} For greater code reuse, it is good practice to keep your console commands light and let them defer to application services to accomplish their tasks. In the example below, note that we inject a service class to do the “heavy lifting” of sending the e-mails.

Let’s take a look at an example command. Note that we are able to inject any dependencies we need into the command’s constructor. The Laravel service container will automatically inject all dependencies type-hinted in the constructor:

<?php

namespace App\Console\Commands;

use App\User;
use App\DripEmailer;
use Illuminate\Console\Command;

class SendEmails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email:send {user}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send drip e-mails to a user';

    /**
     * The drip e-mail service.
     *
     * @var DripEmailer
     */
    protected $drip;

    /**
     * Create a new command instance.
     *
     * @param  DripEmailer  $drip
     * @return void
     */
    public function __construct(DripEmailer $drip)
    {
        parent::__construct();

        $this->drip = $drip;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->drip->send(User::find($this->argument('user')));
    }
}

<a name=“closure-commands”></a>

35.2.3 Closure Commands

Closure based commands provide an alternative to defining console commands as classes. In the same way that route Closures are an alternative to controllers, think of command Closures as an alternative to command classes. Within the commands method of your app/Console/Kernel.php file, Laravel loads the routes/console.php file:

/**
 * Register the Closure based commands for the application.
 *
 * @return void
 */
protected function commands()
{
    require base_path('routes/console.php');
}

Even though this file does not define HTTP routes, it defines console based entry points (routes) into your application. Within this file, you may define all of your Closure based routes using the Artisan::command method. The command method accepts two arguments: the command signature and a Closure which receives the commands arguments and options:

Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
});

The Closure is bound to the underlying command instance, so you have full access to all of the helper methods you would typically be able to access on a full command class.

35.2.3.1 Type-Hinting Dependencies

In addition to receiving your command’s arguments and options, command Closures may also type-hint additional dependencies that you would like resolved out of the service container:

use App\User;
use App\DripEmailer;

Artisan::command('email:send {user}', function (DripEmailer $drip, $user) {
    $drip->send(User::find($user));
});

35.2.3.2 Closure Command Descriptions

When defining a Closure based command, you may use the describe method to add a description to the command. This description will be displayed when you run the php artisan list or php artisan help commands:

Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
})->describe('Build the project');

<a name=“defining-input-expectations”></a>

35.3 Defining Input Expectations

When writing console commands, it is common to gather input from the user through arguments or options. Laravel makes it very convenient to define the input you expect from the user using the signature property on your commands. The signature property allows you to define the name, arguments, and options for the command in a single, expressive, route-like syntax.

<a name=“arguments”></a>

35.3.1 Arguments

All user supplied arguments and options are wrapped in curly braces. In the following example, the command defines one required argument: user:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send {user}';

You may also make arguments optional and define default values for arguments:

// Optional argument...
email:send {user?}

// Optional argument with default value...
email:send {user=foo}

<a name=“options”></a>

35.3.2 Options

Options, like arguments, are another form of user input. Options are prefixed by two hyphens (--) when they are specified on the command line. There are two types of options: those that receive a value and those that don’t. Options that don’t receive a value serve as a boolean “switch”. Let’s take a look at an example of this type of option:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send {user} {--queue}';

In this example, the --queue switch may be specified when calling the Artisan command. If the --queue switch is passed, the value of the option will be true. Otherwise, the value will be false:

php artisan email:send 1 --queue

<a name=“options-with-values”></a>

35.3.2.1 Options With Values

Next, let’s take a look at an option that expects a value. If the user must specify a value for an option, suffix the option name with a = sign:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send {user} {--queue=}';

In this example, the user may pass a value for the option like so:

php artisan email:send 1 --queue=default

You may assign default values to options by specifying the default value after the option name. If no option value is passed by the user, the default value will be used:

email:send {user} {--queue=default}

<a name=“option-shortcuts”></a>

35.3.2.2 Option Shortcuts

To assign a shortcut when defining an option, you may specify it before the option name and use a | delimiter to separate the shortcut from the full option name:

email:send {user} {--Q|queue}

<a name=“input-arrays”></a>

35.3.3 Input Arrays

If you would like to define arguments or options to expect array inputs, you may use the * character. First, let’s take a look at an example that specifies an array argument:

email:send {user*}

When calling this method, the user arguments may be passed in order to the command line. For example, the following command will set the value of user to ['foo', 'bar']:

php artisan email:send foo bar

When defining an option that expects an array input, each option value passed to the command should be prefixed with the option name:

email:send {user} {--id=*}

php artisan email:send --id=1 --id=2

<a name=“input-descriptions”></a>

35.3.4 Input Descriptions

You may assign descriptions to input arguments and options by separating the parameter from the description using a colon. If you need a little extra room to define your command, feel free to spread the definition across multiple lines:

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'email:send
                        {user : The ID of the user}
                        {--queue= : Whether the job should be queued}';

<a name=“command-io”></a>

35.4 Command I/O

<a name=“retrieving-input”></a>

35.4.1 Retrieving Input

While your command is executing, you will obviously need to access the values for the arguments and options accepted by your command. To do so, you may use the argument and option methods:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $userId = $this->argument('user');

    //
}

If you need to retrieve all of the arguments as an array, call the arguments method:

$arguments = $this->arguments();

Options may be retrieved just as easily as arguments using the option method. To retrieve all of the options as an array, call the options method:

// Retrieve a specific option...
$queueName = $this->option('queue');

// Retrieve all options...
$options = $this->options();

If the argument or option does not exist, null will be returned.

<a name=“prompting-for-input”></a>

35.4.2 Prompting For Input

In addition to displaying output, you may also ask the user to provide input during the execution of your command. The ask method will prompt the user with the given question, accept their input, and then return the user’s input back to your command:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $name = $this->ask('What is your name?');
}

The secret method is similar to ask, but the user’s input will not be visible to them as they type in the console. This method is useful when asking for sensitive information such as a password:

$password = $this->secret('What is the password?');

35.4.2.1 Asking For Confirmation

If you need to ask the user for a simple confirmation, you may use the confirm method. By default, this method will return false. However, if the user enters y or yes in response to the prompt, the method will return true.

if ($this->confirm('Do you wish to continue?')) {
    //
}

35.4.2.2 Auto-Completion

The anticipate method can be used to provide auto-completion for possible choices. The user can still choose any answer, regardless of the auto-completion hints:

$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

35.4.2.3 Multiple Choice Questions

If you need to give the user a predefined set of choices, you may use the choice method. You may set the default value to be returned if no option is chosen:

$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $default);

<a name=“writing-output”></a>

35.4.3 Writing Output

To send output to the console, use the line, info, comment, question and error methods. Each of these methods will use appropriate ANSI colors for their purpose. For example, let’s display some general information to the user. Typically, the info method will display in the console as green text:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $this->info('Display this on the screen');
}

To display an error message, use the error method. Error message text is typically displayed in red:

$this->error('Something went wrong!');

If you would like to display plain, uncolored console output, use the line method:

$this->line('Display this on the screen');

35.4.3.1 Table Layouts

The table method makes it easy to correctly format multiple rows / columns of data. Just pass in the headers and rows to the method. The width and height will be dynamically calculated based on the given data:

$headers = ['Name', 'Email'];

$users = App\User::all(['name', 'email'])->toArray();

$this->table($headers, $users);

35.4.3.2 Progress Bars

For long running tasks, it could be helpful to show a progress indicator. Using the output object, we can start, advance and stop the Progress Bar. First, define the total number of steps the process will iterate through. Then, advance the Progress Bar after processing each item:

$users = App\User::all();

$bar = $this->output->createProgressBar(count($users));

foreach ($users as $user) {
    $this->performTask($user);

    $bar->advance();
}

$bar->finish();

For more advanced options, check out the Symfony Progress Bar component documentation.

<a name=“registering-commands”></a>

35.5 Registering Commands

Because of the load method call in your console kernel’s commands method, all commands within the app/Console/Commands directory will automatically be registered with Artisan. In fact, you are free to make additional calls to the load method to scan other directories for Artisan commands:

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $this->load(__DIR__.'/Commands');
    $this->load(__DIR__.'/MoreCommands');

    // ...
}

You may also manually register commands by adding its class name to the $command property of your app/Console/Kernel.php file. When Artisan boots, all the commands listed in this property will be resolved by the service container and registered with Artisan:

protected $commands = [
    Commands\SendEmails::class
];

<a name=“programmatically-executing-commands”></a>

35.6 Programmatically Executing Commands

Sometimes you may wish to execute an Artisan command outside of the CLI. For example, you may wish to fire an Artisan command from a route or controller. You may use the call method on the Artisan facade to accomplish this. The call method accepts the name of the command as the first argument, and an array of command parameters as the second argument. The exit code will be returned:

Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
});

Using the queue method on the Artisan facade, you may even queue Artisan commands so they are processed in the background by your queue workers. Before using this method, make sure you have configured your queue and are running a queue listener:

Route::get('/foo', function () {
    Artisan::queue('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
});

35.6.0.1 Passing Array Values

If your command defines an option that accepts an array, you may simply pass an array of values to that option:

Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
        'user' => 1, '--id' => [5, 13]
    ]);
});

35.6.0.2 Passing Boolean Values

If you need to specify the value of an option that does not accept string values, such as the --force flag on the migrate:refresh command, you should pass true or false:

$exitCode = Artisan::call('migrate:refresh', [
    '--force' => true,
]);

<a name=“calling-commands-from-other-commands”></a>

35.6.1 Calling Commands From Other Commands

Sometimes you may wish to call other commands from an existing Artisan command. You may do so using the call method. This call method accepts the command name and an array of command parameters:

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $this->call('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
}

If you would like to call another console command and suppress all of its output, you may use the callSilent method. The callSilent method has the same signature as the call method:

$this->callSilent('email:send', [
    'user' => 1, '--queue' => 'default'
]);

36 Broadcasting

<a name=“introduction”></a>

36.1 Introduction

In many modern web applications, WebSockets are used to implement realtime, live-updating user interfaces. When some data is updated on the server, a message is typically sent over a WebSocket connection to be handled by the client. This provides a more robust, efficient alternative to continually polling your application for changes.

To assist you in building these types of applications, Laravel makes it easy to “broadcast” your events over a WebSocket connection. Broadcasting your Laravel events allows you to share the same event names between your server-side code and your client-side JavaScript application.

{tip} Before diving into event broadcasting, make sure you have read all of the documentation regarding Laravel events and listeners.

<a name=“configuration”></a>

36.1.1 Configuration

All of your application’s event broadcasting configuration is stored in the config/broadcasting.php configuration file. Laravel supports several broadcast drivers out of the box: Pusher, Redis, and a log driver for local development and debugging. Additionally, a null driver is included which allows you to totally disable broadcasting. A configuration example is included for each of these drivers in the config/broadcasting.php configuration file.

36.1.1.1 Broadcast Service Provider

Before broadcasting any events, you will first need to register the App\Providers\BroadcastServiceProvider. In fresh Laravel applications, you only need to uncomment this provider in the providers array of your config/app.php configuration file. This provider will allow you to register the broadcast authorization routes and callbacks.

36.1.1.2 CSRF Token

Laravel Echo will need access to the current session’s CSRF token. You should verify that your application’s head HTML element defines a meta tag containing the CSRF token:

<meta name="csrf-token" content="{{ csrf_token() }}">

<a name=“driver-prerequisites”></a>

36.1.2 Driver Prerequisites

36.1.2.1 Pusher

If you are broadcasting your events over Pusher, you should install the Pusher PHP SDK using the Composer package manager:

composer require pusher/pusher-php-server "~3.0"

Next, you should configure your Pusher credentials in the config/broadcasting.php configuration file. An example Pusher configuration is already included in this file, allowing you to quickly specify your Pusher key, secret, and application ID. The config/broadcasting.php file’s pusher configuration also allows you to specify additional options that are supported by Pusher, such as the cluster:

'options' => [
    'cluster' => 'eu',
    'encrypted' => true
],

When using Pusher and Laravel Echo, you should specify pusher as your desired broadcaster when instantiating the Echo instance in your resources/assets/js/bootstrap.js file:

import Echo from "laravel-echo"

window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key'
});

36.1.2.2 Redis

If you are using the Redis broadcaster, you should install the Predis library:

composer require predis/predis

The Redis broadcaster will broadcast messages using Redis’ pub / sub feature; however, you will need to pair this with a WebSocket server that can receive the messages from Redis and broadcast them to your WebSocket channels.

When the Redis broadcaster publishes an event, it will be published on the event’s specified channel names and the payload will be a JSON encoded string containing the event name, a data payload, and the user that generated the event’s socket ID (if applicable).

36.1.2.3 Socket.IO

If you are going to pair the Redis broadcaster with a Socket.IO server, you will need to include the Socket.IO JavaScript client library in your application’s head HTML element. When the Socket.IO server is started, it will automatically expose the client JavaScript library at a standard URL. For example, if you are running the Socket.IO server on the same domain as your web application, you may access the client library like so:

<script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>

Next, you will need to instantiate Echo with the socket.io connector and a host.

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});

Finally, you will need to run a compatible Socket.IO server. Laravel does not include a Socket.IO server implementation; however, a community driven Socket.IO server is currently maintained at the tlaverdure/laravel-echo-server GitHub repository.

36.1.2.4 Queue Prerequisites

Before broadcasting events, you will also need to configure and run a queue listener. All event broadcasting is done via queued jobs so that the response time of your application is not seriously affected.

<a name=“concept-overview”></a>

36.2 Concept Overview

Laravel’s event broadcasting allows you to broadcast your server-side Laravel events to your client-side JavaScript application using a driver-based approach to WebSockets. Currently, Laravel ships with Pusher and Redis drivers. The events may be easily consumed on the client-side using the Laravel Echo Javascript package.

Events are broadcast over “channels”, which may be specified as public or private. Any visitor to your application may subscribe to a public channel without any authentication or authorization; however, in order to subscribe to a private channel, a user must be authenticated and authorized to listen on that channel.

<a name=“using-example-application”></a>

36.2.1 Using An Example Application

Before diving into each component of event broadcasting, let’s take a high level overview using an e-commerce store as an example. We won’t discuss the details of configuring Pusher or Laravel Echo since that will be discussed in detail in other sections of this documentation.

In our application, let’s assume we have a page that allows users to view the shipping status for their orders. Let’s also assume that a ShippingStatusUpdated event is fired when a shipping status update is processed by the application:

event(new ShippingStatusUpdated($update));

36.2.1.1 The ShouldBroadcast Interface

When a user is viewing one of their orders, we don’t want them to have to refresh the page to view status updates. Instead, we want to broadcast the updates to the application as they are created. So, we need to mark the ShippingStatusUpdated event with the ShouldBroadcast interface. This will instruct Laravel to broadcast the event when it is fired:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class ShippingStatusUpdated implements ShouldBroadcast
{
    /**
     * Information about the shipping status update.
     *
     * @var string
     */
    public $update;
}

The ShouldBroadcast interface requires our event to define a broadcastOn method. This method is responsible for returning the channels that the event should broadcast on. An empty stub of this method is already defined on generated event classes, so we only need to fill in its details. We only want the creator of the order to be able to view status updates, so we will broadcast the event on a private channel that is tied to the order:

/**
 * Get the channels the event should broadcast on.
 *
 * @return array
 */
public function broadcastOn()
{
    return new PrivateChannel('order.'.$this->update->order_id);
}

36.2.1.2 Authorizing Channels

Remember, users must be authorized to listen on private channels. We may define our channel authorization rules in the routes/channels.php file. In this example, we need to verify that any user attempting to listen on the private order.1 channel is actually the creator of the order:

Broadcast::channel('order.{orderId}', function ($user, $orderId) {
    return $user->id === Order::findOrNew($orderId)->user_id;
});

The channel method accepts two arguments: the name of the channel and a callback which returns true or false indicating whether the user is authorized to listen on the channel.

All authorization callbacks receive the currently authenticated user as their first argument and any additional wildcard parameters as their subsequent arguments. In this example, we are using the {orderId} placeholder to indicate that the “ID” portion of the channel name is a wildcard.

36.2.1.3 Listening For Event Broadcasts

Next, all that remains is to listen for the event in our JavaScript application. We can do this using Laravel Echo. First, we’ll use the private method to subscribe to the private channel. Then, we may use the listen method to listen for the ShippingStatusUpdated event. By default, all of the event’s public properties will be included on the broadcast event:

Echo.private(`order.${orderId}`)
    .listen('ShippingStatusUpdated', (e) => {
        console.log(e.update);
    });

<a name=“defining-broadcast-events”></a>

36.3 Defining Broadcast Events

To inform Laravel that a given event should be broadcast, implement the Illuminate\Contracts\Broadcasting\ShouldBroadcast interface on the event class. This interface is already imported into all event classes generated by the framework so you may easily add it to any of your events.

The ShouldBroadcast interface requires you to implement a single method: broadcastOn. The broadcastOn method should return a channel or array of channels that the event should broadcast on. The channels should be instances of Channel, PrivateChannel, or PresenceChannel. Instances of Channel represent public channels that any user may subscribe to, while PrivateChannels and PresenceChannels represent private channels that require channel authorization:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class ServerCreated implements ShouldBroadcast
{
    use SerializesModels;

    public $user;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('user.'.$this->user->id);
    }
}

Then, you only need to fire the event as you normally would. Once the event has been fired, a queued job will automatically broadcast the event over your specified broadcast driver.

<a name=“broadcast-name”></a>

36.3.1 Broadcast Name

By default, Laravel will broadcast the event using the event’s class name. However, you may customize the broadcast name by defining a broadcastAs method on the event:

/**
 * The event's broadcast name.
 *
 * @return string
 */
public function broadcastAs()
{
    return 'server.created';
}

If you customize the broadcast name using the broadcastAs method, you should make sure to register your listener with a leading . character. This will instruct Echo to not prepend the application’s namespace to the event:

.listen('.server.created', function (e) {
    ....
});

<a name=“broadcast-data”></a>

36.3.2 Broadcast Data

When an event is broadcast, all of its public properties are automatically serialized and broadcast as the event’s payload, allowing you to access any of its public data from your JavaScript application. So, for example, if your event has a single public $user property that contains an Eloquent model, the event’s broadcast payload would be:

{
    "user": {
        "id": 1,
        "name": "Patrick Stewart"
        ...
    }
}

However, if you wish to have more fine-grained control over your broadcast payload, you may add a broadcastWith method to your event. This method should return the array of data that you wish to broadcast as the event payload:

/**
 * Get the data to broadcast.
 *
 * @return array
 */
public function broadcastWith()
{
    return ['id' => $this->user->id];
}

<a name=“broadcast-queue”></a>

36.3.3 Broadcast Queue

By default, each broadcast event is placed on the default queue for the default queue connection specified in your queue.php configuration file. You may customize the queue used by the broadcaster by defining a broadcastQueue property on your event class. This property should specify the name of the queue you wish to use when broadcasting:

/**
 * The name of the queue on which to place the event.
 *
 * @var string
 */
public $broadcastQueue = 'your-queue-name';

If you want to broadcast your event using the sync queue instead of the default queue driver, you can implement the ShouldBroadcastNow interface instead of ShouldBroadcast:

<?php

use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;

class ShippingStatusUpdated implements ShouldBroadcastNow
{
    //
}

<a name=“broadcast-conditions”></a>

36.3.4 Broadcast Conditions

Sometimes you want to broadcast your event only if a given condition is true. You may define these conditions by adding a broadcastWhen method to your event class:

/**
 * Determine if this event should broadcast.
 *
 * @return bool
 */
public function broadcastWhen()
{
    return $this->value > 100;
}

<a name=“authorizing-channels”></a>

36.4 Authorizing Channels

Private channels require you to authorize that the currently authenticated user can actually listen on the channel. This is accomplished by making an HTTP request to your Laravel application with the channel name and allowing your application to determine if the user can listen on that channel. When using Laravel Echo, the HTTP request to authorize subscriptions to private channels will be made automatically; however, you do need to define the proper routes to respond to these requests.

<a name=“defining-authorization-routes”></a>

36.4.1 Defining Authorization Routes

Thankfully, Laravel makes it easy to define the routes to respond to channel authorization requests. In the BroadcastServiceProvider included with your Laravel application, you will see a call to the Broadcast::routes method. This method will register the /broadcasting/auth route to handle authorization requests:

Broadcast::routes();

The Broadcast::routes method will automatically place its routes within the web middleware group; however, you may pass an array of route attributes to the method if you would like to customize the assigned attributes:

Broadcast::routes($attributes);

<a name=“defining-authorization-callbacks”></a>

36.4.2 Defining Authorization Callbacks

Next, we need to define the logic that will actually perform the channel authorization. This is done in the routes/channels.php file that is included with your application. In this file, you may use the Broadcast::channel method to register channel authorization callbacks:

Broadcast::channel('order.{orderId}', function ($user, $orderId) {
    return $user->id === Order::findOrNew($orderId)->user_id;
});

The channel method accepts two arguments: the name of the channel and a callback which returns true or false indicating whether the user is authorized to listen on the channel.

All authorization callbacks receive the currently authenticated user as their first argument and any additional wildcard parameters as their subsequent arguments. In this example, we are using the {orderId} placeholder to indicate that the “ID” portion of the channel name is a wildcard.

36.4.2.1 Authorization Callback Model Binding

Just like HTTP routes, channel routes may also take advantage of implicit and explicit route model binding. For example, instead of receiving the string or numeric order ID, you may request an actual Order model instance:

use App\Order;

Broadcast::channel('order.{order}', function ($user, Order $order) {
    return $user->id === $order->user_id;
});

<a name=“broadcasting-events”></a>

36.5 Broadcasting Events

Once you have defined an event and marked it with the ShouldBroadcast interface, you only need to fire the event using the event function. The event dispatcher will notice that the event is marked with the ShouldBroadcast interface and will queue the event for broadcasting:

event(new ShippingStatusUpdated($update));

<a name=“only-to-others”></a>

36.5.1 Only To Others

When building an application that utilizes event broadcasting, you may substitute the event function with the broadcast function. Like the event function, the broadcast function dispatches the event to your server-side listeners:

broadcast(new ShippingStatusUpdated($update));

However, the broadcast function also exposes the toOthers method which allows you to exclude the current user from the broadcast’s recipients:

broadcast(new ShippingStatusUpdated($update))->toOthers();

To better understand when you may want to use the toOthers method, let’s imagine a task list application where a user may create a new task by entering a task name. To create a task, your application might make a request to a /task end-point which broadcasts the task’s creation and returns a JSON representation of the new task. When your JavaScript application receives the response from the end-point, it might directly insert the new task into its task list like so:

axios.post('/task', task)
    .then((response) => {
        this.tasks.push(response.data);
    });

However, remember that we also broadcast the task’s creation. If your JavaScript application is listening for this event in order to add tasks to the task list, you will have duplicate tasks in your list: one from the end-point and one from the broadcast.

You may solve this by using the toOthers method to instruct the broadcaster to not broadcast the event to the current user.

36.5.1.1 Configuration

When you initialize a Laravel Echo instance, a socket ID is assigned to the connection. If you are using Vue and Axios, the socket ID will automatically be attached to every outgoing request as a X-Socket-ID header. Then, when you call the toOthers method, Laravel will extract the socket ID from the header and instruct the broadcaster to not broadcast to any connections with that socket ID.

If you are not using Vue and Axios, you will need to manually configure your JavaScript application to send the X-Socket-ID header. You may retrieve the socket ID using the Echo.socketId method:

var socketId = Echo.socketId();

<a name=“receiving-broadcasts”></a>

36.6 Receiving Broadcasts

<a name=“installing-laravel-echo”></a>

36.6.1 Installing Laravel Echo

Laravel Echo is a JavaScript library that makes it painless to subscribe to channels and listen for events broadcast by Laravel. You may install Echo via the NPM package manager. In this example, we will also install the pusher-js package since we will be using the Pusher broadcaster:

npm install --save laravel-echo pusher-js

Once Echo is installed, you are ready to create a fresh Echo instance in your application’s JavaScript. A great place to do this is at the bottom of the resources/assets/js/bootstrap.js file that is included with the Laravel framework:

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key'
});

When creating an Echo instance that uses the pusher connector, you may also specify a cluster as well as whether the connection should be encrypted:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    cluster: 'eu',
    encrypted: true
});

<a name=“listening-for-events”></a>

36.6.2 Listening For Events

Once you have installed and instantiated Echo, you are ready to start listening for event broadcasts. First, use the channel method to retrieve an instance of a channel, then call the listen method to listen for a specified event:

Echo.channel('orders')
    .listen('OrderShipped', (e) => {
        console.log(e.order.name);
    });

If you would like to listen for events on a private channel, use the private method instead. You may continue to chain calls to the listen method to listen for multiple events on a single channel:

Echo.private('orders')
    .listen(...)
    .listen(...)
    .listen(...);

<a name=“leaving-a-channel”></a>

36.6.3 Leaving A Channel

To leave a channel, you may call the leave method on your Echo instance:

Echo.leave('orders');

<a name=“namespaces”></a>

36.6.4 Namespaces

You may have noticed in the examples above that we did not specify the full namespace for the event classes. This is because Echo will automatically assume the events are located in the App\Events namespace. However, you may configure the root namespace when you instantiate Echo by passing a namespace configuration option:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'your-pusher-key',
    namespace: 'App.Other.Namespace'
});

Alternatively, you may prefix event classes with a . when subscribing to them using Echo. This will allow you to always specify the fully-qualified class name:

Echo.channel('orders')
    .listen('.Namespace.Event.Class', (e) => {
        //
    });

<a name=“presence-channels”></a>

36.7 Presence Channels

Presence channels build on the security of private channels while exposing the additional feature of awareness of who is subscribed to the channel. This makes it easy to build powerful, collaborative application features such as notifying users when another user is viewing the same page.

<a name=“joining-a-presence-channel”></a>

36.7.1 Authorizing Presence Channels

All presence channels are also private channels; therefore, users must be authorized to access them. However, when defining authorization callbacks for presence channels, you will not return true if the user is authorized to join the channel. Instead, you should return an array of data about the user.

The data returned by the authorization callback will be made available to the presence channel event listeners in your JavaScript application. If the user is not authorized to join the presence channel, you should return false or null:

Broadcast::channel('chat.{roomId}', function ($user, $roomId) {
    if ($user->canJoinRoom($roomId)) {
        return ['id' => $user->id, 'name' => $user->name];
    }
});

<a name=“joining-presence-channels”></a>

36.7.2 Joining Presence Channels

To join a presence channel, you may use Echo’s join method. The join method will return a PresenceChannel implementation which, along with exposing the listen method, allows you to subscribe to the here, joining, and leaving events.

Echo.join(`chat.${roomId}`)
    .here((users) => {
        //
    })
    .joining((user) => {
        console.log(user.name);
    })
    .leaving((user) => {
        console.log(user.name);
    });

The here callback will be executed immediately once the channel is joined successfully, and will receive an array containing the user information for all of the other users currently subscribed to the channel. The joining method will be executed when a new user joins a channel, while the leaving method will be executed when a user leaves the channel.

<a name=“broadcasting-to-presence-channels”></a>

36.7.3 Broadcasting To Presence Channels

Presence channels may receive events just like public or private channels. Using the example of a chatroom, we may want to broadcast NewMessage events to the room’s presence channel. To do so, we’ll return an instance of PresenceChannel from the event’s broadcastOn method:

/**
 * Get the channels the event should broadcast on.
 *
 * @return Channel|array
 */
public function broadcastOn()
{
    return new PresenceChannel('room.'.$this->message->room_id);
}

Like public or private events, presence channel events may be broadcast using the broadcast function. As with other events, you may use the toOthers method to exclude the current user from receiving the broadcast:

broadcast(new NewMessage($message));

broadcast(new NewMessage($message))->toOthers();

You may listen for the join event via Echo’s listen method:

Echo.join(`chat.${roomId}`)
    .here(...)
    .joining(...)
    .leaving(...)
    .listen('NewMessage', (e) => {
        //
    });

<a name=“client-events”></a>

36.8 Client Events

Sometimes you may wish to broadcast an event to other connected clients without hitting your Laravel application at all. This can be particularly useful for things like “typing” notifications, where you want to alert users of your application that another user is typing a message on a given screen. To broadcast client events, you may use Echo’s whisper method:

Echo.channel('chat')
    .whisper('typing', {
        name: this.user.name
    });

To listen for client events, you may use the listenForWhisper method:

Echo.channel('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

<a name=“notifications”></a>

36.9 Notifications

By pairing event broadcasting with notifications, your JavaScript application may receive new notifications as they occur without needing to refresh the page. First, be sure to read over the documentation on using the broadcast notification channel.

Once you have configured a notification to use the broadcast channel, you may listen for the broadcast events using Echo’s notification method. Remember, the channel name should match the class name of the entity receiving the notifications:

Echo.private(`App.User.${userId}`)
    .notification((notification) => {
        console.log(notification.type);
    });

In this example, all notifications sent to App\User instances via the broadcast channel would be received by the callback. A channel authorization callback for the App.User.{id} channel is included in the default BroadcastServiceProvider that ships with the Laravel framework.

37 Cache

<a name=“configuration”></a>

37.1 Configuration

Laravel provides an expressive, unified API for various caching backends. The cache configuration is located at config/cache.php. In this file you may specify which cache driver you would like used by default throughout your application. Laravel supports popular caching backends like Memcached and Redis out of the box.

The cache configuration file also contains various other options, which are documented within the file, so make sure to read over these options. By default, Laravel is configured to use the file cache driver, which stores the serialized, cached objects in the filesystem. For larger applications, it is recommended that you use a more robust driver such as Memcached or Redis. You may even configure multiple cache configurations for the same driver.

<a name=“driver-prerequisites”></a>

37.1.1 Driver Prerequisites

37.1.1.1 Database

When using the database cache driver, you will need to setup a table to contain the cache items. You’ll find an example Schema declaration for the table below:

Schema::create('cache', function ($table) {
    $table->string('key')->unique();
    $table->text('value');
    $table->integer('expiration');
});

{tip} You may also use the php artisan cache:table Artisan command to generate a migration with the proper schema.

37.1.1.2 Memcached

Using the Memcached driver requires the Memcached PECL package to be installed. You may list all of your Memcached servers in the config/cache.php configuration file:

'memcached' => [
    [
        'host' => '127.0.0.1',
        'port' => 11211,
        'weight' => 100
    ],
],

You may also set the host option to a UNIX socket path. If you do this, the port option should be set to 0:

'memcached' => [
    [
        'host' => '/var/run/memcached/memcached.sock',
        'port' => 0,
        'weight' => 100
    ],
],

37.1.1.3 Redis

Before using a Redis cache with Laravel, you will need to either install the predis/predis package (~1.0) via Composer or install the PhpRedis PHP extension via PECL.

For more information on configuring Redis, consult its Laravel documentation page.

<a name=“cache-usage”></a>

37.2 Cache Usage

<a name=“obtaining-a-cache-instance”></a>

37.2.1 Obtaining A Cache Instance

The Illuminate\Contracts\Cache\Factory and Illuminate\Contracts\Cache\Repository contracts provide access to Laravel’s cache services. The Factory contract provides access to all cache drivers defined for your application. The Repository contract is typically an implementation of the default cache driver for your application as specified by your cache configuration file.

However, you may also use the Cache facade, which is what we will use throughout this documentation. The Cache facade provides convenient, terse access to the underlying implementations of the Laravel cache contracts:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    /**
     * Show a list of all users of the application.
     *
     * @return Response
     */
    public function index()
    {
        $value = Cache::get('key');

        //
    }
}

37.2.1.1 Accessing Multiple Cache Stores

Using the Cache facade, you may access various cache stores via the store method. The key passed to the store method should correspond to one of the stores listed in the stores configuration array in your cache configuration file:

$value = Cache::store('file')->get('foo');

Cache::store('redis')->put('bar', 'baz', 10);

<a name=“retrieving-items-from-the-cache”></a>

37.2.2 Retrieving Items From The Cache

The get method on the Cache facade is used to retrieve items from the cache. If the item does not exist in the cache, null will be returned. If you wish, you may pass a second argument to the get method specifying the default value you wish to be returned if the item doesn’t exist:

$value = Cache::get('key');

$value = Cache::get('key', 'default');

You may even pass a Closure as the default value. The result of the Closure will be returned if the specified item does not exist in the cache. Passing a Closure allows you to defer the retrieval of default values from a database or other external service:

$value = Cache::get('key', function () {
    return DB::table(...)->get();
});

37.2.2.1 Checking For Item Existence

The has method may be used to determine if an item exists in the cache. This method will return false if the value is null or false:

if (Cache::has('key')) {
    //
}

37.2.2.2 Incrementing / Decrementing Values

The increment and decrement methods may be used to adjust the value of integer items in the cache. Both of these methods accept an optional second argument indicating the amount by which to increment or decrement the item’s value:

Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);

37.2.2.3 Retrieve & Store

Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn’t exist. For example, you may wish to retrieve all users from the cache or, if they don’t exist, retrieve them from the database and add them to the cache. You may do this using the Cache::remember method:

$value = Cache::remember('users', $minutes, function () {
    return DB::table('users')->get();
});

If the item does not exist in the cache, the Closure passed to the remember method will be executed and its result will be placed in the cache.

37.2.2.4 Retrieve & Delete

If you need to retrieve an item from the cache and then delete the item, you may use the pull method. Like the get method, null will be returned if the item does not exist in the cache:

$value = Cache::pull('key');

<a name=“storing-items-in-the-cache”></a>

37.2.3 Storing Items In The Cache

You may use the put method on the Cache facade to store items in the cache. When you place an item in the cache, you need to specify the number of minutes for which the value should be cached:

Cache::put('key', 'value', $minutes);

Instead of passing the number of minutes as an integer, you may also pass a DateTime instance representing the expiration time of the cached item:

$expiresAt = Carbon::now()->addMinutes(10);

Cache::put('key', 'value', $expiresAt);

37.2.3.1 Store If Not Present

The add method will only add the item to the cache if it does not already exist in the cache store. The method will return true if the item is actually added to the cache. Otherwise, the method will return false:

Cache::add('key', 'value', $minutes);

37.2.3.2 Storing Items Forever

The forever method may be used to store an item in the cache permanently. Since these items will not expire, they must be manually removed from the cache using the forget method:

Cache::forever('key', 'value');

{tip} If you are using the Memcached driver, items that are stored “forever” may be removed when the cache reaches its size limit.

<a name=“removing-items-from-the-cache”></a>

37.2.4 Removing Items From The Cache

You may remove items from the cache using the forget method:

Cache::forget('key');

You may clear the entire cache using the flush method:

Cache::flush();

{note} Flushing the cache does not respect the cache prefix and will remove all entries from the cache. Consider this carefully when clearing a cache which is shared by other applications.

<a name=“the-cache-helper”></a>

37.2.5 The Cache Helper

In addition to using the Cache facade or cache contract, you may also use the global cache function to retrieve and store data via the cache. When the cache function is called with a single, string argument, it will return the value of the given key:

$value = cache('key');

If you provide an array of key / value pairs and an expiration time to the function, it will store values in the cache for the specified duration:

cache(['key' => 'value'], $minutes);

cache(['key' => 'value'], Carbon::now()->addSeconds(10));

{tip} When testing call to the global cache function, you may use the Cache::shouldReceive method just as if you were testing a facade.

<a name=“cache-tags”></a>

37.3 Cache Tags

{note} Cache tags are not supported when using the file or database cache drivers. Furthermore, when using multiple tags with caches that are stored “forever”, performance will be best with a driver such as memcached, which automatically purges stale records.

<a name=“storing-tagged-cache-items”></a>

37.3.1 Storing Tagged Cache Items

Cache tags allow you to tag related items in the cache and then flush all cached values that have been assigned a given tag. You may access a tagged cache by passing in an ordered array of tag names. For example, let’s access a tagged cache and put value in the cache:

Cache::tags(['people', 'artists'])->put('John', $john, $minutes);

Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);

<a name=“accessing-tagged-cache-items”></a>

37.3.2 Accessing Tagged Cache Items

To retrieve a tagged cache item, pass the same ordered list of tags to the tags method and then call the get method with the key you wish to retrieve:

$john = Cache::tags(['people', 'artists'])->get('John');

$anne = Cache::tags(['people', 'authors'])->get('Anne');

<a name=“removing-tagged-cache-items”></a>

37.3.3 Removing Tagged Cache Items

You may flush all items that are assigned a tag or list of tags. For example, this statement would remove all caches tagged with either people, authors, or both. So, both Anne and John would be removed from the cache:

Cache::tags(['people', 'authors'])->flush();

In contrast, this statement would remove only caches tagged with authors, so Anne would be removed, but not John:

Cache::tags('authors')->flush();

<a name=“adding-custom-cache-drivers”></a>

37.4 Adding Custom Cache Drivers

<a name=“writing-the-driver”></a>

37.4.1 Writing The Driver

To create our custom cache driver, we first need to implement the Illuminate\Contracts\Cache\Store contract contract. So, a MongoDB cache implementation would look something like this:

<?php

namespace App\Extensions;

use Illuminate\Contracts\Cache\Store;

class MongoStore implements Store
{
    public function get($key) {}
    public function many(array $keys);
    public function put($key, $value, $minutes) {}
    public function putMany(array $values, $minutes);
    public function increment($key, $value = 1) {}
    public function decrement($key, $value = 1) {}
    public function forever($key, $value) {}
    public function forget($key) {}
    public function flush() {}
    public function getPrefix() {}
}

We just need to implement each of these methods using a MongoDB connection. For an example of how to implement each of these methods, take a look at the Illuminate\Cache\MemcachedStore in the framework source code. Once our implementation is complete, we can finish our custom driver registration.

Cache::extend('mongo', function ($app) {
    return Cache::repository(new MongoStore);
});

{tip} If you’re wondering where to put your custom cache driver code, you could create an Extensions namespace within your app directory. However, keep in mind that Laravel does not have a rigid application structure and you are free to organize your application according to your preferences.

<a name=“registering-the-driver”></a>

37.4.2 Registering The Driver

To register the custom cache driver with Laravel, we will use the extend method on the Cache facade. The call to Cache::extend could be done in the boot method of the default App\Providers\AppServiceProvider that ships with fresh Laravel applications, or you may create your own service provider to house the extension - just don’t forget to register the provider in the config/app.php provider array:

<?php

namespace App\Providers;

use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Cache::extend('mongo', function ($app) {
            return Cache::repository(new MongoStore);
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

The first argument passed to the extend method is the name of the driver. This will correspond to your driver option in the config/cache.php configuration file. The second argument is a Closure that should return an Illuminate\Cache\Repository instance. The Closure will be passed an $app instance, which is an instance of the service container.

Once your extension is registered, simply update your config/cache.php configuration file’s driver option to the name of your extension.

<a name=“events”></a>

37.5 Events

To execute code on every cache operation, you may listen for the events fired by the cache. Typically, you should place these event listeners within your EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Cache\Events\CacheHit' => [
        'App\Listeners\LogCacheHit',
    ],

    'Illuminate\Cache\Events\CacheMissed' => [
        'App\Listeners\LogCacheMissed',
    ],

    'Illuminate\Cache\Events\KeyForgotten' => [
        'App\Listeners\LogKeyForgotten',
    ],

    'Illuminate\Cache\Events\KeyWritten' => [
        'App\Listeners\LogKeyWritten',
    ],
];

38 Collections

<a name=“introduction”></a>

38.1 Introduction

The Illuminate\Support\Collection class provides a fluent, convenient wrapper for working with arrays of data. For example, check out the following code. We’ll use the collect helper to create a new collection instance from the array, run the strtoupper function on each element, and then remove all empty elements:

$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
    return strtoupper($name);
})
->reject(function ($name) {
    return empty($name);
});

As you can see, the Collection class allows you to chain its methods to perform fluent mapping and reducing of the underlying array. In general, collections are immutable, meaning every Collection method returns an entirely new Collection instance.

<a name=“creating-collections”></a>

38.1.1 Creating Collections

As mentioned above, the collect helper returns a new Illuminate\Support\Collection instance for the given array. So, creating a collection is as simple as:

$collection = collect([1, 2, 3]);

{tip} The results of Eloquent queries are always returned as Collection instances.

<a name=“available-methods”></a>

38.2 Available Methods

For the remainder of this documentation, we’ll discuss each method available on the Collection class. Remember, all of these methods may be chained to fluently manipulating the underlying array. Furthermore, almost every method returns a new Collection instance, allowing you to preserve the original copy of the collection when necessary:

<style>
#collection-method-list > p {
column-count: 3; -moz-column-count: 3; -webkit-column-count: 3;
column-gap: 2em; -moz-column-gap: 2em; -webkit-column-gap: 2em;
}

#collection-method-list a {
    display: block;
}

</style>

<div id=“collection-method-list” markdown=“1”>

all
average
avg
chunk
collapse
combine
contains
containsStrict
count
diff
diffAssoc
diffKeys
each
every
except
filter
first
flatMap
flatten
flip
forget
forPage
get
groupBy
has
implode
intersect
intersectKey
isEmpty
isNotEmpty
keyBy
keys
last
map
mapWithKeys
max
median
merge
min
mode
nth
only
partition
pipe
pluck
pop
prepend
pull
push
put
random
reduce
reject
reverse
search
shift
shuffle
slice
sort
sortBy
sortByDesc
splice
split
sum
take
tap
times
toArray
toJson
transform
union
unique
uniqueStrict
values
when
where
whereStrict
whereIn
whereInStrict
whereNotIn
whereNotInStrict
zip

</div>

<a name=“method-listing”></a>

38.3 Method Listing

<style>
#collection-method code {
font-size: 14px;
}

#collection-method:not(.first-collection-method) {
    margin-top: 50px;
}

</style>

<a name=“method-all”></a>

38.3.0.1 all() {#collection-method .first-collection-method}

The all method returns the underlying array represented by the collection:

collect([1, 2, 3])->all();

// [1, 2, 3]

<a name=“method-average”></a>

38.3.0.2 average() {#collection-method}

Alias for the avg method.

<a name=“method-avg”></a>

38.3.0.3 avg() {#collection-method}

The avg method returns the average value of a given key:

$average = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo');

// 20

$average = collect([1, 1, 2, 4])->avg();

// 2

<a name=“method-chunk”></a>

38.3.0.4 chunk() {#collection-method}

The chunk method breaks the collection into multiple, smaller collections of a given size:

$collection = collect([1, 2, 3, 4, 5, 6, 7]);

$chunks = $collection->chunk(4);

$chunks->toArray();

// [[1, 2, 3, 4], [5, 6, 7]]

This method is especially useful in views when working with a grid system such as Bootstrap. Imagine you have a collection of Eloquent models you want to display in a grid:

@foreach ($products->chunk(3) as $chunk)
    <div class="row">
        @foreach ($chunk as $product)
            <div class="col-xs-4">{{ $product->name }}</div>
        @endforeach
    </div>
@endforeach

<a name=“method-collapse”></a>

38.3.0.5 collapse() {#collection-method}

The collapse method collapses a collection of arrays into a single, flat collection:

$collection = collect([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

$collapsed = $collection->collapse();

$collapsed->all();

// [1, 2, 3, 4, 5, 6, 7, 8, 9]

<a name=“method-combine”></a>

38.3.0.6 combine() {#collection-method}

The combine method combines the keys of the collection with the values of another array or collection:

$collection = collect(['name', 'age']);

$combined = $collection->combine(['George', 29]);

$combined->all();

// ['name' => 'George', 'age' => 29]

<a name=“method-contains”></a>

38.3.0.7 contains() {#collection-method}

The contains method determines whether the collection contains a given item:

$collection = collect(['name' => 'Desk', 'price' => 100]);

$collection->contains('Desk');

// true

$collection->contains('New York');

// false

You may also pass a key / value pair to the contains method, which will determine if the given pair exists in the collection:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
]);

$collection->contains('product', 'Bookcase');

// false

Finally, you may also pass a callback to the contains method to perform your own truth test:

$collection = collect([1, 2, 3, 4, 5]);

$collection->contains(function ($value, $key) {
    return $value > 5;
});

// false

The contains method uses “loose” comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the containsStrict method to filter using “strict” comparisons.

<a name=“method-containsstrict”></a>

38.3.0.8 containsStrict() {#collection-method}

This method has the same signature as the contains method; however, all values are compared using “strict” comparisons.

<a name=“method-count”></a>

38.3.0.9 count() {#collection-method}

The count method returns the total number of items in the collection:

$collection = collect([1, 2, 3, 4]);

$collection->count();

// 4

<a name=“method-diff”></a>

38.3.0.10 diff() {#collection-method}

The diff method compares the collection against another collection or a plain PHP array based on its values. This method will return the values in the original collection that are not present in the given collection:

$collection = collect([1, 2, 3, 4, 5]);

$diff = $collection->diff([2, 4, 6, 8]);

$diff->all();

// [1, 3, 5]

<a name=“method-diffassoc”></a>

38.3.0.11 diffAssoc() {#collection-method}

The diffAssoc method compares the collection against another collection or a plain PHP array based on its keys and values. This method will return the key / value pairs in the original collection that are not present in the given collection:

$collection = collect([
    'color' => 'orange',
    'type' => 'fruit',
    'remain' => 6
]);

$diff = $collection->diffAssoc([
    'color' => 'yellow',
    'type' => 'fruit',
    'remain' => 3,
    'used' => 6
]);

$diff->all();

// ['color' => 'orange', 'remain' => 6]

<a name=“method-diffkeys”></a>

38.3.0.12 diffKeys() {#collection-method}

The diffKeys method compares the collection against another collection or a plain PHP array based on its keys. This method will return the key / value pairs in the original collection that are not present in the given collection:

$collection = collect([
    'one' => 10,
    'two' => 20,
    'three' => 30,
    'four' => 40,
    'five' => 50,
]);

$diff = $collection->diffKeys([
    'two' => 2,
    'four' => 4,
    'six' => 6,
    'eight' => 8,
]);

$diff->all();

// ['one' => 10, 'three' => 30, 'five' => 50]

<a name=“method-each”></a>

38.3.0.13 each() {#collection-method}

The each method iterates over the items in the collection and passes each item to a callback:

$collection = $collection->each(function ($item, $key) {
    //
});

If you would like to stop iterating through the items, you may return false from your callback:

$collection = $collection->each(function ($item, $key) {
    if (/* some condition */) {
        return false;
    }
});

<a name=“method-every”></a>

38.3.0.14 every() {#collection-method}

The every method may be used to verify that all elements of a collection pass a given truth test:

collect([1, 2, 3, 4])->every(function ($value, $key) {
    return $value > 2;
});

// false

<a name=“method-except”></a>

38.3.0.15 except() {#collection-method}

The except method returns all items in the collection except for those with the specified keys:

$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);

$filtered = $collection->except(['price', 'discount']);

$filtered->all();

// ['product_id' => 1]

For the inverse of except, see the only method.

<a name=“method-filter”></a>

38.3.0.16 filter() {#collection-method}

The filter method filters the collection using the given callback, keeping only those items that pass a given truth test:

$collection = collect([1, 2, 3, 4]);

$filtered = $collection->filter(function ($value, $key) {
    return $value > 2;
});

$filtered->all();

// [3, 4]

If no callback is supplied, all entries of the collection that are equivalent to false will be removed:

$collection = collect([1, 2, 3, null, false, '', 0, []]);

$collection->filter()->all();

// [1, 2, 3]

For the inverse of filter, see the reject method.

<a name=“method-first”></a>

38.3.0.17 first() {#collection-method}

The first method returns the first element in the collection that passes a given truth test:

collect([1, 2, 3, 4])->first(function ($value, $key) {
    return $value > 2;
});

// 3

You may also call the first method with no arguments to get the first element in the collection. If the collection is empty, null is returned:

collect([1, 2, 3, 4])->first();

// 1

<a name=“method-flatmap”></a>

38.3.0.18 flatMap() {#collection-method}

The flatMap method iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items. Then, the array is flattened by a level:

$collection = collect([
    ['name' => 'Sally'],
    ['school' => 'Arkansas'],
    ['age' => 28]
]);

$flattened = $collection->flatMap(function ($values) {
    return array_map('strtoupper', $values);
});

$flattened->all();

// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];

<a name=“method-flatten”></a>

38.3.0.19 flatten() {#collection-method}

The flatten method flattens a multi-dimensional collection into a single dimension:

$collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]);

$flattened = $collection->flatten();

$flattened->all();

// ['taylor', 'php', 'javascript'];

You may optionally pass the function a “depth” argument:

$collection = collect([
    'Apple' => [
        ['name' => 'iPhone 6S', 'brand' => 'Apple'],
    ],
    'Samsung' => [
        ['name' => 'Galaxy S7', 'brand' => 'Samsung']
    ],
]);

$products = $collection->flatten(1);

$products->values()->all();

/*
    [
        ['name' => 'iPhone 6S', 'brand' => 'Apple'],
        ['name' => 'Galaxy S7', 'brand' => 'Samsung'],
    ]
*/

In this example, calling flatten without providing the depth would have also flattened the nested arrays, resulting in ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']. Providing a depth allows you to restrict the levels of nested arrays that will be flattened.

<a name=“method-flip”></a>

38.3.0.20 flip() {#collection-method}

The flip method swaps the collection’s keys with their corresponding values:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$flipped = $collection->flip();

$flipped->all();

// ['taylor' => 'name', 'laravel' => 'framework']

<a name=“method-forget”></a>

38.3.0.21 forget() {#collection-method}

The forget method removes an item from the collection by its key:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$collection->forget('name');

$collection->all();

// ['framework' => 'laravel']

{note} Unlike most other collection methods, forget does not return a new modified collection; it modifies the collection it is called on.

<a name=“method-forpage”></a>

38.3.0.22 forPage() {#collection-method}

The forPage method returns a new collection containing the items that would be present on a given page number. The method accepts the page number as its first argument and the number of items to show per page as its second argument:

$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);

$chunk = $collection->forPage(2, 3);

$chunk->all();

// [4, 5, 6]

<a name=“method-get”></a>

38.3.0.23 get() {#collection-method}

The get method returns the item at a given key. If the key does not exist, null is returned:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('name');

// taylor

You may optionally pass a default value as the second argument:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('foo', 'default-value');

// default-value

You may even pass a callback as the default value. The result of the callback will be returned if the specified key does not exist:

$collection->get('email', function () {
    return 'default-value';
});

// default-value

<a name=“method-groupby”></a>

38.3.0.24 groupBy() {#collection-method}

The groupBy method groups the collection’s items by a given key:

$collection = collect([
    ['account_id' => 'account-x10', 'product' => 'Chair'],
    ['account_id' => 'account-x10', 'product' => 'Bookcase'],
    ['account_id' => 'account-x11', 'product' => 'Desk'],
]);

$grouped = $collection->groupBy('account_id');

$grouped->toArray();

/*
    [
        'account-x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'account-x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]
*/

In addition to passing a string key, you may also pass a callback. The callback should return the value you wish to key the group by:

$grouped = $collection->groupBy(function ($item, $key) {
    return substr($item['account_id'], -3);
});

$grouped->toArray();

/*
    [
        'x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]
*/

<a name=“method-has”></a>

38.3.0.25 has() {#collection-method}

The has method determines if a given key exists in the collection:

$collection = collect(['account_id' => 1, 'product' => 'Desk']);

$collection->has('product');

// true

<a name=“method-implode”></a>

38.3.0.26 implode() {#collection-method}

The implode method joins the items in a collection. Its arguments depend on the type of items in the collection. If the collection contains arrays or objects, you should pass the key of the attributes you wish to join, and the “glue” string you wish to place between the values:

$collection = collect([
    ['account_id' => 1, 'product' => 'Desk'],
    ['account_id' => 2, 'product' => 'Chair'],
]);

$collection->implode('product', ', ');

// Desk, Chair

If the collection contains simple strings or numeric values, simply pass the “glue” as the only argument to the method:

collect([1, 2, 3, 4, 5])->implode('-');

// '1-2-3-4-5'

<a name=“method-intersect”></a>

38.3.0.27 intersect() {#collection-method}

The intersect method removes any values from the original collection that are not present in the given array or collection. The resulting collection will preserve the original collection’s keys:

$collection = collect(['Desk', 'Sofa', 'Chair']);

$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);

$intersect->all();

// [0 => 'Desk', 2 => 'Chair']

<a name=“method-intersectkey”></a>

38.3.0.28 intersectKey() {#collection-method}

The intersectKey method removes any keys from the original collection that are not present in the given array or collection:

$collection = collect([
    'serial' => 'UX301', 'type' => 'screen', 'year' => 2009
]);

$intersect = $collection->intersectKey([
    'reference' => 'UX404', 'type' => 'tab', 'year' => 2011
]);

$intersect->all();

// ['type' => 'screen', 'year' => 2009]

<a name=“method-isempty”></a>

38.3.0.29 isEmpty() {#collection-method}

The isEmpty method returns true if the collection is empty; otherwise, false is returned:

collect([])->isEmpty();

// true

<a name=“method-isnotempty”></a>

38.3.0.30 isNotEmpty() {#collection-method}

The isNotEmpty method returns true if the collection is not empty; otherwise, false is returned:

collect([])->isNotEmpty();

// false

<a name=“method-keyby”></a>

38.3.0.31 keyBy() {#collection-method}

The keyBy method keys the collection by the given key. If multiple items have the same key, only the last one will appear in the new collection:

$collection = collect([
    ['product_id' => 'prod-100', 'name' => 'desk'],
    ['product_id' => 'prod-200', 'name' => 'chair'],
]);

$keyed = $collection->keyBy('product_id');

$keyed->all();

/*
    [
        'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
        'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
    ]
*/

You may also pass a callback to the method. The callback should return the value to key the collection by:

$keyed = $collection->keyBy(function ($item) {
    return strtoupper($item['product_id']);
});

$keyed->all();

/*
    [
        'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
        'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
    ]
*/

<a name=“method-keys”></a>

38.3.0.32 keys() {#collection-method}

The keys method returns all of the collection’s keys:

$collection = collect([
    'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
    'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]);

$keys = $collection->keys();

$keys->all();

// ['prod-100', 'prod-200']

<a name=“method-last”></a>

38.3.0.33 last() {#collection-method}

The last method returns the last element in the collection that passes a given truth test:

collect([1, 2, 3, 4])->last(function ($value, $key) {
    return $value < 3;
});

// 2

You may also call the last method with no arguments to get the last element in the collection. If the collection is empty, null is returned:

collect([1, 2, 3, 4])->last();

// 4

<a name=“method-map”></a>

38.3.0.34 map() {#collection-method}

The map method iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items:

$collection = collect([1, 2, 3, 4, 5]);

$multiplied = $collection->map(function ($item, $key) {
    return $item * 2;
});

$multiplied->all();

// [2, 4, 6, 8, 10]

{note} Like most other collection methods, map returns a new collection instance; it does not modify the collection it is called on. If you want to transform the original collection, use the transform method.

<a name=“method-mapwithkeys”></a>

38.3.0.35 mapWithKeys() {#collection-method}

The mapWithKeys method iterates through the collection and passes each value to the given callback. The callback should return an associative array containing a single key / value pair:

$collection = collect([
    [
        'name' => 'John',
        'department' => 'Sales',
        'email' => 'john@example.com'
    ],
    [
        'name' => 'Jane',
        'department' => 'Marketing',
        'email' => 'jane@example.com'
    ]
]);

$keyed = $collection->mapWithKeys(function ($item) {
    return [$item['email'] => $item['name']];
});

$keyed->all();

/*
    [
        'john@example.com' => 'John',
        'jane@example.com' => 'Jane',
    ]
*/

<a name=“method-max”></a>

38.3.0.36 max() {#collection-method}

The max method returns the maximum value of a given key:

$max = collect([['foo' => 10], ['foo' => 20]])->max('foo');

// 20

$max = collect([1, 2, 3, 4, 5])->max();

// 5

<a name=“method-median”></a>

38.3.0.37 median() {#collection-method}

The median method returns the median value of a given key:

$median = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->median('foo');

// 15

$median = collect([1, 1, 2, 4])->median();

// 1.5

<a name=“method-merge”></a>

38.3.0.38 merge() {#collection-method}

The merge method merges the given array or collection with the original collection. If a string key in the given items matches a string key in the original collection, the given items’s value will overwrite the value in the original collection:

$collection = collect(['product_id' => 1, 'price' => 100]);

$merged = $collection->merge(['price' => 200, 'discount' => false]);

$merged->all();

// ['product_id' => 1, 'price' => 200, 'discount' => false]

If the given items’s keys are numeric, the values will be appended to the end of the collection:

$collection = collect(['Desk', 'Chair']);

$merged = $collection->merge(['Bookcase', 'Door']);

$merged->all();

// ['Desk', 'Chair', 'Bookcase', 'Door']

<a name=“method-min”></a>

38.3.0.39 min() {#collection-method}

The min method returns the minimum value of a given key:

$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');

// 10

$min = collect([1, 2, 3, 4, 5])->min();

// 1

<a name=“method-mode”></a>

38.3.0.40 mode() {#collection-method}

The mode method returns the mode value of a given key:

$mode = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->mode('foo');

// [10]

$mode = collect([1, 1, 2, 4])->mode();

// [1]

<a name=“method-nth”></a>

38.3.0.41 nth() {#collection-method}

The nth method creates a new collection consisting of every n-th element:

$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);

$collection->nth(4);

// ['a', 'e']

You may optionally pass an offset as the second argument:

$collection->nth(4, 1);

// ['b', 'f']

<a name=“method-only”></a>

38.3.0.42 only() {#collection-method}

The only method returns the items in the collection with the specified keys:

$collection = collect(['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]);

$filtered = $collection->only(['product_id', 'name']);

$filtered->all();

// ['product_id' => 1, 'name' => 'Desk']

For the inverse of only, see the except method.

<a name=“method-partition”></a>

38.3.0.43 partition() {#collection-method}

The partition method may be combined with the list PHP function to separate elements that pass a given truth test from those that do not:

$collection = collect([1, 2, 3, 4, 5, 6]);

list($underThree, $aboveThree) = $collection->partition(function ($i) {
    return $i < 3;
});

<a name=“method-pipe”></a>

38.3.0.44 pipe() {#collection-method}

The pipe method passes the collection to the given callback and returns the result:

$collection = collect([1, 2, 3]);

$piped = $collection->pipe(function ($collection) {
    return $collection->sum();
});

// 6

<a name=“method-pluck”></a>

38.3.0.45 pluck() {#collection-method}

The pluck method retrieves all of the values for a given key:

$collection = collect([
    ['product_id' => 'prod-100', 'name' => 'Desk'],
    ['product_id' => 'prod-200', 'name' => 'Chair'],
]);

$plucked = $collection->pluck('name');

$plucked->all();

// ['Desk', 'Chair']

You may also specify how you wish the resulting collection to be keyed:

$plucked = $collection->pluck('name', 'product_id');

$plucked->all();

// ['prod-100' => 'Desk', 'prod-200' => 'Chair']

<a name=“method-pop”></a>

38.3.0.46 pop() {#collection-method}

The pop method removes and returns the last item from the collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->pop();

// 5

$collection->all();

// [1, 2, 3, 4]

<a name=“method-prepend”></a>

38.3.0.47 prepend() {#collection-method}

The prepend method adds an item to the beginning of the collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->prepend(0);

$collection->all();

// [0, 1, 2, 3, 4, 5]

You may also pass a second argument to set the key of the prepended item:

$collection = collect(['one' => 1, 'two' => 2]);

$collection->prepend(0, 'zero');

$collection->all();

// ['zero' => 0, 'one' => 1, 'two' => 2]

<a name=“method-pull”></a>

38.3.0.48 pull() {#collection-method}

The pull method removes and returns an item from the collection by its key:

$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);

$collection->pull('name');

// 'Desk'

$collection->all();

// ['product_id' => 'prod-100']

<a name=“method-push”></a>

38.3.0.49 push() {#collection-method}

The push method appends an item to the end of the collection:

$collection = collect([1, 2, 3, 4]);

$collection->push(5);

$collection->all();

// [1, 2, 3, 4, 5]

<a name=“method-put”></a>

38.3.0.50 put() {#collection-method}

The put method sets the given key and value in the collection:

$collection = collect(['product_id' => 1, 'name' => 'Desk']);

$collection->put('price', 100);

$collection->all();

// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]

<a name=“method-random”></a>

38.3.0.51 random() {#collection-method}

The random method returns a random item from the collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->random();

// 4 - (retrieved randomly)

You may optionally pass an integer to random to specify how many items you would like to randomly retrieve. A collection of items is always returned when explicitly passing the number of items you wish to receive:

$random = $collection->random(3);

$random->all();

// [2, 4, 5] - (retrieved randomly)

<a name=“method-reduce”></a>

38.3.0.52 reduce() {#collection-method}

The reduce method reduces the collection to a single value, passing the result of each iteration into the subsequent iteration:

$collection = collect([1, 2, 3]);

$total = $collection->reduce(function ($carry, $item) {
    return $carry + $item;
});

// 6

The value for $carry on the first iteration is null; however, you may specify its initial value by passing a second argument to reduce:

$collection->reduce(function ($carry, $item) {
    return $carry + $item;
}, 4);

// 10

<a name=“method-reject”></a>

38.3.0.53 reject() {#collection-method}

The reject method filters the collection using the given callback. The callback should return true if the item should be removed from the resulting collection:

$collection = collect([1, 2, 3, 4]);

$filtered = $collection->reject(function ($value, $key) {
    return $value > 2;
});

$filtered->all();

// [1, 2]

For the inverse of the reject method, see the filter method.

<a name=“method-reverse”></a>

38.3.0.54 reverse() {#collection-method}

The reverse method reverses the order of the collection’s items:

$collection = collect([1, 2, 3, 4, 5]);

$reversed = $collection->reverse();

$reversed->all();

// [5, 4, 3, 2, 1]

<a name=“method-search”></a>

38.3.0.55 search() {#collection-method}

The search method searches the collection for the given value and returns its key if found. If the item is not found, false is returned.

$collection = collect([2, 4, 6, 8]);

$collection->search(4);

// 1

The search is done using a “loose” comparison, meaning a string with an integer value will be considered equal to an integer of the same value. To use “strict” comparison, pass true as the second argument to the method:

$collection->search('4', true);

// false

Alternatively, you may pass in your own callback to search for the first item that passes your truth test:

$collection->search(function ($item, $key) {
    return $item > 5;
});

// 2

<a name=“method-shift”></a>

38.3.0.56 shift() {#collection-method}

The shift method removes and returns the first item from the collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->shift();

// 1

$collection->all();

// [2, 3, 4, 5]

<a name=“method-shuffle”></a>

38.3.0.57 shuffle() {#collection-method}

The shuffle method randomly shuffles the items in the collection:

$collection = collect([1, 2, 3, 4, 5]);

$shuffled = $collection->shuffle();

$shuffled->all();

// [3, 2, 5, 1, 4] - (generated randomly)

<a name=“method-slice”></a>

38.3.0.58 slice() {#collection-method}

The slice method returns a slice of the collection starting at the given index:

$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$slice = $collection->slice(4);

$slice->all();

// [5, 6, 7, 8, 9, 10]

If you would like to limit the size of the returned slice, pass the desired size as the second argument to the method:

$slice = $collection->slice(4, 2);

$slice->all();

// [5, 6]

The returned slice will preserve keys by default. If you do not wish to preserve the original keys, you can use the values method to reindex them.

<a name=“method-sort”></a>

38.3.0.59 sort() {#collection-method}

The sort method sorts the collection. The sorted collection keeps the original array keys, so in this example we’ll use the values method to reset the keys to consecutively numbered indexes:

$collection = collect([5, 3, 1, 2, 4]);

$sorted = $collection->sort();

$sorted->values()->all();

// [1, 2, 3, 4, 5]

If your sorting needs are more advanced, you may pass a callback to sort with your own algorithm. Refer to the PHP documentation on usort, which is what the collection’s sort method calls under the hood.

{tip} If you need to sort a collection of nested arrays or objects, see the sortBy and sortByDesc methods.

<a name=“method-sortby”></a>

38.3.0.60 sortBy() {#collection-method}

The sortBy method sorts the collection by the given key. The sorted collection keeps the original array keys, so in this example we’ll use the values method to reset the keys to consecutively numbered indexes:

$collection = collect([
    ['name' => 'Desk', 'price' => 200],
    ['name' => 'Chair', 'price' => 100],
    ['name' => 'Bookcase', 'price' => 150],
]);

$sorted = $collection->sortBy('price');

$sorted->values()->all();

/*
    [
        ['name' => 'Chair', 'price' => 100],
        ['name' => 'Bookcase', 'price' => 150],
        ['name' => 'Desk', 'price' => 200],
    ]
*/

You can also pass your own callback to determine how to sort the collection values:

$collection = collect([
    ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
    ['name' => 'Chair', 'colors' => ['Black']],
    ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);

$sorted = $collection->sortBy(function ($product, $key) {
    return count($product['colors']);
});

$sorted->values()->all();

/*
    [
        ['name' => 'Chair', 'colors' => ['Black']],
        ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
        ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
    ]
*/

<a name=“method-sortbydesc”></a>

38.3.0.61 sortByDesc() {#collection-method}

This method has the same signature as the sortBy method, but will sort the collection in the opposite order.

<a name=“method-splice”></a>

38.3.0.62 splice() {#collection-method}

The splice method removes and returns a slice of items starting at the specified index:

$collection = collect([1, 2, 3, 4, 5]);

$chunk = $collection->splice(2);

$chunk->all();

// [3, 4, 5]

$collection->all();

// [1, 2]

You may pass a second argument to limit the size of the resulting chunk:

$collection = collect([1, 2, 3, 4, 5]);

$chunk = $collection->splice(2, 1);

$chunk->all();

// [3]

$collection->all();

// [1, 2, 4, 5]

In addition, you can pass a third argument containing the new items to replace the items removed from the collection:

$collection = collect([1, 2, 3, 4, 5]);

$chunk = $collection->splice(2, 1, [10, 11]);

$chunk->all();

// [3]

$collection->all();

// [1, 2, 10, 11, 4, 5]

<a name=“method-split”></a>

38.3.0.63 split() {#collection-method}

The split method breaks a collection into the given number of groups:

$collection = collect([1, 2, 3, 4, 5]);

$groups = $collection->split(3);

$groups->toArray();

// [[1, 2], [3, 4], [5]]

<a name=“method-sum”></a>

38.3.0.64 sum() {#collection-method}

The sum method returns the sum of all items in the collection:

collect([1, 2, 3, 4, 5])->sum();

// 15

If the collection contains nested arrays or objects, you should pass a key to use for determining which values to sum:

$collection = collect([
    ['name' => 'JavaScript: The Good Parts', 'pages' => 176],
    ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
]);

$collection->sum('pages');

// 1272

In addition, you may pass your own callback to determine which values of the collection to sum:

$collection = collect([
    ['name' => 'Chair', 'colors' => ['Black']],
    ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
    ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);

$collection->sum(function ($product) {
    return count($product['colors']);
});

// 6

<a name=“method-take”></a>

38.3.0.65 take() {#collection-method}

The take method returns a new collection with the specified number of items:

$collection = collect([0, 1, 2, 3, 4, 5]);

$chunk = $collection->take(3);

$chunk->all();

// [0, 1, 2]

You may also pass a negative integer to take the specified amount of items from the end of the collection:

$collection = collect([0, 1, 2, 3, 4, 5]);

$chunk = $collection->take(-2);

$chunk->all();

// [4, 5]

<a name=“method-tap”></a>

38.3.0.66 tap() {#collection-method}

The tap method passes the collection to the given callback, allowing you to “tap” into the collection at a specific point and do something with the items while not affecting the collection itself:

collect([2, 4, 3, 1, 5])
    ->sort()
    ->tap(function ($collection) {
        Log::debug('Values after sorting', $collection->values()->toArray());
    })
    ->shift();

// 1

<a name=“method-times”></a>

38.3.0.67 times() {#collection-method}

The static times method creates a new collection by invoking the callback a given amount of times:

$collection = Collection::times(10, function ($number) {
    return $number * 9;
});

$collection->all();

// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]

This method can be useful when combined with factories to create Eloquent models:

$categories = Collection::times(3, function ($number) {
    return factory(Category::class)->create(['name' => 'Category #'.$number]);
});

$categories->all();

/*
    [
        ['id' => 1, 'name' => 'Category #1'],
        ['id' => 2, 'name' => 'Category #2'],
        ['id' => 3, 'name' => 'Category #3'],
    ]
*/

<a name=“method-toarray”></a>

38.3.0.68 toArray() {#collection-method}

The toArray method converts the collection into a plain PHP array. If the collection’s values are Eloquent models, the models will also be converted to arrays:

$collection = collect(['name' => 'Desk', 'price' => 200]);

$collection->toArray();

/*
    [
        ['name' => 'Desk', 'price' => 200],
    ]
*/

{note} toArray also converts all of the collection’s nested objects to an array. If you want to get the raw underlying array, use the all method instead.

<a name=“method-tojson”></a>

38.3.0.69 toJson() {#collection-method}

The toJson method converts the collection into a JSON serialized string:

$collection = collect(['name' => 'Desk', 'price' => 200]);

$collection->toJson();

// '{"name":"Desk", "price":200}'

<a name=“method-transform”></a>

38.3.0.70 transform() {#collection-method}

The transform method iterates over the collection and calls the given callback with each item in the collection. The items in the collection will be replaced by the values returned by the callback:

$collection = collect([1, 2, 3, 4, 5]);

$collection->transform(function ($item, $key) {
    return $item * 2;
});

$collection->all();

// [2, 4, 6, 8, 10]

{note} Unlike most other collection methods, transform modifies the collection itself. If you wish to create a new collection instead, use the map method.

<a name=“method-union”></a>

38.3.0.71 union() {#collection-method}

The union method adds the given array to the collection. If the given array contains keys that are already in the original collection, the original collection’s values will be preferred:

$collection = collect([1 => ['a'], 2 => ['b']]);

$union = $collection->union([3 => ['c'], 1 => ['b']]);

$union->all();

// [1 => ['a'], 2 => ['b'], 3 => ['c']]

<a name=“method-unique”></a>

38.3.0.72 unique() {#collection-method}

The unique method returns all of the unique items in the collection. The returned collection keeps the original array keys, so in this example we’ll use the values method to reset the keys to consecutively numbered indexes:

$collection = collect([1, 1, 2, 2, 3, 4, 2]);

$unique = $collection->unique();

$unique->values()->all();

// [1, 2, 3, 4]

When dealing with nested arrays or objects, you may specify the key used to determine uniqueness:

$collection = collect([
    ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
    ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],
    ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
    ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
    ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]);

$unique = $collection->unique('brand');

$unique->values()->all();

/*
    [
        ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
        ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
    ]
*/

You may also pass your own callback to determine item uniqueness:

$unique = $collection->unique(function ($item) {
    return $item['brand'].$item['type'];
});

$unique->values()->all();

/*
    [
        ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
        ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
        ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
        ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
    ]
*/

The unique method uses “loose” comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the uniqueStrict method to filter using “strict” comparisons.

<a name=“method-uniquestrict”></a>

38.3.0.73 uniqueStrict() {#collection-method}

This method has the same signature as the unique method; however, all values are compared using “strict” comparisons.

<a name=“method-values”></a>

38.3.0.74 values() {#collection-method}

The values method returns a new collection with the keys reset to consecutive integers:

$collection = collect([
    10 => ['product' => 'Desk', 'price' => 200],
    11 => ['product' => 'Desk', 'price' => 200]
]);

$values = $collection->values();

$values->all();

/*
    [
        0 => ['product' => 'Desk', 'price' => 200],
        1 => ['product' => 'Desk', 'price' => 200],
    ]
*/

<a name=“method-when”></a>

38.3.0.75 when() {#collection-method}

The when method will execute the given callback when the first argument given to the method evaluates to true:

$collection = collect([1, 2, 3]);

$collection->when(true, function ($collection) {
    return $collection->push(4);
});

$collection->all();

// [1, 2, 3, 4]

<a name=“method-where”></a>

38.3.0.76 where() {#collection-method}

The where method filters the collection by a given key / value pair:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
    ['product' => 'Bookcase', 'price' => 150],
    ['product' => 'Door', 'price' => 100],
]);

$filtered = $collection->where('price', 100);

$filtered->all();

/*
    [
        ['product' => 'Chair', 'price' => 100],
        ['product' => 'Door', 'price' => 100],
    ]
*/

The where method uses “loose” comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the whereStrict method to filter using “strict” comparisons.

<a name=“method-wherestrict”></a>

38.3.0.77 whereStrict() {#collection-method}

This method has the same signature as the where method; however, all values are compared using “strict” comparisons.

<a name=“method-wherein”></a>

38.3.0.78 whereIn() {#collection-method}

The whereIn method filters the collection by a given key / value contained within the given array:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
    ['product' => 'Bookcase', 'price' => 150],
    ['product' => 'Door', 'price' => 100],
]);

$filtered = $collection->whereIn('price', [150, 200]);

$filtered->all();

/*
    [
        ['product' => 'Bookcase', 'price' => 150],
        ['product' => 'Desk', 'price' => 200],
    ]
*/

The whereIn method uses “loose” comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the whereInStrict method to filter using “strict” comparisons.

<a name=“method-whereinstrict”></a>

38.3.0.79 whereInStrict() {#collection-method}

This method has the same signature as the whereIn method; however, all values are compared using “strict” comparisons.

<a name=“method-wherenotin”></a>

38.3.0.80 whereNotIn() {#collection-method}

The whereNotIn method filters the collection by a given key / value not contained within the given array:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
    ['product' => 'Bookcase', 'price' => 150],
    ['product' => 'Door', 'price' => 100],
]);

$filtered = $collection->whereNotIn('price', [150, 200]);

$filtered->all();

/*
    [
        ['product' => 'Chair', 'price' => 100],
        ['product' => 'Door', 'price' => 100],
    ]
*/

The whereNotIn method uses “loose” comparisons when checking item values, meaning a string with an integer value will be considered equal to an integer of the same value. Use the whereNotInStrict method to filter using “strict” comparisons.

<a name=“method-wherenotinstrict”></a>

38.3.0.81 whereNotInStrict() {#collection-method}

This method has the same signature as the whereNotIn method; however, all values are compared using “strict” comparisons.

<a name=“method-zip”></a>

38.3.0.82 zip() {#collection-method}

The zip method merges together the values of the given array with the values of the original collection at the corresponding index:

$collection = collect(['Chair', 'Desk']);

$zipped = $collection->zip([100, 200]);

$zipped->all();

// [['Chair', 100], ['Desk', 200]]

<a name=“higher-order-messages”></a>

38.4 Higher Order Messages

Collections also provide support for “higher order messages”, which are short-cuts for performing common actions on collections. The collection methods that provide higher order messages are: average, avg, contains, each, every, filter, first, flatMap, map, partition, reject, sortBy, sortByDesc, and sum.

Each higher order message can be accessed as a dynamic property on a collection instance. For instance, let’s use the each higher order message to call a method on each object within a collection:

$users = User::where('votes', '>', 500)->get();

$users->each->markAsVip();

Likewise, we can use the sum higher order message to gather the total number of “votes” for a collection of users:

$users = User::where('group', 'Development')->get();

return $users->sum->votes;

39 Events

<a name=“introduction”></a>

39.1 Introduction

Laravel’s events provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Event classes are typically stored in the app/Events directory, while their listeners are stored in app/Listeners. Don’t worry if you don’t see these directories in your application, since they will be created for you as you generate events and listeners using Artisan console commands.

Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other. For example, you may wish to send a Slack notification to your user each time an order has shipped. Instead of coupling your order processing code to your Slack notification code, you can simply raise an OrderShipped event, which a listener can receive and transform into a Slack notification.

<a name=“registering-events-and-listeners”></a>

39.2 Registering Events & Listeners

The EventServiceProvider included with your Laravel application provides a convenient place to register all of your application’s event listeners. The listen property contains an array of all events (keys) and their listeners (values). Of course, you may add as many events to this array as your application requires. For example, let’s add a OrderShipped event:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'App\Events\OrderShipped' => [
        'App\Listeners\SendShipmentNotification',
    ],
];

<a name=“generating-events-and-listeners”></a>

39.2.1 Generating Events & Listeners

Of course, manually creating the files for each event and listener is cumbersome. Instead, simply add listeners and events to your EventServiceProvider and use the event:generate command. This command will generate any events or listeners that are listed in your EventServiceProvider. Of course, events and listeners that already exist will be left untouched:

php artisan event:generate

<a name=“manually-registering-events”></a>

39.2.2 Manually Registering Events

Typically, events should be registered via the EventServiceProvider $listen array; however, you may also register Closure based events manually in the boot method of your EventServiceProvider:

/**
 * Register any other events for your application.
 *
 * @return void
 */
public function boot()
{
    parent::boot();

    Event::listen('event.name', function ($foo, $bar) {
        //
    });
}

39.2.2.1 Wildcard Event Listeners

You may even register listeners using the * as a wildcard parameter, allowing you to catch multiple events on the same listener. Wildcard listeners receive the event name as their first argument, and the entire event data array as their second argument:

Event::listen('event.*', function ($eventName, array $data) {
    //
});

<a name=“defining-events”></a>

39.3 Defining Events

An event class is simply a data container which holds the information related to the event. For example, let’s assume our generated OrderShipped event receives an Eloquent ORM object:

<?php

namespace App\Events;

use App\Order;
use Illuminate\Queue\SerializesModels;

class OrderShipped
{
    use SerializesModels;

    public $order;

    /**
     * Create a new event instance.
     *
     * @param  Order  $order
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }
}

As you can see, this event class contains no logic. It is simply a container for the Order instance that was purchased. The SerializesModels trait used by the event will gracefully serialize any Eloquent models if the event object is serialized using PHP’s serialize function.

<a name=“defining-listeners”></a>

39.4 Defining Listeners

Next, let’s take a look at the listener for our example event. Event listeners receive the event instance in their handle method. The event:generate command will automatically import the proper event class and type-hint the event on the handle method. Within the handle method, you may perform any actions necessary to respond to the event:

<?php

namespace App\Listeners;

use App\Events\OrderShipped;

class SendShipmentNotification
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  OrderShipped  $event
     * @return void
     */
    public function handle(OrderShipped $event)
    {
        // Access the order using $event->order...
    }
}

{tip} Your event listeners may also type-hint any dependencies they need on their constructors. All event listeners are resolved via the Laravel service container, so dependencies will be injected automatically.

39.4.0.1 Stopping The Propagation Of An Event

Sometimes, you may wish to stop the propagation of an event to other listeners. You may do so by returning false from your listener’s handle method.

<a name=“queued-event-listeners”></a>

39.5 Queued Event Listeners

Queueing listeners can be beneficial if your listener is going to perform a slow task such as sending an e-mail or making an HTTP request. Before getting started with queued listeners, make sure to configure your queue and start a queue listener on your server or local development environment.

To specify that a listener should be queued, add the ShouldQueue interface to the listener class. Listeners generated by the event:generate Artisan command already have this interface imported into the current namespace, so you can use it immediately:

<?php

namespace App\Listeners;

use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendShipmentNotification implements ShouldQueue
{
    //
}

That’s it! Now, when this listener is called for an event, it will be automatically queued by the event dispatcher using Laravel’s queue system. If no exceptions are thrown when the listener is executed by the queue, the queued job will automatically be deleted after it has finished processing.

39.5.0.1 Customizing The Queue Connection & Queue Name

If you would like to customize the queue connection and queue name used by an event listener, you may define $connection and $queue properties on your listener class:

<?php

namespace App\Listeners;

use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendShipmentNotification implements ShouldQueue
{
    /**
     * The name of the connection the job should be sent to.
     *
     * @var string|null
     */
    public $connection = 'sqs';

    /**
     * The name of the queue the job should be sent to.
     *
     * @var string|null
     */
    public $queue = 'listeners';
}

<a name=“manually-accessing-the-queue”></a>

39.5.1 Manually Accessing The Queue

If you need to manually access the listener’s underlying queue job’s delete and release methods, you may do so using the Illuminate\Queue\InteractsWithQueue trait. This trait is imported by default on generated listeners and provides access to these methods:

<?php

namespace App\Listeners;

use App\Events\OrderShipped;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendShipmentNotification implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * Handle the event.
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */
    public function handle(OrderShipped $event)
    {
        if (true) {
            $this->release(30);
        }
    }
}

<a name=“handling-failed-jobs”></a>

39.5.2 Handling Failed Jobs

Sometimes your queued event listeners may fail. If queued listener exceeds the maximum number of attempts as defined by your queue worker, the failed method will be called on your listener. The failed method receives the event instance and the exception that caused the failure:

<?php

namespace App\Listeners;

use App\Events\OrderShipped;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendShipmentNotification implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * Handle the event.
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */
    public function handle(OrderShipped $event)
    {
        //
    }

    /**
     * Handle a job failure.
     *
     * @param  \App\Events\OrderShipped  $event
     * @param  \Exception  $exception
     * @return void
     */
    public function failed(OrderShipped $event, $exception)
    {
        //
    }
}

<a name=“dispatching-events”></a>

39.6 Dispatching Events

To dispatch an event, you may pass an instance of the event to the event helper. The helper will dispatch the event to all of its registered listeners. Since the event helper is globally available, you may call it from anywhere in your application:

<?php

namespace App\Http\Controllers;

use App\Order;
use App\Events\OrderShipped;
use App\Http\Controllers\Controller;

class OrderController extends Controller
{
    /**
     * Ship the given order.
     *
     * @param  int  $orderId
     * @return Response
     */
    public function ship($orderId)
    {
        $order = Order::findOrFail($orderId);

        // Order shipment logic...

        event(new OrderShipped($order));
    }
}

{tip} When testing, it can be helpful to assert that certain events were dispatched without actually triggering their listeners. Laravel’s built-in testing helpers makes it a cinch.

<a name=“event-subscribers”></a>

39.7 Event Subscribers

<a name=“writing-event-subscribers”></a>

39.7.1 Writing Event Subscribers

Event subscribers are classes that may subscribe to multiple events from within the class itself, allowing you to define several event handlers within a single class. Subscribers should define a subscribe method, which will be passed an event dispatcher instance. You may call the listen method on the given dispatcher to register event listeners:

<?php

namespace App\Listeners;

class UserEventSubscriber
{
    /**
     * Handle user login events.
     */
    public function onUserLogin($event) {}

    /**
     * Handle user logout events.
     */
    public function onUserLogout($event) {}

    /**
     * Register the listeners for the subscriber.
     *
     * @param  Illuminate\Events\Dispatcher  $events
     */
    public function subscribe($events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Login',
            'App\Listeners\UserEventSubscriber@onUserLogin'
        );

        $events->listen(
            'Illuminate\Auth\Events\Logout',
            'App\Listeners\UserEventSubscriber@onUserLogout'
        );
    }

}

<a name=“registering-event-subscribers”></a>

39.7.2 Registering Event Subscribers

After writing the subscriber, you are ready to register it with the event dispatcher. You may register subscribers using the $subscribe property on the EventServiceProvider. For example, let’s add the UserEventSubscriber to the list:

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        //
    ];

    /**
     * The subscriber classes to register.
     *
     * @var array
     */
    protected $subscribe = [
        'App\Listeners\UserEventSubscriber',
    ];
}

40 File Storage

<a name=“introduction”></a>

40.1 Introduction

Laravel provides a powerful filesystem abstraction thanks to the wonderful Flysystem PHP package by Frank de Jonge. The Laravel Flysystem integration provides simple to use drivers for working with local filesystems, Amazon S3, and Rackspace Cloud Storage. Even better, it’s amazingly simple to switch between these storage options as the API remains the same for each system.

<a name=“configuration”></a>

40.2 Configuration

The filesystem configuration file is located at config/filesystems.php. Within this file you may configure all of your “disks”. Each disk represents a particular storage driver and storage location. Example configurations for each supported driver are included in the configuration file. So, simply modify the configuration to reflect your storage preferences and credentials.

Of course, you may configure as many disks as you like, and may even have multiple disks that use the same driver.

<a name=“the-public-disk”></a>

40.2.1 The Public Disk

The public disk is intended for files that are going to be publicly accessible. By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public. This convention will keep your publicly accessible files in one directory that can be easily shared across deployments when using zero down-time deployment systems like Envoyer.

To create the symbolic link, you may use the storage:link Artisan command:

php artisan storage:link

Of course, once a file has been stored and the symbolic link has been created, you can create a URL to the files using the asset helper:

echo asset('storage/file.txt');

<a name=“the-local-driver”></a>

40.2.2 The Local Driver

When using the local driver, all file operations are relative to the root directory defined in your configuration file. By default, this value is set to the storage/app directory. Therefore, the following method would store a file in storage/app/file.txt:

Storage::disk('local')->put('file.txt', 'Contents');

<a name=“driver-prerequisites”></a>

40.2.3 Driver Prerequisites

40.2.3.1 Composer Packages

Before using the S3 or Rackspace drivers, you will need to install the appropriate package via Composer:

  • Amazon S3: league/flysystem-aws-s3-v3 ~1.0
  • Rackspace: league/flysystem-rackspace ~1.0

40.2.3.2 S3 Driver Configuration

The S3 driver configuration information is located in your config/filesystems.php configuration file. This file contains an example configuration array for an S3 driver. You are free to modify this array with your own S3 configuration and credentials.

40.2.3.3 FTP Driver Configuration

Laravel’s Flysystem integrations works great with FTP; however, a sample configuration is not included with the framework’s default filesystems.php configuration file. If you need to configure a FTP filesystem, you may use the example configuration below:

'ftp' => [
    'driver'   => 'ftp',
    'host'     => 'ftp.example.com',
    'username' => 'your-username',
    'password' => 'your-password',

    // Optional FTP Settings...
    // 'port'     => 21,
    // 'root'     => '',
    // 'passive'  => true,
    // 'ssl'      => true,
    // 'timeout'  => 30,
],

40.2.3.4 Rackspace Driver Configuration

Laravel’s Flysystem integrations works great with Rackspace; however, a sample configuration is not included with the framework’s default filesystems.php configuration file. If you need to configure a Rackspace filesystem, you may use the example configuration below:

'rackspace' => [
    'driver'    => 'rackspace',
    'username'  => 'your-username',
    'key'       => 'your-key',
    'container' => 'your-container',
    'endpoint'  => 'https://identity.api.rackspacecloud.com/v2.0/',
    'region'    => 'IAD',
    'url_type'  => 'publicURL',
],

<a name=“obtaining-disk-instances”></a>

40.3 Obtaining Disk Instances

The Storage facade may be used to interact with any of your configured disks. For example, you may use the put method on the facade to store an avatar on the default disk. If you call methods on the Storage facade without first calling the disk method, the method call will automatically be passed to the default disk:

use Illuminate\Support\Facades\Storage;

Storage::put('avatars/1', $fileContents);

If your applications interacts with multiple disks, you may use the disk method on the Storage facade to work with files on a particular disk:

Storage::disk('s3')->put('avatars/1', $fileContents);

<a name=“retrieving-files”></a>

40.4 Retrieving Files

The get method may be used to retrieve the contents of a file. The raw string contents of the file will be returned by the method. Remember, all file paths should be specified relative to the “root” location configured for the disk:

$contents = Storage::get('file.jpg');

The exists method may be used to determine if a file exists on the disk:

$exists = Storage::disk('s3')->exists('file.jpg');

<a name=“file-urls”></a>

40.4.1 File URLs

When using the local or s3 drivers, you may use the url method to get the URL for the given file. If you are using the local driver, this will typically just prepend /storage to the given path and return a relative URL to the file. If you are using the s3 driver, the fully qualified remote URL will be returned:

use Illuminate\Support\Facades\Storage;

$url = Storage::url('file1.jpg');

{note} Remember, if you are using the local driver, all files that should be publicly accessible should be placed in the storage/app/public directory. Furthermore, you should create a symbolic link at public/storage which points to the storage/app/public directory.

40.4.1.1 Temporary URLs

For files stored using the s3 driver, you may create a temporary URL to a given file using the temporaryUrl method. This methods accepts a path and a DateTime instance specifying when the URL should expire:

$url = Storage::temporaryUrl(
    'file1.jpg', Carbon::now()->addMinutes(5)
);

40.4.1.2 Local URL Host Customization

If you would like to pre-define the host for files stored on a disk using the local driver, you may add a url option to the disk’s configuration array:

'public' => [
    'driver' => 'local',
    'root' => storage_path('app/public'),
    'url' => env('APP_URL').'/storage',
    'visibility' => 'public',
],

<a name=“file-metadata”></a>

40.4.2 File Metadata

In addition to reading and writing files, Laravel can also provide information about the files themselves. For example, the size method may be used to get the size of the file in bytes:

use Illuminate\Support\Facades\Storage;

$size = Storage::size('file1.jpg');

The lastModified method returns the UNIX timestamp of the last time the file was modified:

$time = Storage::lastModified('file1.jpg');

<a name=“storing-files”></a>

40.5 Storing Files

The put method may be used to store raw file contents on a disk. You may also pass a PHP resource to the put method, which will use Flysystem’s underlying stream support. Using streams is greatly recommended when dealing with large files:

use Illuminate\Support\Facades\Storage;

Storage::put('file.jpg', $contents);

Storage::put('file.jpg', $resource);

40.5.0.1 Automatic Streaming

If you would like Laravel to automatically manage streaming a given file to your storage location, you may use the putFile or putFileAs method. This method accepts either a Illuminate\Http\File or Illuminate\Http\UploadedFile instance and will automatically stream the file to your desired location:

use Illuminate\Http\File;

// Automatically generate a unique ID for file name...
Storage::putFile('photos', new File('/path/to/photo'));

// Manually specify a file name...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');

There are a few important things to note about the putFile method. Note that we only specified a directory name, not a file name. By default, the putFile method will generate a unique ID to serve as the file name. The path to the file will be returned by the putFile method so you can store the path, including the generated file name, in your database.

The putFile and putFileAs methods also accept an argument to specify the “visibility” of the stored file. This is particularly useful if you are storing the file on a cloud disk such as S3 and would like the file to be publicly accessible:

Storage::putFile('photos', new File('/path/to/photo'), 'public');

40.5.0.2 Prepending & Appending To Files

The prepend and append methods allow you to write to the beginning or end of a file:

Storage::prepend('file.log', 'Prepended Text');

Storage::append('file.log', 'Appended Text');

40.5.0.3 Copying & Moving Files

The copy method may be used to copy an existing file to a new location on the disk, while the move method may be used to rename or move an existing file to a new location:

Storage::copy('old/file1.jpg', 'new/file1.jpg');

Storage::move('old/file1.jpg', 'new/file1.jpg');

<a name=“file-uploads”></a>

40.5.1 File Uploads

In web applications, one of the most common use-cases for storing files is storing user uploaded files such as profile pictures, photos, and documents. Laravel makes it very easy to store uploaded files using the store method on an uploaded file instance. Simply call the store method with the path at which you wish to store the uploaded file:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserAvatarController extends Controller
{
    /**
     * Update the avatar for the user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        $path = $request->file('avatar')->store('avatars');

        return $path;
    }
}

There are a few important things to note about this example. Note that we only specified a directory name, not a file name. By default, the store method will generate a unique ID to serve as the file name. The path to the file will be returned by the store method so you can store the path, including the generated file name, in your database.

You may also call the putFile method on the Storage facade to perform the same file manipulation as the example above:

$path = Storage::putFile('avatars', $request->file('avatar'));

40.5.1.1 Specifying A File Name

If you would not like a file name to be automatically assigned to your stored file, you may use the storeAs method, which receives the path, the file name, and the (optional) disk as its arguments:

$path = $request->file('avatar')->storeAs(
    'avatars', $request->user()->id
);

Of course, you may also use the putFileAs method on the Storage facade, which will perform the same file manipulation as the example above:

$path = Storage::putFileAs(
    'avatars', $request->file('avatar'), $request->user()->id
);

40.5.1.2 Specifying A Disk

By default, this method will use your default disk. If you would like to specify another disk, pass the disk name as the second argument to the store method:

$path = $request->file('avatar')->store(
    'avatars/'.$request->user()->id, 's3'
);

<a name=“file-visibility”></a>

40.5.2 File Visibility

In Laravel’s Flysystem integration, “visibility” is an abstraction of file permissions across multiple platforms. Files may either be declared public or private. When a file is declared public, you are indicating that the file should generally be accessible to others. For example, when using the S3 driver, you may retrieve URLs for public files.

You can set the visibility when setting the file via the put method:

use Illuminate\Support\Facades\Storage;

Storage::put('file.jpg', $contents, 'public');

If the file has already been stored, its visibility can be retrieved and set via the getVisibility and setVisibility methods:

$visibility = Storage::getVisibility('file.jpg');

Storage::setVisibility('file.jpg', 'public')

<a name=“deleting-files”></a>

40.6 Deleting Files

The delete method accepts a single filename or an array of files to remove from the disk:

use Illuminate\Support\Facades\Storage;

Storage::delete('file.jpg');

Storage::delete(['file1.jpg', 'file2.jpg']);

<a name=“directories”></a>

40.7 Directories

40.7.0.1 Get All Files Within A Directory

The files method returns an array of all of the files in a given directory. If you would like to retrieve a list of all files within a given directory including all sub-directories, you may use the allFiles method:

use Illuminate\Support\Facades\Storage;

$files = Storage::files($directory);

$files = Storage::allFiles($directory);

40.7.0.2 Get All Directories Within A Directory

The directories method returns an array of all the directories within a given directory. Additionally, you may use the allDirectories method to get a list of all directories within a given directory and all of its sub-directories:

$directories = Storage::directories($directory);

// Recursive...
$directories = Storage::allDirectories($directory);

40.7.0.3 Create A Directory

The makeDirectory method will create the given directory, including any needed sub-directories:

Storage::makeDirectory($directory);

40.7.0.4 Delete A Directory

Finally, the deleteDirectory may be used to remove a directory and all of its files:

Storage::deleteDirectory($directory);

<a name=“custom-filesystems”></a>

40.8 Custom Filesystems

Laravel’s Flysystem integration provides drivers for several “drivers” out of the box; however, Flysystem is not limited to these and has adapters for many other storage systems. You can create a custom driver if you want to use one of these additional adapters in your Laravel application.

In order to set up the custom filesystem you will need a Flysystem adapter. Let’s add a community maintained Dropbox adapter to our project:

composer require spatie/flysystem-dropbox

Next, you should create a service provider such as DropboxServiceProvider. In the provider’s boot method, you may use the Storage facade’s extend method to define the custom driver:

<?php

namespace App\Providers;

use Storage;
use League\Flysystem\Filesystem;
use Spatie\Dropbox\Client as DropboxClient;
use Illuminate\Support\ServiceProvider;
use Spatie\FlysystemDropbox\DropboxAdapter;

class DropboxServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Storage::extend('dropbox', function ($app, $config) {
            $client = new DropboxClient(
                $config['authorizationToken']
            );

            return new Filesystem(new DropboxAdapter($client));
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

The first argument of the extend method is the name of the driver and the second is a Closure that receives the $app and $config variables. The resolver Closure must return an instance of League\Flysystem\Filesystem. The $config variable contains the values defined in config/filesystems.php for the specified disk.

Once you have created the service provider to register the extension, you may use the dropbox driver in your config/filesystems.php configuration file.

41 Helpers

<a name=“introduction”></a>

41.1 Introduction

Laravel includes a variety of global “helper” PHP functions. Many of these functions are used by the framework itself; however, you are free to use them in your own applications if you find them convenient.

<a name=“available-methods”></a>

41.2 Available Methods

<style>
.collection-method-list > p {
column-count: 3; -moz-column-count: 3; -webkit-column-count: 3;
column-gap: 2em; -moz-column-gap: 2em; -webkit-column-gap: 2em;
}

.collection-method-list a {
    display: block;
}

</style>

41.2.1 Arrays

<div class=“collection-method-list” markdown=“1”>

array_add
array_collapse
array_divide
array_dot
array_except
array_first
array_flatten
array_forget
array_get
array_has
array_last
array_only
array_pluck
array_prepend
array_pull
array_set
array_sort
array_sort_recursive
array_where
array_wrap
head
last
</div>

41.2.2 Paths

<div class=“collection-method-list” markdown=“1”>

app_path
base_path
config_path
database_path
mix
public_path
resource_path
storage_path

</div>

41.2.3 Strings

<div class=“collection-method-list” markdown=“1”>

camel_case
class_basename
e
ends_with
kebab_case
snake_case
str_limit
starts_with
str_after
str_before
str_contains
str_finish
str_is
str_plural
str_random
str_singular
str_slug
studly_case
title_case
trans
trans_choice

</div>

41.2.4 URLs

<div class=“collection-method-list” markdown=“1”>

action
asset
secure_asset
route
secure_url
url

</div>

41.2.5 Miscellaneous

<div class=“collection-method-list” markdown=“1”>

abort
abort_if
abort_unless
auth
back
bcrypt
cache
collect
config
csrf_field
csrf_token
dd
dispatch
env
event
factory
info
logger
method_field
now
old
redirect
report
request
response
retry
session
tap
today
value
view

</div>

<a name=“method-listing”></a>

41.3 Method Listing

<style>
#collection-method code {
font-size: 14px;
}

#collection-method:not(.first-collection-method) {
    margin-top: 50px;
}

</style>

<a name=“arrays”></a>

41.4 Arrays

<a name=“method-array-add”></a>

41.4.0.1 array_add() {#collection-method .first-collection-method}

The array_add function adds a given key / value pair to the array if the given key doesn’t already exist in the array:

$array = array_add(['name' => 'Desk'], 'price', 100);

// ['name' => 'Desk', 'price' => 100]

<a name=“method-array-collapse”></a>

41.4.0.2 array_collapse() {#collection-method}

The array_collapse function collapses an array of arrays into a single array:

$array = array_collapse([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

// [1, 2, 3, 4, 5, 6, 7, 8, 9]

<a name=“method-array-divide”></a>

41.4.0.3 array_divide() {#collection-method}

The array_divide function returns two arrays, one containing the keys, and the other containing the values of the original array:

list($keys, $values) = array_divide(['name' => 'Desk']);

// $keys: ['name']

// $values: ['Desk']

<a name=“method-array-dot”></a>

41.4.0.4 array_dot() {#collection-method}

The array_dot function flattens a multi-dimensional array into a single level array that uses “dot” notation to indicate depth:

$array = array_dot(['foo' => ['bar' => 'baz']]);

// ['foo.bar' => 'baz'];

<a name=“method-array-except”></a>

41.4.0.5 array_except() {#collection-method}

The array_except function removes the given key / value pairs from the array:

$array = ['name' => 'Desk', 'price' => 100];

$array = array_except($array, ['price']);

// ['name' => 'Desk']

<a name=“method-array-first”></a>

41.4.0.6 array_first() {#collection-method}

The array_first function returns the first element of an array passing a given truth test:

$array = [100, 200, 300];

$value = array_first($array, function ($value, $key) {
    return $value >= 150;
});

// 200

A default value may also be passed as the third parameter to the method. This value will be returned if no value passes the truth test:

$value = array_first($array, $callback, $default);

<a name=“method-array-flatten”></a>

41.4.0.7 array_flatten() {#collection-method}

The array_flatten function will flatten a multi-dimensional array into a single level.

$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby']];

$array = array_flatten($array);

// ['Joe', 'PHP', 'Ruby'];

<a name=“method-array-forget”></a>

41.4.0.8 array_forget() {#collection-method}

The array_forget function removes a given key / value pair from a deeply nested array using “dot” notation:

$array = ['products' => ['desk' => ['price' => 100]]];

array_forget($array, 'products.desk');

// ['products' => []]

<a name=“method-array-get”></a>

41.4.0.9 array_get() {#collection-method}

The array_get function retrieves a value from a deeply nested array using “dot” notation:

$array = ['products' => ['desk' => ['price' => 100]]];

$value = array_get($array, 'products.desk');

// ['price' => 100]

The array_get function also accepts a default value, which will be returned if the specific key is not found:

$value = array_get($array, 'names.john', 'default');

<a name=“method-array-has”></a>

41.4.0.10 array_has() {#collection-method}

The array_has function checks that a given item or items exists in an array using “dot” notation:

$array = ['product' => ['name' => 'desk', 'price' => 100]];

$hasItem = array_has($array, 'product.name');

// true

$hasItems = array_has($array, ['product.price', 'product.discount']);

// false

<a name=“method-array-last”></a>

41.4.0.11 array_last() {#collection-method}

The array_last function returns the last element of an array passing a given truth test:

$array = [100, 200, 300, 110];

$value = array_last($array, function ($value, $key) {
    return $value >= 150;
});

// 300

A default value may be passed as the third argument to the method. This value will be returned if no value passes the truth test:

$value = array_last($array, $callback, $default);

<a name=“method-array-only”></a>

41.4.0.12 array_only() {#collection-method}

The array_only function will return only the specified key / value pairs from the given array:

$array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];

$array = array_only($array, ['name', 'price']);

// ['name' => 'Desk', 'price' => 100]

<a name=“method-array-pluck”></a>

41.4.0.13 array_pluck() {#collection-method}

The array_pluck function will pluck a list of the given key / value pairs from the array:

$array = [
    ['developer' => ['id' => 1, 'name' => 'Taylor']],
    ['developer' => ['id' => 2, 'name' => 'Abigail']],
];

$array = array_pluck($array, 'developer.name');

// ['Taylor', 'Abigail'];

You may also specify how you wish the resulting list to be keyed:

$array = array_pluck($array, 'developer.name', 'developer.id');

// [1 => 'Taylor', 2 => 'Abigail'];

<a name=“method-array-prepend”></a>

41.4.0.14 array_prepend() {#collection-method}

The array_prepend function will push an item onto the beginning of an array:

$array = ['one', 'two', 'three', 'four'];

$array = array_prepend($array, 'zero');

// $array: ['zero', 'one', 'two', 'three', 'four']

If needed, you may specify the key that should be used for the value:

$array = ['price' => 100];

$array = array_prepend($array, 'Desk', 'name');

// $array: ['name' => 'Desk', 'price' => 100]

<a name=“method-array-pull”></a>

41.4.0.15 array_pull() {#collection-method}

The array_pull function returns and removes a key / value pair from the array:

$array = ['name' => 'Desk', 'price' => 100];

$name = array_pull($array, 'name');

// $name: Desk

// $array: ['price' => 100]

A default value may be passed as the third argument to the method. This value will be returned if the key doesn’t exist:

$value = array_pull($array, $key, $default);

<a name=“method-array-set”></a>

41.4.0.16 array_set() {#collection-method}

The array_set function sets a value within a deeply nested array using “dot” notation:

$array = ['products' => ['desk' => ['price' => 100]]];

array_set($array, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 200]]]

<a name=“method-array-sort”></a>

41.4.0.17 array_sort() {#collection-method}

The array_sort function sorts the array by the results of the given Closure:

$array = [
    ['name' => 'Desk'],
    ['name' => 'Chair'],
];

$array = array_values(array_sort($array, function ($value) {
    return $value['name'];
}));

/*
    [
        ['name' => 'Chair'],
        ['name' => 'Desk'],
    ]
*/

<a name=“method-array-sort-recursive”></a>

41.4.0.18 array_sort_recursive() {#collection-method}

The array_sort_recursive function recursively sorts the array using the sort function:

$array = [
    [
        'Roman',
        'Taylor',
        'Li',
    ],
    [
        'PHP',
        'Ruby',
        'JavaScript',
    ],
];

$array = array_sort_recursive($array);

/*
    [
        [
            'Li',
            'Roman',
            'Taylor',
        ],
        [
            'JavaScript',
            'PHP',
            'Ruby',
        ]
    ];
*/

<a name=“method-array-where”></a>

41.4.0.19 array_where() {#collection-method}

The array_where function filters the array using the given Closure:

$array = [100, '200', 300, '400', 500];

$array = array_where($array, function ($value, $key) {
    return is_string($value);
});

// [1 => 200, 3 => 400]

<a name=“method-array-wrap”></a>

41.4.0.20 array_wrap() {#collection-method}

The array_wrap function will wrap the given value in an array. If the given value is already an array it will not be changed:

$string = 'Laravel';

$array = array_wrap($string);

// [0 => 'Laravel']

<a name=“method-head”></a>

41.4.0.21 head() {#collection-method}

The head function returns the first element in the given array:

$array = [100, 200, 300];

$first = head($array);

// 100

<a name=“method-last”></a>

41.4.0.22 last() {#collection-method}

The last function returns the last element in the given array:

$array = [100, 200, 300];

$last = last($array);

// 300

<a name=“paths”></a>

41.5 Paths

<a name=“method-app-path”></a>

41.5.0.1 app_path() {#collection-method}

The app_path function returns the fully qualified path to the app directory. You may also use the app_path function to generate a fully qualified path to a file relative to the application directory:

$path = app_path();

$path = app_path('Http/Controllers/Controller.php');

<a name=“method-base-path”></a>

41.5.0.2 base_path() {#collection-method}

The base_path function returns the fully qualified path to the project root. You may also use the base_path function to generate a fully qualified path to a given file relative to the project root directory:

$path = base_path();

$path = base_path('vendor/bin');

<a name=“method-config-path”></a>

41.5.0.3 config_path() {#collection-method}

The config_path function returns the fully qualified path to the application configuration directory:

$path = config_path();

<a name=“method-database-path”></a>

41.5.0.4 database_path() {#collection-method}

The database_path function returns the fully qualified path to the application’s database directory:

$path = database_path();

<a name=“method-mix”></a>

41.5.0.5 mix() {#collection-method}

The mix function gets the path to a versioned Mix file:

mix($file);

<a name=“method-public-path”></a>

41.5.0.6 public_path() {#collection-method}

The public_path function returns the fully qualified path to the public directory:

$path = public_path();

<a name=“method-resource-path”></a>

41.5.0.7 resource_path() {#collection-method}

The resource_path function returns the fully qualified path to the resources directory. You may also use the resource_path function to generate a fully qualified path to a given file relative to the resources directory:

$path = resource_path();

$path = resource_path('assets/sass/app.scss');

<a name=“method-storage-path”></a>

41.5.0.8 storage_path() {#collection-method}

The storage_path function returns the fully qualified path to the storage directory. You may also use the storage_path function to generate a fully qualified path to a given file relative to the storage directory:

$path = storage_path();

$path = storage_path('app/file.txt');

<a name=“strings”></a>

41.6 Strings

<a name=“method-camel-case”></a>

41.6.0.1 camel_case() {#collection-method}

The camel_case function converts the given string to camelCase:

$camel = camel_case('foo_bar');

// fooBar

<a name=“method-class-basename”></a>

41.6.0.2 class_basename() {#collection-method}

The class_basename returns the class name of the given class with the class’ namespace removed:

$class = class_basename('Foo\Bar\Baz');

// Baz

<a name=“method-e”></a>

41.6.0.3 e() {#collection-method}

The e function runs PHP’s htmlspecialchars function with the double_encode option set to false:

echo e('<html>foo</html>');

// &lt;html&gt;foo&lt;/html&gt;

<a name=“method-ends-with”></a>

41.6.0.4 ends_with() {#collection-method}

The ends_with function determines if the given string ends with the given value:

$value = ends_with('This is my name', 'name');

// true

<a name=“method-kebab-case”></a>

41.6.0.5 kebab_case() {#collection-method}

The kebab_case function converts the given string to kebab-case:

$value = kebab_case('fooBar');

// foo-bar

<a name=“method-snake-case”></a>

41.6.0.6 snake_case() {#collection-method}

The snake_case function converts the given string to snake_case:

$snake = snake_case('fooBar');

// foo_bar

<a name=“method-str-limit”></a>

41.6.0.7 str_limit() {#collection-method}

The str_limit function limits the number of characters in a string. The function accepts a string as its first argument and the maximum number of resulting characters as its second argument:

$value = str_limit('The PHP framework for web artisans.', 7);

// The PHP...

<a name=“method-starts-with”></a>

41.6.0.8 starts_with() {#collection-method}

The starts_with function determines if the given string begins with the given value:

$value = starts_with('This is my name', 'This');

// true

<a name=“method-str-after”></a>

41.6.0.9 str_after() {#collection-method}

The str_after function returns everything after the given value in a string:

$value = str_after('This is: a test', 'This is:');

// ' a test'

<a name=“method-str-before”></a>

41.6.0.10 str_before() {#collection-method}

The str_before function returns everything before the given value in a string:

$value = str_before('Test :it before', ':it before');

// 'Test '

<a name=“method-str-contains”></a>

41.6.0.11 str_contains() {#collection-method}

The str_contains function determines if the given string contains the given value:

$value = str_contains('This is my name', 'my');

// true

You may also pass an array of values to determine if the given string contains any of the values:

$value = str_contains('This is my name', ['my', 'foo']);

// true

<a name=“method-str-finish”></a>

41.6.0.12 str_finish() {#collection-method}

The str_finish function adds a single instance of the given value to a string if it does not already end with it:

$string = str_finish('this/string', '/');
$string2 = str_finish('this/string/', '/');

// this/string/

<a name=“method-str-is”></a>

41.6.0.13 str_is() {#collection-method}

The str_is function determines if a given string matches a given pattern. Asterisks may be used to indicate wildcards:

$value = str_is('foo*', 'foobar');

// true

$value = str_is('baz*', 'foobar');

// false

<a name=“method-str-plural”></a>

41.6.0.14 str_plural() {#collection-method}

The str_plural function converts a string to its plural form. This function currently only supports the English language:

$plural = str_plural('car');

// cars

$plural = str_plural('child');

// children

You may provide an integer as a second argument to the function to retrieve the singular or plural form of the string:

$plural = str_plural('child', 2);

// children

$plural = str_plural('child', 1);

// child

<a name=“method-str-random”></a>

41.6.0.15 str_random() {#collection-method}

The str_random function generates a random string of the specified length. This function uses PHP’s random_bytes function:

$string = str_random(40);

<a name=“method-str-singular”></a>

41.6.0.16 str_singular() {#collection-method}

The str_singular function converts a string to its singular form. This function currently only supports the English language:

$singular = str_singular('cars');

// car

<a name=“method-str-slug”></a>

41.6.0.17 str_slug() {#collection-method}

The str_slug function generates a URL friendly “slug” from the given string:

$title = str_slug('Laravel 5 Framework', '-');

// laravel-5-framework

<a name=“method-studly-case”></a>

41.6.0.18 studly_case() {#collection-method}

The studly_case function converts the given string to StudlyCase:

$value = studly_case('foo_bar');

// FooBar

<a name=“method-title-case”></a>

41.6.0.19 title_case() {#collection-method}

The title_case function converts the given string to Title Case:

$title = title_case('a nice title uses the correct case');

// A Nice Title Uses The Correct Case

<a name=“method-trans”></a>

41.6.0.20 trans() {#collection-method}

The trans function translates the given language line using your localization files:

echo trans('validation.required'):

<a name=“method-trans-choice”></a>

41.6.0.21 trans_choice() {#collection-method}

The trans_choice function translates the given language line with inflection:

$value = trans_choice('foo.bar', $count);

<a name=“urls”></a>

41.7 URLs

<a name=“method-action”></a>

41.7.0.1 action() {#collection-method}

The action function generates a URL for the given controller action. You do not need to pass the full namespace to the controller. Instead, pass the controller class name relative to the App\Http\Controllers namespace:

$url = action('HomeController@getIndex');

If the method accepts route parameters, you may pass them as the second argument to the method:

$url = action('UserController@profile', ['id' => 1]);

<a name=“method-asset”></a>

41.7.0.2 asset() {#collection-method}

Generate a URL for an asset using the current scheme of the request (HTTP or HTTPS):

$url = asset('img/photo.jpg');

<a name=“method-secure-asset”></a>

41.7.0.3 secure_asset() {#collection-method}

Generate a URL for an asset using HTTPS:

echo secure_asset('foo/bar.zip', $title, $attributes = []);

<a name=“method-route”></a>

41.7.0.4 route() {#collection-method}

The route function generates a URL for the given named route:

$url = route('routeName');

If the route accepts parameters, you may pass them as the second argument to the method:

$url = route('routeName', ['id' => 1]);

By default, the route function generates an absolute URL. If you wish to generate a relative URL, you may pass false as the third parameter:

$url = route('routeName', ['id' => 1], false);

<a name=“method-secure-url”></a>

41.7.0.5 secure_url() {#collection-method}

The secure_url function generates a fully qualified HTTPS URL to the given path:

echo secure_url('user/profile');

echo secure_url('user/profile', [1]);

<a name=“method-url”></a>

41.7.0.6 url() {#collection-method}

The url function generates a fully qualified URL to the given path:

echo url('user/profile');

echo url('user/profile', [1]);

If no path is provided, a Illuminate\Routing\UrlGenerator instance is returned:

echo url()->current();
echo url()->full();
echo url()->previous();

<a name=“miscellaneous”></a>

41.8 Miscellaneous

<a name=“method-abort”></a>

41.8.0.1 abort() {#collection-method}

The abort function throws a HTTP exception which will be rendered by the exception handler:

abort(401);

You may also provide the exception’s response text:

abort(401, 'Unauthorized.');

<a name=“method-abort-if”></a>

41.8.0.2 abort_if() {#collection-method}

The abort_if function throws an HTTP exception if a given boolean expression evaluates to true:

abort_if(! Auth::user()->isAdmin(), 403);

<a name=“method-abort-unless”></a>

41.8.0.3 abort_unless() {#collection-method}

The abort_unless function throws an HTTP exception if a given boolean expression evaluates to false:

abort_unless(Auth::user()->isAdmin(), 403);

<a name=“method-auth”></a>

41.8.0.4 auth() {#collection-method}

The auth function returns an authenticator instance. You may use it instead of the Auth facade for convenience:

$user = auth()->user();

<a name=“method-back”></a>

41.8.0.5 back() {#collection-method}

The back() function generates a redirect response to the user’s previous location:

return back();

<a name=“method-bcrypt”></a>

41.8.0.6 bcrypt() {#collection-method}

The bcrypt function hashes the given value using Bcrypt. You may use it as an alternative to the Hash facade:

$password = bcrypt('my-secret-password');

<a name=“method-cache”></a>

41.8.0.7 cache() {#collection-method}

The cache function may be used to get values from the cache. If the given key does not exist in the cache, an optional default value will be returned:

$value = cache('key');

$value = cache('key', 'default');

You may add items to the cache by passing an array of key / value pairs to the function. You should also pass the number of minutes or duration the cached value should be considered valid:

cache(['key' => 'value'], 5);

cache(['key' => 'value'], Carbon::now()->addSeconds(10));

<a name=“method-collect”></a>

41.8.0.8 collect() {#collection-method}

The collect function creates a collection instance from the given array:

$collection = collect(['taylor', 'abigail']);

<a name=“method-config”></a>

41.8.0.9 config() {#collection-method}

The config function gets the value of a configuration variable. The configuration values may be accessed using “dot” syntax, which includes the name of the file and the option you wish to access. A default value may be specified and is returned if the configuration option does not exist:

$value = config('app.timezone');

$value = config('app.timezone', $default);

The config helper may also be used to set configuration variables at runtime by passing an array of key / value pairs:

config(['app.debug' => true]);

<a name=“method-csrf-field”></a>

41.8.0.10 csrf_field() {#collection-method}

The csrf_field function generates an HTML hidden input field containing the value of the CSRF token. For example, using Blade syntax:

{{ csrf_field() }}

<a name=“method-csrf-token”></a>

41.8.0.11 csrf_token() {#collection-method}

The csrf_token function retrieves the value of the current CSRF token:

$token = csrf_token();

<a name=“method-dd”></a>

41.8.0.12 dd() {#collection-method}

The dd function dumps the given variables and ends execution of the script:

dd($value);

dd($value1, $value2, $value3, ...);

If you do not want to halt the execution of your script, use the dump function instead:

dump($value);

<a name=“method-dispatch”></a>

41.8.0.13 dispatch() {#collection-method}

The dispatch function pushes a new job onto the Laravel job queue:

dispatch(new App\Jobs\SendEmails);

<a name=“method-env”></a>

41.8.0.14 env() {#collection-method}

The env function gets the value of an environment variable or returns a default value:

$env = env('APP_ENV');

// Return a default value if the variable doesn't exist...
$env = env('APP_ENV', 'production');

<a name=“method-event”></a>

41.8.0.15 event() {#collection-method}

The event function dispatches the given event to its listeners:

event(new UserRegistered($user));

<a name=“method-factory”></a>

41.8.0.16 factory() {#collection-method}

The factory function creates a model factory builder for a given class, name, and amount. It can be used while testing or seeding:

$user = factory(App\User::class)->make();

<a name=“method-info”></a>

41.8.0.17 info() {#collection-method}

The info function will write information to the log:

info('Some helpful information!');

An array of contextual data may also be passed to the function:

info('User login attempt failed.', ['id' => $user->id]);

<a name=“method-logger”></a>

41.8.0.18 logger() {#collection-method}

The logger function can be used to write a debug level message to the log:

logger('Debug message');

An array of contextual data may also be passed to the function:

logger('User has logged in.', ['id' => $user->id]);

A logger instance will be returned if no value is passed to the function:

logger()->error('You are not allowed here.');

<a name=“method-method-field”></a>

41.8.0.19 method_field() {#collection-method}

The method_field function generates an HTML hidden input field containing the spoofed value of the form’s HTTP verb. For example, using Blade syntax:

<form method="POST">
    {{ method_field('DELETE') }}
</form>

<a name=“method-now”></a>

41.8.0.20 now() {#collection-method}

The now function creates a new Illuminate\Support\Carbon instance for the current time:

return now();

<a name=“method-old”></a>

41.8.0.21 old() {#collection-method}

The old function retrieves an old input value flashed into the session:

$value = old('value');

$value = old('value', 'default');

<a name=“method-redirect”></a>

41.8.0.22 redirect() {#collection-method}

The redirect function returns a redirect HTTP response, or returns the redirector instance if called with no arguments:

return redirect('/home');

return redirect()->route('route.name');

<a name=“method-report”></a>

41.8.0.23 report() {#collection-method}

The report function will report an exception using your exception handler’s report method:

report($e);

<a name=“method-request”></a>

41.8.0.24 request() {#collection-method}

The request function returns the current request instance or obtains an input item:

$request = request();

$value = request('key', $default = null)

<a name=“method-response”></a>

41.8.0.25 response() {#collection-method}

The response function creates a response instance or obtains an instance of the response factory:

return response('Hello World', 200, $headers);

return response()->json(['foo' => 'bar'], 200, $headers);

<a name=“method-retry”></a>

41.8.0.26 retry() {#collection-method}

The retry function attempts to execute the given callback until the given maximum attempt threshold is met. If the callback does not throw an exception, it’s return value will be returned. If the callback throws an exception, it will automatically be retried. If the maximum attempt count is exceeded, the exception will be thrown:

return retry(5, function () {
    // Attempt 5 times while resting 100ms in between attempts...
}, 100);

<a name=“method-session”></a>

41.8.0.27 session() {#collection-method}

The session function may be used to get or set session values:

$value = session('key');

You may set values by passing an array of key / value pairs to the function:

session(['chairs' => 7, 'instruments' => 3]);

The session store will be returned if no value is passed to the function:

$value = session()->get('key');

session()->put('key', $value);

<a name=“method-tap”></a>

41.8.0.28 tap() {#collection-method}

The tap function accepts two arguments: an arbitrary $value and a Closure. The $value will be passed to the Closure and then be returned by the tap function. The return value of the Closure is irrelevant:

$user = tap(User::first(), function ($user) {
    $user->name = 'taylor';

    $user->save();
});

If no Closure is passed to the tap function, you may call any method on the given $value. The return value of the method you call will always be $value, regardless of the what the method actually returns in its definition. For example, the Eloquent update method typically returns an integer. However, we can force the method to return the model itself by chaining the update method call through the tap function:

$user = tap($user)->update([
    'name' => $name,
    'email' => $email
]);

<a name=“method-today”></a>

41.8.0.29 today() {#collection-method}

The today function creates a new Illuminate\Support\Carbon instance for the current date:

return today();

<a name=“method-value”></a>

41.8.0.30 value() {#collection-method}

The value function’s behavior will simply return the value it is given. However, if you pass a Closure to the function, the Closure will be executed then its result will be returned:

$value = value(function () {
    return 'bar';
});

<a name=“method-view”></a>

41.8.0.31 view() {#collection-method}

The view function retrieves a view instance:

return view('auth.login');

42 Mail

<a name=“introduction”></a>

42.1 Introduction

Laravel provides a clean, simple API over the popular SwiftMailer library with drivers for SMTP, Mailgun, SparkPost, Amazon SES, PHP’s mail function, and sendmail, allowing you to quickly get started sending mail through a local or cloud based service of your choice.

<a name=“driver-prerequisites”></a>

42.1.1 Driver Prerequisites

The API based drivers such as Mailgun and SparkPost are often simpler and faster than SMTP servers. If possible, you should use one of these drivers. All of the API drivers require the Guzzle HTTP library, which may be installed via the Composer package manager:

composer require guzzlehttp/guzzle

42.1.1.1 Mailgun Driver

To use the Mailgun driver, first install Guzzle, then set the driver option in your config/mail.php configuration file to mailgun. Next, verify that your config/services.php configuration file contains the following options:

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
],

42.1.1.2 SparkPost Driver

To use the SparkPost driver, first install Guzzle, then set the driver option in your config/mail.php configuration file to sparkpost. Next, verify that your config/services.php configuration file contains the following options:

'sparkpost' => [
    'secret' => 'your-sparkpost-key',
],

42.1.1.3 SES Driver

To use the Amazon SES driver you must first install the Amazon AWS SDK for PHP. You may install this library by adding the following line to your composer.json file’s require section and running the composer update command:

"aws/aws-sdk-php": "~3.0"

Next, set the driver option in your config/mail.php configuration file to ses and verify that your config/services.php configuration file contains the following options:

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
],

<a name=“generating-mailables”></a>

42.2 Generating Mailables

In Laravel, each type of email sent by your application is represented as a “mailable” class. These classes are stored in the app/Mail directory. Don’t worry if you don’t see this directory in your application, since it will be generated for you when you create your first mailable class using the make:mail command:

php artisan make:mail OrderShipped

<a name=“writing-mailables”></a>

42.3 Writing Mailables

All of a mailable class’ configuration is done in the build method. Within this method, you may call various methods such as from, subject, view, and attach to configure the email’s presentation and delivery.

<a name=“configuring-the-sender”></a>

42.3.1 Configuring The Sender

42.3.1.1 Using The from Method

First, let’s explore configuring the sender of the email. Or, in other words, who the email is going to be “from”. There are two ways to configure the sender. First, you may use the from method within your mailable class’ build method:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->view('emails.orders.shipped');
}

42.3.1.2 Using A Global from Address

However, if your application uses the same “from” address for all of its emails, it can become cumbersome to call the from method in each mailable class you generate. Instead, you may specify a global “from” address in your config/mail.php configuration file. This address will be used if no other “from” address is specified within the mailable class:

'from' => ['address' => 'example@example.com', 'name' => 'App Name'],

<a name=“configuring-the-view”></a>

42.3.2 Configuring The View

Within a mailable class’ build method, you may use the view method to specify which template should be used when rendering the email’s contents. Since each email typically uses a Blade template to render its contents, you have the full power and convenience of the Blade templating engine when building your email’s HTML:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped');
}

{tip} You may wish to create a resources/views/emails directory to house all of your email templates; however, you are free to place them wherever you wish within your resources/views directory.

42.3.2.1 Plain Text Emails

If you would like to define a plain-text version of your email, you may use the text method. Like the view method, the text method accepts a template name which will be used to render the contents of the email. You are free to define both a HTML and plain-text version of your message:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

<a name=“view-data”></a>

42.3.3 View Data

42.3.3.1 Via Public Properties

Typically, you will want to pass some data to your view that you can utilize when rendering the email’s HTML. There are two ways you may make data available to your view. First, any public property defined on your mailable class will automatically be made available to the view. So, for example, you may pass data into your mailable class’ constructor and set that data to public properties defined on the class:

<?php

namespace App\Mail;

use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * The order instance.
     *
     * @var Order
     */
    public $order;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped');
    }
}

Once the data has been set to a public property, it will automatically be available in your view, so you may access it like you would access any other data in your Blade templates:

<div>
    Price: {{ $order->price }}
</div>

42.3.3.2 Via The with Method:

If you would like to customize the format of your email’s data before it is sent to the template, you may manually pass your data to the view via the with method. Typically, you will still pass data via the mailable class’ constructor; however, you should set this data to protected or private properties so the data is not automatically made available to the template. Then, when calling the with method, pass an array of data that you wish to make available to the template:

<?php

namespace App\Mail;

use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * The order instance.
     *
     * @var Order
     */
    protected $order;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->with([
                        'orderName' => $this->order->name,
                        'orderPrice' => $this->order->price,
                    ]);
    }
}

Once the data has been passed to the with method, it will automatically be available in your view, so you may access it like you would access any other data in your Blade templates:

<div>
    Price: {{ $orderPrice }}
</div>

<a name=“attachments”></a>

42.3.4 Attachments

To add attachments to an email, use the attach method within the mailable class’ build method. The attach method accepts the full path to the file as its first argument:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file');
    }

When attaching files to a message, you may also specify the display name and / or MIME type by passing an array as the second argument to the attach method:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file', [
                        'as' => 'name.pdf',
                        'mime' => 'application/pdf',
                    ]);
    }

42.3.4.1 Raw Data Attachments

The attachData method may be used to attach a raw string of bytes as an attachment. For example, you might use this method if you have generated a PDF in memory and want to attach it to the email without writing it to disk. The attachData method accepts the raw data bytes as its first argument, the name of the file as its second argument, and an array of options as its third argument:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attachData($this->pdf, 'name.pdf', [
                        'mime' => 'application/pdf',
                    ]);
    }

<a name=“inline-attachments”></a>

42.3.5 Inline Attachments

Embedding inline images into your emails is typically cumbersome; however, Laravel provides a convenient way to attach images to your emails and retrieving the appropriate CID. To embed an inline image, use the embed method on the $message variable within your email template. Laravel automatically makes the $message variable available to all of your email templates, so you don’t need to worry about passing it in manually:

<body>
    Here is an image:

    <img src="{{ $message->embed($pathToFile) }}">
</body>

{note} $message variable is not available in markdown messages.

42.3.5.1 Embedding Raw Data Attachments

If you already have a raw data string you wish to embed into an email template, you may use the embedData method on the $message variable:

<body>
    Here is an image from raw data:

    <img src="{{ $message->embedData($data, $name) }}">
</body>

<a name=“customizing-the-swiftmailer-message”></a>

42.3.6 Customizing The SwiftMailer Message

The withSwiftMessage method of the Mailable base class allows you to register a callback which will be invoked with the raw SwiftMailer message instance before sending the message. This gives you an opportunity to customize the message before it is delivered:

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $this->view('emails.orders.shipped');

        $this->withSwiftMessage(function ($message) {
            $message->getHeaders()
                    ->addTextHeader('Custom-Header', 'HeaderValue');
        });
    }

<a name=“markdown-mailables”></a>

42.4 Markdown Mailables

Markdown mailable messages allow you to take advantage of the pre-built templates and components of mail notifications in your mailables. Since the messages are written in Markdown, Laravel is able to render beautiful, responsive HTML templates for the messages while also automatically generating a plain-text counterpart.

<a name=“generating-markdown-mailables”></a>

42.4.1 Generating Markdown Mailables

To generate a mailable with a corresponding Markdown template, you may use the --markdown option of the make:mail Artisan command:

php artisan make:mail OrderShipped --markdown=emails.orders.shipped

Then, when configuring the mailable within its build method, call the markdown method instead of the view method. The markdown methods accepts the name of the Markdown template and an optional array of data to make available to the template:

/**
 * Build the message.
 *
 * @return $this
 */
public function build()
{
    return $this->from('example@example.com')
                ->markdown('emails.orders.shipped');
}

<a name=“writing-markdown-messages”></a>

42.4.2 Writing Markdown Messages

Markdown mailables use a combination of Blade components and Markdown syntax which allow you to easily construct mail messages while leveraging Laravel’s pre-crafted components:

@component('mail::message')
# Order Shipped

Your order has been shipped!

@component('mail::button', ['url' => $url])
View Order
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

{tip} Do not use excess indentation when writing Markdown emails. Markdown parsers will render indented content as code blocks.

42.4.2.1 Button Component

The button component renders a centered button link. The component accepts two arguments, a url and an optional color. Supported colors are blue, green, and red. You may add as many button components to a message as you wish:

@component('mail::button', ['url' => $url, 'color' => 'green'])
View Order
@endcomponent

42.4.2.2 Panel Component

The panel component renders the given block of text in a panel that has a slightly different background color than the rest of the message. This allows you to draw attention to a given block of text:

@component('mail::panel')
This is the panel content.
@endcomponent

42.4.2.3 Table Component

The table component allows you to transform a Markdown table into an HTML table. The component accepts the Markdown table as its content. Table column alignment is supported using the default Markdown table alignment syntax:

@component('mail::table')
| Laravel       | Table         | Example  |
| ------------- |:-------------:| --------:|
| Col 2 is      | Centered      | $10      |
| Col 3 is      | Right-Aligned | $20      |
@endcomponent

<a name=“customizing-the-components”></a>

42.4.3 Customizing The Components

You may export all of the Markdown mail components to your own application for customization. To export the components, use the vendor:publish Artisan command to publish the laravel-mail asset tag:

php artisan vendor:publish --tag=laravel-mail

This command will publish the Markdown mail components to the resources/views/vendor/mail directory. The mail directory will contain a html and a markdown directory, each containing their respective representations of every available component. You are free to customize these components however you like.

42.4.3.1 Customizing The CSS

After exporting the components, the resources/views/vendor/mail/html/themes directory will contain a default.css file. You may customize the CSS in this file and your styles will automatically be in-lined within the HTML representations of your Markdown mail messages.

{tip} If you would like to build an entirely new theme for the Markdown components, simply write a new CSS file within the html/themes directory and change the theme option of your mail configuration file.

<a name=“previewing-mailables-in-the-browser”></a>

42.5 Previewing Mailables In The Browser

When designing a mailable’s template, it is convenient to quickly preview the rendered mailable in your browser like a typical Blade template. For this reason, Laravel allows you to return any mailable directly from a route Closure or controller. When a mailable is returned, it will be rendered and displayed in the browser, allowing you to quickly preview its design without needing to send it to an actual email address:

Route::get('/mailable', function () {
    $invoice = App\Invoice::find(1);

    return new App\Mail\InvoicePaid($invoice);
});

<a name=“sending-mail”></a>

42.6 Sending Mail

To send a message, use the to method on the Mail facade. The to method accepts an email address, a user instance, or a collection of users. If you pass an object or collection of objects, the mailer will automatically use their email and name properties when setting the email recipients, so make sure these attributes are available on your objects. Once you have specified your recipients, you may pass an instance of your mailable class to the send method:

<?php

namespace App\Http\Controllers;

use App\Order;
use App\Mail\OrderShipped;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;

class OrderController extends Controller
{
    /**
     * Ship the given order.
     *
     * @param  Request  $request
     * @param  int  $orderId
     * @return Response
     */
    public function ship(Request $request, $orderId)
    {
        $order = Order::findOrFail($orderId);

        // Ship order...

        Mail::to($request->user())->send(new OrderShipped($order));
    }
}

Of course, you are not limited to just specifying the “to” recipients when sending a message. You are free to set “to”, “cc”, and “bcc” recipients all within a single, chained method call:

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new OrderShipped($order));

<a name=“queueing-mail”></a>

42.6.1 Queueing Mail

42.6.1.1 Queueing A Mail Message

Since sending email messages can drastically lengthen the response time of your application, many developers choose to queue email messages for background sending. Laravel makes this easy using its built-in unified queue API. To queue a mail message, use the queue method on the Mail facade after specifying the message’s recipients:

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue(new OrderShipped($order));

This method will automatically take care of pushing a job onto the queue so the message is sent in the background. Of course, you will need to configure your queues before using this feature.

42.6.1.2 Delayed Message Queueing

If you wish to delay the delivery of a queued email message, you may use the later method. As its first argument, the later method accepts a DateTime instance indicating when the message should be sent:

$when = Carbon\Carbon::now()->addMinutes(10);

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->later($when, new OrderShipped($order));

42.6.1.3 Pushing To Specific Queues

Since all mailable classes generated using the make:mail command make use of the Illuminate\Bus\Queueable trait, you may call the onQueue and onConnection methods on any mailable class instance, allowing you to specify the connection and queue name for the message:

$message = (new OrderShipped($order))
                ->onConnection('sqs')
                ->onQueue('emails');

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue($message);

42.6.1.4 Queueing By Default

If you have mailable classes that you want to always be queued, you may implement the ShouldQueue contract on the class. Now, even if you call the send method when mailing, the mailable will still be queued since it implements the contract:

use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    //
}

<a name=“mail-and-local-development”></a>

42.7 Mail & Local Development

When developing an application that sends email, you probably don’t want to actually send emails to live email addresses. Laravel provides several ways to “disable” the actual sending of emails during local development.

42.7.0.1 Log Driver

Instead of sending your emails, the log mail driver will write all email messages to your log files for inspection. For more information on configuring your application per environment, check out the configuration documentation.

42.7.0.2 Universal To

Another solution provided by Laravel is to set a universal recipient of all emails sent by the framework. This way, all the emails generated by your application will be sent to a specific address, instead of the address actually specified when sending the message. This can be done via the to option in your config/mail.php configuration file:

'to' => [
    'address' => 'example@example.com',
    'name' => 'Example'
],

42.7.0.3 Mailtrap

Finally, you may use a service like Mailtrap and the smtp driver to send your email messages to a “dummy” mailbox where you may view them in a true email client. This approach has the benefit of allowing you to actually inspect the final emails in Mailtrap’s message viewer.

<a name=“events”></a>

42.8 Events

Laravel fires an event just before sending mail messages. Remember, this event is fired when the mail is sent, not when it is queued. You may register an event listener for this event in your EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Mail\Events\MessageSending' => [
        'App\Listeners\LogSentMessage',
    ],
];

43 Notifications

<a name=“introduction”></a>

43.1 Introduction

In addition to support for sending email, Laravel provides support for sending notifications across a variety of delivery channels, including mail, SMS (via Nexmo), and Slack. Notifications may also be stored in a database so they may be displayed in your web interface.

Typically, notifications should be short, informational messages that notify users of something that occurred in your application. For example, if you are writing a billing application, you might send an “Invoice Paid” notification to your users via the email and SMS channels.

<a name=“creating-notifications”></a>

43.2 Creating Notifications

In Laravel, each notification is represented by a single class (typically stored in the app/Notifications directory). Don’t worry if you don’t see this directory in your application, it will be created for you when you run the make:notification Artisan command:

php artisan make:notification InvoicePaid

This command will place a fresh notification class in your app/Notifications directory. Each notification class contains a via method and a variable number of message building methods (such as toMail or toDatabase) that convert the notification to a message optimized for that particular channel.

<a name=“sending-notifications”></a>

43.3 Sending Notifications

<a name=“using-the-notifiable-trait”></a>

43.3.1 Using The Notifiable Trait

Notifications may be sent in two ways: using the notify method of the Notifiable trait or using the Notification facade. First, let’s explore using the trait:

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;
}

This trait is utilized by the default App\User model and contains one method that may be used to send notifications: notify. The notify method expects to receive a notification instance:

use App\Notifications\InvoicePaid;

$user->notify(new InvoicePaid($invoice));

{tip} Remember, you may use the Illuminate\Notifications\Notifiable trait on any of your models. You are not limited to only including it on your User model.

<a name=“using-the-notification-facade”></a>

43.3.2 Using The Notification Facade

Alternatively, you may send notifications via the Notification facade. This is useful primarily when you need to send a notification to multiple notifiable entities such as a collection of users. To send notifications using the facade, pass all of the notifiable entities and the notification instance to the send method:

Notification::send($users, new InvoicePaid($invoice));

<a name=“specifying-delivery-channels”></a>

43.3.3 Specifying Delivery Channels

Every notification class has a via method that determines on which channels the notification will be delivered. Out of the box, notifications may be sent on the mail, database, broadcast, nexmo, and slack channels.

{tip} If you would like to use other delivery channels such as Telegram or Pusher, check out the community driven Laravel Notification Channels website.

The via method receives a $notifiable instance, which will be an instance of the class to which the notification is being sent. You may use $notifiable to determine which channels the notification should be delivered on:

/**
 * Get the notification's delivery channels.
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function via($notifiable)
{
    return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}

<a name=“queueing-notifications”></a>

43.3.4 Queueing Notifications

{note} Before queueing notifications you should configure your queue and start a worker.

Sending notifications can take time, especially if the channel needs an external API call to deliver the notification. To speed up your application’s response time, let your notification be queued by adding the ShouldQueue interface and Queueable trait to your class. The interface and trait are already imported for all notifications generated using make:notification, so you may immediately add them to your notification class:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    // ...
}

Once the ShouldQueue interface has been added to your notification, you may send the notification like normal. Laravel will detect the ShouldQueue interface on the class and automatically queue the delivery of the notification:

$user->notify(new InvoicePaid($invoice));

If you would like to delay the delivery of the notification, you may chain the delay method onto your notification instantiation:

$when = Carbon::now()->addMinutes(10);

$user->notify((new InvoicePaid($invoice))->delay($when));

<a name=“on-demand-notifications”></a>

43.3.5 On-Demand Notifications

Sometimes you may need to send a notification to someone who is not stored as a “user” of your application. Using the Notification::route method, you may specify ad-hoc notification routing information before sending the notification:

Notification::route('mail', 'taylor@laravel.com')
            ->route('nexmo', '5555555555')
            ->send(new InvoicePaid($invoice));

<a name=“mail-notifications”></a>

43.4 Mail Notifications

<a name=“formatting-mail-messages”></a>

43.4.1 Formatting Mail Messages

If a notification supports being sent as an email, you should define a toMail method on the notification class. This method will receive a $notifiable entity and should return a Illuminate\Notifications\Messages\MailMessage instance. Mail messages may contain lines of text as well as a “call to action”. Let’s take a look at an example toMail method:

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->greeting('Hello!')
                ->line('One of your invoices has been paid!')
                ->action('View Invoice', $url)
                ->line('Thank you for using our application!');
}

{tip} Note we are using $this->invoice->id in our message method. You may pass any data your notification needs to generate its message into the notification’s constructor.

In this example, we register a greeting, a line of text, a call to action, and then another line of text. These methods provided by the MailMessage object make it simple and fast to format small transactional emails. The mail channel will then translate the message components into a nice, responsive HTML email template with a plain-text counterpart. Here is an example of an email generated by the mail channel:

<img src=“https://laravel.com/assets/img/notification-example.png” width=“551” height=“596”>

{tip} When sending mail notifications, be sure to set the name value in your config/app.php configuration file. This value will be used in the header and footer of your mail notification messages.

43.4.1.1 Other Notification Formatting Options

Instead of defining the “lines” of text in the notification class, you may use the view method to specify a custom template that should be used to render the notification email:

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)->view(
        'emails.name', ['invoice' => $this->invoice]
    );
}

In addition, you may return a mailable object from the toMail method:

use App\Mail\InvoicePaid as Mailable;

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return Mailable
 */
public function toMail($notifiable)
{
    return (new Mailable($this->invoice))->to($this->user->email);
}

<a name=“error-messages”></a>

43.4.1.2 Error Messages

Some notifications inform users of errors, such as a failed invoice payment. You may indicate that a mail message is regarding an error by calling the error method when building your message. When using the error method on a mail message, the call to action button will be red instead of blue:

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Message
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->error()
                ->subject('Notification Subject')
                ->line('...');
}

<a name=“customizing-the-recipient”></a>

43.4.2 Customizing The Recipient

When sending notifications via the mail channel, the notification system will automatically look for an email property on your notifiable entity. You may customize which email address is used to deliver the notification by defining a routeNotificationForMail method on the entity:

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Route notifications for the mail channel.
     *
     * @return string
     */
    public function routeNotificationForMail()
    {
        return $this->email_address;
    }
}

<a name=“customizing-the-subject”></a>

43.4.3 Customizing The Subject

By default, the email’s subject is the class name of the notification formatted to “title case”. So, if your notification class is named InvoicePaid, the email’s subject will be Invoice Paid. If you would like to specify an explicit subject for the message, you may call the subject method when building your message:

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('Notification Subject')
                ->line('...');
}

<a name=“customizing-the-templates”></a>

43.4.4 Customizing The Templates

You can modify the HTML and plain-text template used by mail notifications by publishing the notification package’s resources. After running this command, the mail notification templates will be located in the resources/views/vendor/notifications directory:

php artisan vendor:publish --tag=laravel-notifications

<a name=“markdown-mail-notifications”></a>

43.5 Markdown Mail Notifications

Markdown mail notifications allow you to take advantage of the pre-built templates of mail notifications, while giving you more freedom to write longer, customized messages. Since the messages are written in Markdown, Laravel is able to render beautiful, responsive HTML templates for the messages while also automatically generating a plain-text counterpart.

<a name=“generating-the-message”></a>

43.5.1 Generating The Message

To generate a notification with a corresponding Markdown template, you may use the --markdown option of the make:notification Artisan command:

php artisan make:notification InvoicePaid --markdown=mail.invoice.paid

Like all other mail notifications, notifications that use Markdown templates should define a toMail method on their notification class. However, instead of using the line and action methods to construct the notification, use the markdown method to specify the name of the Markdown template that should be used:

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    $url = url('/invoice/'.$this->invoice->id);

    return (new MailMessage)
                ->subject('Invoice Paid')
                ->markdown('mail.invoice.paid', ['url' => $url]);
}

<a name=“writing-the-message”></a>

43.5.2 Writing The Message

Markdown mail notifications use a combination of Blade components and Markdown syntax which allow you to easily construct notifications while leveraging Laravel’s pre-crafted notification components:

@component('mail::message')
# Invoice Paid

Your invoice has been paid!

@component('mail::button', ['url' => $url])
View Invoice
@endcomponent

Thanks,<br>
{{ config('app.name') }}
@endcomponent

43.5.2.1 Button Component

The button component renders a centered button link. The component accepts two arguments, a url and an optional color. Supported colors are blue, green, and red. You may add as many button components to a notification as you wish:

@component('mail::button', ['url' => $url, 'color' => 'green'])
View Invoice
@endcomponent

43.5.2.2 Panel Component

The panel component renders the given block of text in a panel that has a slightly different background color than the rest of the notification. This allows you to draw attention to a given block of text:

@component('mail::panel')
This is the panel content.
@endcomponent

43.5.2.3 Table Component

The table component allows you to transform a Markdown table into an HTML table. The component accepts the Markdown table as its content. Table column alignment is supported using the default Markdown table alignment syntax:

@component('mail::table')
| Laravel       | Table         | Example  |
| ------------- |:-------------:| --------:|
| Col 2 is      | Centered      | $10      |
| Col 3 is      | Right-Aligned | $20      |
@endcomponent

<a name=“customizing-the-components”></a>

43.5.3 Customizing The Components

You may export all of the Markdown notification components to your own application for customization. To export the components, use the vendor:publish Artisan command to publish the laravel-mail asset tag:

php artisan vendor:publish --tag=laravel-mail

This command will publish the Markdown mail components to the resources/views/vendor/mail directory. The mail directory will contain a html and a markdown directory, each containing their respective representations of every available component. You are free to customize these components however you like.

43.5.3.1 Customizing The CSS

After exporting the components, the resources/views/vendor/mail/html/themes directory will contain a default.css file. You may customize the CSS in this file and your styles will automatically be in-lined within the HTML representations of your Markdown notifications.

{tip} If you would like to build an entirely new theme for the Markdown components, simply write a new CSS file within the html/themes directory and change the theme option of your mail configuration file.

<a name=“database-notifications”></a>

43.6 Database Notifications

<a name=“database-prerequisites”></a>

43.6.1 Prerequisites

The database notification channel stores the notification information in a database table. This table will contain information such as the notification type as well as custom JSON data that describes the notification.

You can query the table to display the notifications in your application’s user interface. But, before you can do that, you will need to create a database table to hold your notifications. You may use the notifications:table command to generate a migration with the proper table schema:

php artisan notifications:table

php artisan migrate

<a name=“formatting-database-notifications”></a>

43.6.2 Formatting Database Notifications

If a notification supports being stored in a database table, you should define a toDatabase or toArray method on the notification class. This method will receive a $notifiable entity and should return a plain PHP array. The returned array will be encoded as JSON and stored in the data column of your notifications table. Let’s take a look at an example toArray method:

/**
 * Get the array representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toArray($notifiable)
{
    return [
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ];
}

43.6.2.1 toDatabase Vs. toArray

The toArray method is also used by the broadcast channel to determine which data to broadcast to your JavaScript client. If you would like to have two different array representations for the database and broadcast channels, you should define a toDatabase method instead of a toArray method.

<a name=“accessing-the-notifications”></a>

43.6.3 Accessing The Notifications

Once notifications are stored in the database, you need a convenient way to access them from your notifiable entities. The Illuminate\Notifications\Notifiable trait, which is included on Laravel’s default App\User model, includes a notifications Eloquent relationship that returns the notifications for the entity. To fetch notifications, you may access this method like any other Eloquent relationship. By default, notifications will be sorted by the created_at timestamp:

$user = App\User::find(1);

foreach ($user->notifications as $notification) {
    echo $notification->type;
}

If you want to retrieve only the “unread” notifications, you may use the unreadNotifications relationship. Again, these notifications will be sorted by the created_at timestamp:

$user = App\User::find(1);

foreach ($user->unreadNotifications as $notification) {
    echo $notification->type;
}

{tip} To access your notifications from your JavaScript client, you should define a notification controller for your application which returns the notifications for a notifiable entity, such as the current user. You may then make an HTTP request to that controller’s URI from your JavaScript client.

<a name=“marking-notifications-as-read”></a>

43.6.4 Marking Notifications As Read

Typically, you will want to mark a notification as “read” when a user views it. The Illuminate\Notifications\Notifiable trait provides a markAsRead method, which updates the read_at column on the notification’s database record:

$user = App\User::find(1);

foreach ($user->unreadNotifications as $notification) {
    $notification->markAsRead();
}

However, instead of looping through each notification, you may use the markAsRead method directly on a collection of notifications:

$user->unreadNotifications->markAsRead();

You may also use a mass-update query to mark all of the notifications as read without retrieving them from the database:

$user = App\User::find(1);

$user->unreadNotifications()->update(['read_at' => Carbon::now()]);

Of course, you may delete the notifications to remove them from the table entirely:

$user->notifications()->delete();

<a name=“broadcast-notifications”></a>

43.7 Broadcast Notifications

<a name=“broadcast-prerequisites”></a>

43.7.1 Prerequisites

Before broadcasting notifications, you should configure and be familiar with Laravel’s event broadcasting services. Event broadcasting provides a way to react to server-side fired Laravel events from your JavaScript client.

<a name=“formatting-broadcast-notifications”></a>

43.7.2 Formatting Broadcast Notifications

The broadcast channel broadcasts notifications using Laravel’s event broadcasting services, allowing your JavaScript client to catch notifications in realtime. If a notification supports broadcasting, you should define a toBroadcast method on the notification class. This method will receive a $notifiable entity and should return a BroadcastMessage instance. The returned data will be encoded as JSON and broadcast to your JavaScript client. Let’s take a look at an example toBroadcast method:

use Illuminate\Notifications\Messages\BroadcastMessage;

/**
 * Get the broadcastable representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return BroadcastMessage
 */
public function toBroadcast($notifiable)
{
    return new BroadcastMessage([
        'invoice_id' => $this->invoice->id,
        'amount' => $this->invoice->amount,
    ]);
}

43.7.2.1 Broadcast Queue Configuration

All broadcast notifications are queued for broadcasting. If you would like to configure the queue connection or queue name that is used to the queue the broadcast operation, you may use the onConnection and onQueue methods of the BroadcastMessage:

return (new BroadcastMessage($data))
                ->onConnection('sqs')
                ->onQueue('broadcasts');

{tip} In addition to the data you specify, broadcast notifications will also contain a type field containing the class name of the notification.

<a name=“listening-for-notifications”></a>

43.7.3 Listening For Notifications

Notifications will broadcast on a private channel formatted using a {notifiable}.{id} convention. So, if you are sending a notification to a App\User instance with an ID of 1, the notification will be broadcast on the App.User.1 private channel. When using Laravel Echo, you may easily listen for notifications on a channel using the notification helper method:

Echo.private('App.User.' + userId)
    .notification((notification) => {
        console.log(notification.type);
    });

43.7.3.1 Customizing The Notification Channel

If you would like to customize which channels a notifiable entity receives its broadcast notifications on, you may define a receivesBroadcastNotificationsOn method on the notifiable entity:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The channels the user receives notification broadcasts on.
     *
     * @return string
     */
    public function receivesBroadcastNotificationsOn()
    {
        return 'users.'.$this->id;
    }
}

<a name=“sms-notifications”></a>

43.8 SMS Notifications

<a name=“sms-prerequisites”></a>

43.8.1 Prerequisites

Sending SMS notifications in Laravel is powered by Nexmo. Before you can send notifications via Nexmo, you need to install the nexmo/client Composer package and add a few configuration options to your config/services.php configuration file. You may copy the example configuration below to get started:

'nexmo' => [
    'key' => env('NEXMO_KEY'),
    'secret' => env('NEXMO_SECRET'),
    'sms_from' => '15556666666',
],

The sms_from option is the phone number that your SMS messages will be sent from. You should generate a phone number for your application in the Nexmo control panel.

<a name=“formatting-sms-notifications”></a>

43.8.2 Formatting SMS Notifications

If a notification supports being sent as a SMS, you should define a toNexmo method on the notification class. This method will receive a $notifiable entity and should return a Illuminate\Notifications\Messages\NexmoMessage instance:

/**
 * Get the Nexmo / SMS representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content');
}

43.8.2.1 Unicode Content

If your SMS message will contain unicode characters, you should call the unicode method when constructing the NexmoMessage instance:

/**
 * Get the Nexmo / SMS representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your unicode message')
                ->unicode();
}

<a name=“customizing-the-from-number”></a>

43.8.3 Customizing The “From” Number

If you would like to send some notifications from a phone number that is different from the phone number specified in your config/services.php file, you may use the from method on a NexmoMessage instance:

/**
 * Get the Nexmo / SMS representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return NexmoMessage
 */
public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content')
                ->from('15554443333');
}

<a name=“routing-sms-notifications”></a>

43.8.4 Routing SMS Notifications

When sending notifications via the nexmo channel, the notification system will automatically look for a phone_number attribute on the notifiable entity. If you would like to customize the phone number the notification is delivered to, define a routeNotificationForNexmo method on the entity:

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Route notifications for the Nexmo channel.
     *
     * @return string
     */
    public function routeNotificationForNexmo()
    {
        return $this->phone;
    }
}

<a name=“slack-notifications”></a>

43.9 Slack Notifications

<a name=“slack-prerequisites”></a>

43.9.1 Prerequisites

Before you can send notifications via Slack, you must install the Guzzle HTTP library via Composer:

composer require guzzlehttp/guzzle

You will also need to configure an “Incoming Webhook” integration for your Slack team. This integration will provide you with a URL you may use when routing Slack notifications.

<a name=“formatting-slack-notifications”></a>

43.9.2 Formatting Slack Notifications

If a notification supports being sent as a Slack message, you should define a toSlack method on the notification class. This method will receive a $notifiable entity and should return a Illuminate\Notifications\Messages\SlackMessage instance. Slack messages may contain text content as well as an “attachment” that formats additional text or an array of fields. Let’s take a look at a basic toSlack example:

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->content('One of your invoices has been paid!');
}

In this example we are just sending a single line of text to Slack, which will create a message that looks like the following:

<img src=“https://laravel.com/assets/img/basic-slack-notification.png”>

43.9.2.1 Customizing The Sender & Recipient

You may use the from and to methods to customize the sender and recipient. The from method accepts a username and emoji identifier, while the to method accepts a channel or username:

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->from('Ghost', ':ghost:')
                ->to('#other')
                ->content('This will be sent to #other');
}

You may also use an image as your logo instead of an emoji:

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
                ->from('Laravel')
                ->image('https://laravel.com/favicon.png')
                ->content('This will display the Laravel logo next to the message');
}

<a name=“slack-attachments”></a>

43.9.3 Slack Attachments

You may also add “attachments” to Slack messages. Attachments provide richer formatting options than simple text messages. In this example, we will send an error notification about an exception that occurred in an application, including a link to view more details about the exception:

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/exceptions/'.$this->exception->id);

    return (new SlackMessage)
                ->error()
                ->content('Whoops! Something went wrong.')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Exception: File Not Found', $url)
                               ->content('File [background.jpg] was not found.');
                });
}

The example above will generate a Slack message that looks like the following:

<img src=“https://laravel.com/assets/img/basic-slack-attachment.png”>

Attachments also allow you to specify an array of data that should be presented to the user. The given data will be presented in a table-style format for easy reading:

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/invoices/'.$this->invoice->id);

    return (new SlackMessage)
                ->success()
                ->content('One of your invoices has been paid!')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Invoice 1322', $url)
                               ->fields([
                                    'Title' => 'Server Expenses',
                                    'Amount' => '$1,234',
                                    'Via' => 'American Express',
                                    'Was Overdue' => ':-1:',
                                ]);
                });
}

The example above will create a Slack message that looks like the following:

<img src=“https://laravel.com/assets/img/slack-fields-attachment.png”>

43.9.3.1 Markdown Attachment Content

If some of your attachment fields contain Markdown, you may use the markdown method to instruct Slack to parse and display the given attachment fields as Markdown formatted text. The values accepted by this method are: pretext, text, and / or fields. For more information about Slack attachment formatting, check out the Slack API documentation:

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    $url = url('/exceptions/'.$this->exception->id);

    return (new SlackMessage)
                ->error()
                ->content('Whoops! Something went wrong.')
                ->attachment(function ($attachment) use ($url) {
                    $attachment->title('Exception: File Not Found', $url)
                               ->content('File [background.jpg] was *not found*.')
                               ->markdown(['text']);
                });
}

<a name=“routing-slack-notifications”></a>

43.9.4 Routing Slack Notifications

To route Slack notifications to the proper location, define a routeNotificationForSlack method on your notifiable entity. This should return the webhook URL to which the notification should be delivered. Webhook URLs may be generated by adding an “Incoming Webhook” service to your Slack team:

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Route notifications for the Slack channel.
     *
     * @return string
     */
    public function routeNotificationForSlack()
    {
        return $this->slack_webhook_url;
    }
}

<a name=“notification-events”></a>

43.10 Notification Events

When a notification is sent, the Illuminate\Notifications\Events\NotificationSent event is fired by the notification system. This contains the “notifiable” entity and the notification instance itself. You may register listeners for this event in your EventServiceProvider:

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Notifications\Events\NotificationSent' => [
        'App\Listeners\LogNotification',
    ],
];

{tip} After registering listeners in your EventServiceProvider, use the event:generate Artisan command to quickly generate listener classes.

Within an event listener, you may access the notifiable, notification, and channel properties on the event to learn more about the notification recipient or the notification itself:

/**
 * Handle the event.
 *
 * @param  NotificationSent  $event
 * @return void
 */
public function handle(NotificationSent $event)
{
    // $event->channel
    // $event->notifiable
    // $event->notification
}

<a name=“custom-channels”></a>

43.11 Custom Channels

Laravel ships with a handful of notification channels, but you may want to write your own drivers to deliver notifications via other channels. Laravel makes it simple. To get started, define a class that contains a send method. The method should receive two arguments: a $notifiable and a $notification:

<?php

namespace App\Channels;

use Illuminate\Notifications\Notification;

class VoiceChannel
{
    /**
     * Send the given notification.
     *
     * @param  mixed  $notifiable
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return void
     */
    public function send($notifiable, Notification $notification)
    {
        $message = $notification->toVoice($notifiable);

        // Send notification to the $notifiable instance...
    }
}

Once your notification channel class has been defined, you may simply return the class name from the via method of any of your notifications:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use App\Channels\VoiceChannel;
use App\Channels\Messages\VoiceMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;

class InvoicePaid extends Notification
{
    use Queueable;

    /**
     * Get the notification channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return [VoiceChannel::class];
    }

    /**
     * Get the voice representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return VoiceMessage
     */
    public function toVoice($notifiable)
    {
        // ...
    }
}

44 Package Development

<a name=“introduction”></a>

44.1 Introduction

Packages are the primary way of adding functionality to Laravel. Packages might be anything from a great way to work with dates like Carbon, or an entire BDD testing framework like Behat.

Of course, there are different types of packages. Some packages are stand-alone, meaning they work with any PHP framework. Carbon and Behat are examples of stand-alone packages. Any of these packages may be used with Laravel by simply requesting them in your composer.json file.

On the other hand, other packages are specifically intended for use with Laravel. These packages may have routes, controllers, views, and configuration specifically intended to enhance a Laravel application. This guide primarily covers the development of those packages that are Laravel specific.

<a name=“a-note-on-facades”></a>

44.1.1 A Note On Facades

When writing a Laravel application, it generally does not matter if you use contracts or facades since both provide essentially equal levels of testability. However, when writing packages, your package will not typically have access to all of Laravel’s testing helpers. If you would like to be able to write your package tests as if they existed inside a typical Laravel application, you may use the Orchestral Testbench package.

<a name=“package-discovery”></a>

44.2 Package Discovery

In a Laravel application’s config/app.php configuration file, the providers option defines a list of service providers that should be loaded by Laravel. When someone installs your package, you will typically want your service provider to be included in this list. Instead of requiring users to manually add your service provider to the list, you may define the provider in the extra section of your package’s composer.json file. In addition to service providers, you may also list any facades you would like to be registered:

"extra": {
    "laravel": {
        "providers": [
            "Barryvdh\\Debugbar\\ServiceProvider"
        ],
        "aliases": {
            "Debugbar": "Barryvdh\\Debugbar\\Facade"
        }
    }
},

Once your package has been configured for discovery, Laravel will automatically register its service providers and facades when it is installed, creating a convenient installation experience for your package’s users.

44.2.1 Opting Out Of Package Discovery

If you are the consumer of a package and would like to disable package discovery for a package, you may list the package name in the extra section of your application’s composer.json file:

"extra": {
    "laravel": {
        "dont-discover": [
            "barryvdh/laravel-debugbar"
        ]
    }
},

You may disable package discovery for all packages using the * character inside of your application’s dont-discover directive:

"extra": {
    "laravel": {
        "dont-discover": [
            "*"
        ]
    }
},

<a name=“service-providers”></a>

44.3 Service Providers

Service providers are the connection points between your package and Laravel. A service provider is responsible for binding things into Laravel’s service container and informing Laravel where to load package resources such as views, configuration, and localization files.

A service provider extends the Illuminate\Support\ServiceProvider class and contains two methods: register and boot. The base ServiceProvider class is located in the illuminate/support Composer package, which you should add to your own package’s dependencies. To learn more about the structure and purpose of service providers, check out their documentation.

<a name=“resources”></a>

44.4 Resources

<a name=“configuration”></a>

44.4.1 Configuration

Typically, you will need to publish your package’s configuration file to the application’s own config directory. This will allow users of your package to easily override your default configuration options. To allow your configuration files to be published, call the publishes method from the boot method of your service provider:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
    ]);
}

Now, when users of your package execute Laravel’s vendor:publish command, your file will be copied to the specified publish location. Of course, once your configuration has been published, its values may be accessed like any other configuration file:

$value = config('courier.option');

{note} You should not define Closures in your configuration files. They can not be serialized correctly when users execute the config:cache Artisan command.

44.4.1.1 Default Package Configuration

You may also merge your own package configuration file with the application’s published copy. This will allow your users to define only the options they actually want to override in the published copy of the configuration. To merge the configurations, use the mergeConfigFrom method within your service provider’s register method:

/**
 * Register bindings in the container.
 *
 * @return void
 */
public function register()
{
    $this->mergeConfigFrom(
        __DIR__.'/path/to/config/courier.php', 'courier'
    );
}

{note} This method only merges the first level of the configuration array. If your users partially define a multi-dimensional configuration array, the missing options will not be merged.

<a name=“routes”></a>

44.4.2 Routes

If your package contains routes, you may load them using the loadRoutesFrom method. This method will automatically determine if the application’s routes are cached and will not load your routes file if the routes have already been cached:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadRoutesFrom(__DIR__.'/routes.php');
}

<a name=“migrations”></a>

44.4.3 Migrations

If your package contains database migrations, you may use the loadMigrationsFrom method to inform Laravel how to load them. The loadMigrationsFrom method accepts the path to your package’s migrations as its only argument:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadMigrationsFrom(__DIR__.'/path/to/migrations');
}

Once your package’s migrations have been registered, they will automatically be run when the php artisan migrate command is executed. You do not need to export them to the application’s main database/migrations directory.

<a name=“translations”></a>

44.4.4 Translations

If your package contains translation files, you may use the loadTranslationsFrom method to inform Laravel how to load them. For example, if your package is named courier, you should add the following to your service provider’s boot method:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}

Package translations are referenced using the package::file.line syntax convention. So, you may load the courier package’s welcome line from the messages file like so:

echo trans('courier::messages.welcome');

44.4.4.1 Publishing Translations

If you would like to publish your package’s translations to the application’s resources/lang/vendor directory, you may use the service provider’s publishes method. The publishes method accepts an array of package paths and their desired publish locations. For example, to publish the translation files for the courier package, you may do the following:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');

    $this->publishes([
        __DIR__.'/path/to/translations' => resource_path('lang/vendor/courier'),
    ]);
}

Now, when users of your package execute Laravel’s vendor:publish Artisan command, your package’s translations will be published to the specified publish location.

<a name=“views”></a>

44.4.5 Views

To register your package’s views with Laravel, you need to tell Laravel where the views are located. You may do this using the service provider’s loadViewsFrom method. The loadViewsFrom method accepts two arguments: the path to your view templates and your package’s name. For example, if your package’s name is courier, you would add the following to your service provider’s boot method:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}

Package views are referenced using the package::view syntax convention. So, once your view path is registered in a service provider, you may load the admin view from the courier package like so:

Route::get('admin', function () {
    return view('courier::admin');
});

44.4.5.1 Overriding Package Views

When you use the loadViewsFrom method, Laravel actually registers two locations for your views: the application’s resources/views/vendor directory and the directory you specify. So, using the courier example, Laravel will first check if a custom version of the view has been provided by the developer in resources/views/vendor/courier. Then, if the view has not been customized, Laravel will search the package view directory you specified in your call to loadViewsFrom. This makes it easy for package users to customize / override your package’s views.

44.4.5.2 Publishing Views

If you would like to make your views available for publishing to the application’s resources/views/vendor directory, you may use the service provider’s publishes method. The publishes method accepts an array of package view paths and their desired publish locations:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');

    $this->publishes([
        __DIR__.'/path/to/views' => resource_path('views/vendor/courier'),
    ]);
}

Now, when users of your package execute Laravel’s vendor:publish Artisan command, your package’s views will be copied to the specified publish location.

<a name=“commands”></a>

44.5 Commands

To register your package’s Artisan commands with Laravel, you may use the commands method. This method expects an array of command class names. Once the commands have been registered, you may execute them using the Artisan CLI:

/**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            FooCommand::class,
            BarCommand::class,
        ]);
    }
}

<a name=“public-assets”></a>

44.6 Public Assets

Your package may have assets such as JavaScript, CSS, and images. To publish these assets to the application’s public directory, use the service provider’s publishes method. In this example, we will also add a public asset group tag, which may be used to publish groups of related assets:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/assets' => public_path('vendor/courier'),
    ], 'public');
}

Now, when your package’s users execute the vendor:publish command, your assets will be copied to the specified publish location. Since you will typically need to overwrite the assets every time the package is updated, you may use the --force flag:

php artisan vendor:publish --tag=public --force

<a name=“publishing-file-groups”></a>

44.7 Publishing File Groups

You may want to publish groups of package assets and resources separately. For instance, you might want to allow your users to publish your package’s configuration files without being forced to publish your package’s assets. You may do this by “tagging” them when calling the publishes method from a package’s service provider. For example, let’s use tags to define two publish groups in the boot method of a package service provider:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot()
{
    $this->publishes([
        __DIR__.'/../config/package.php' => config_path('package.php')
    ], 'config');

    $this->publishes([
        __DIR__.'/../database/migrations/' => database_path('migrations')
    ], 'migrations');
}

Now your users may publish these groups separately by referencing their tag when executing the vendor:publish command:

php artisan vendor:publish --tag=config

45 Queues

<a name=“introduction”></a>

45.1 Introduction

{tip} Laravel now offers Horizon, a beautiful dashboard and configuration system for your Redis powered queues. Check out the full Horizon documentation for more information.

Laravel queues provide a unified API across a variety of different queue backends, such as Beanstalk, Amazon SQS, Redis, or even a relational database. Queues allow you to defer the processing of a time consuming task, such as sending an email, until a later time. Deferring these time consuming tasks drastically speeds up web requests to your application.

The queue configuration file is stored in config/queue.php. In this file you will find connection configurations for each of the queue drivers that are included with the framework, which includes a database, Beanstalkd, Amazon SQS, Redis, and a synchronous driver that will execute jobs immediately (for local use). A null queue driver is also included which simply discards queued jobs.

<a name=“connections-vs-queues”></a>

45.1.1 Connections Vs. Queues

Before getting started with Laravel queues, it is important to understand the distinction between “connections” and “queues”. In your config/queue.php configuration file, there is a connections configuration option. This option defines a particular connection to a backend service such as Amazon SQS, Beanstalk, or Redis. However, any given queue connection may have multiple “queues” which may be thought of as different stacks or piles of queued jobs.

Note that each connection configuration example in the queue configuration file contains a queue attribute. This is the default queue that jobs will be dispatched to when they are sent to a given connection. In other words, if you dispatch a job without explicitly defining which queue it should be dispatched to, the job will be placed on the queue that is defined in the queue attribute of the connection configuration:

// This job is sent to the default queue...
Job::dispatch();

// This job is sent to the "emails" queue...
Job::dispatch()->onQueue('emails');

Some applications may not need to ever push jobs onto multiple queues, instead preferring to have one simple queue. However, pushing jobs to multiple queues can be especially useful for applications that wish to prioritize or segment how jobs are processed, since the Laravel queue worker allows you to specify which queues it should process by priority. For example, if you push jobs to a high queue, you may run a worker that gives them higher processing priority:

php artisan queue:work --queue=high,default

<a name=“driver-prerequisites”></a>

45.1.2 Driver Prerequisites

45.1.2.1 Database

In order to use the database queue driver, you will need a database table to hold the jobs. To generate a migration that creates this table, run the queue:table Artisan command. Once the migration has been created, you may migrate your database using the migrate command:

php artisan queue:table

php artisan migrate

45.1.2.2 Redis

In order to use the redis queue driver, you should configure a Redis database connection in your config/database.php configuration file.

If your Redis queue connection uses a Redis Cluster, your queue names must contain a key hash tag. This is required in order to ensure all of the Redis keys for a given queue are placed into the same hash slot:

'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => '{default}',
    'retry_after' => 90,
],

45.1.2.3 Other Driver Prerequisites

The following dependencies are needed for the listed queue drivers:

<div class=“content-list” markdown=“1”>

  • Amazon SQS: aws/aws-sdk-php ~3.0
  • Beanstalkd: pda/pheanstalk ~3.0
  • Redis: predis/predis ~1.0
    </div>

<a name=“creating-jobs”></a>

45.2 Creating Jobs

<a name=“generating-job-classes”></a>

45.2.1 Generating Job Classes

By default, all of the queueable jobs for your application are stored in the app/Jobs directory. If the app/Jobs directory doesn’t exist, it will be created when you run the make:job Artisan command. You may generate a new queued job using the Artisan CLI:

php artisan make:job SendReminderEmail

The generated class will implement the Illuminate\Contracts\Queue\ShouldQueue interface, indicating to Laravel that the job should be pushed onto the queue to run asynchronously.

<a name=“class-structure”></a>

45.2.2 Class Structure

Job classes are very simple, normally containing only a handle method which is called when the job is processed by the queue. To get started, let’s take a look at an example job class. In this example, we’ll pretend we manage a podcast publishing service and need to process the uploaded podcast files before they are published:

<?php

namespace App\Jobs;

use App\Podcast;
use App\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ProcessPodcast implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $podcast;

    /**
     * Create a new job instance.
     *
     * @param  Podcast  $podcast
     * @return void
     */
    public function __construct(Podcast $podcast)
    {
        $this->podcast = $podcast;
    }

    /**
     * Execute the job.
     *
     * @param  AudioProcessor  $processor
     * @return void
     */
    public function handle(AudioProcessor $processor)
    {
        // Process uploaded podcast...
    }
}

In this example, note that we were able to pass an Eloquent model directly into the queued job’s constructor. Because of the SerializesModels trait that the job is using, Eloquent models will be gracefully serialized and unserialized when the job is processing. If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance from the database. It’s all totally transparent to your application and prevents issues that can arise from serializing full Eloquent model instances.

The handle method is called when the job is processed by the queue. Note that we are able to type-hint dependencies on the handle method of the job. The Laravel service container automatically injects these dependencies.

{note} Binary data, such as raw image contents, should be passed through the base64_encode function before being passed to a queued job. Otherwise, the job may not properly serialize to JSON when being placed on the queue.

<a name=“dispatching-jobs”></a>

45.3 Dispatching Jobs

Once you have written your job class, you may dispatch it using the dispatch method on the job itself. The arguments passed to the dispatch method will be given to the job’s constructor:

<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PodcastController extends Controller
{
    /**
     * Store a new podcast.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Create podcast...

        ProcessPodcast::dispatch($podcast);
    }
}

<a name=“delayed-dispatching”></a>

45.3.1 Delayed Dispatching

If you would like to delay the execution of a queued job, you may use the delay method when dispatching a job. For example, let’s specify that a job should not be available for processing until 10 minutes after it has been dispatched:

<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PodcastController extends Controller
{
    /**
     * Store a new podcast.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Create podcast...

        ProcessPodcast::dispatch($podcast)
                ->delay(Carbon::now()->addMinutes(10));
    }
}

{note} The Amazon SQS queue service has a maximum delay time of 15 minutes.

<a name=“job-chaining”></a>

45.3.2 Job Chaining

Job chaining allows you to specify a list of queued jobs that should be run in sequence. If one job in the sequence fails, the rest of the jobs will not be run. To execute a queued job chain, you may use the withChain method on any of your dispatchable jobs:

ProcessPodcast::withChain([
    new OptimizePodcast,
    new ReleasePodcast
])->dispatch();

<a name=“customizing-the-queue-and-connection”></a>

45.3.3 Customizing The Queue & Connection

45.3.3.1 Dispatching To A Particular Queue

By pushing jobs to different queues, you may “categorize” your queued jobs and even prioritize how many workers you assign to various queues. Keep in mind, this does not push jobs to different queue “connections” as defined by your queue configuration file, but only to specific queues within a single connection. To specify the queue, use the onQueue method when dispatching the job:

<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PodcastController extends Controller
{
    /**
     * Store a new podcast.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Create podcast...

        ProcessPodcast::dispatch($podcast)->onQueue('processing');
    }
}

45.3.3.2 Dispatching To A Particular Connection

If you are working with multiple queue connections, you may specify which connection to push a job to. To specify the connection, use the onConnection method when dispatching the job:

<?php

namespace App\Http\Controllers;

use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PodcastController extends Controller
{
    /**
     * Store a new podcast.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Create podcast...

        ProcessPodcast::dispatch($podcast)->onConnection('sqs');
    }
}

Of course, you may chain the onConnection and onQueue methods to specify the connection and the queue for a job:

ProcessPodcast::dispatch($podcast)
              ->onConnection('sqs')
              ->onQueue('processing');

<a name=“max-job-attempts-and-timeout”></a>

45.3.4 Specifying Max Job Attempts / Timeout Values

45.3.4.1 Max Attempts

One approach to specifying the maximum number of times a job may be attempted is via the --tries switch on the Artisan command line:

php artisan queue:work --tries=3

However, you may take a more granular approach by defining the maximum number of attempts on the job class itself. If the maximum number of attempts is specified on the job, it will take precedence over the value provided on the command line:

<?php

namespace App\Jobs;

class ProcessPodcast implements ShouldQueue
{
    /**
     * The number of times the job may be attempted.
     *
     * @var int
     */
    public $tries = 5;
}

<a name=“time-based-attempts”></a>

45.3.4.2 Time Based Attempts

As an alternative to defining how many times a job may be attempted before it fails, you may define a time at which the job should timeout. This allows a job to be attempted any number of times within a given time frame. To define the time at which a job should timeout, add a retryUntil method to your job class:

/**
 * Determine the time at which the job should timeout.
 *
 * @return \DateTime
 */
public function retryUntil()
{
    return now()->addSeconds(5);
}

{tip} You may also define a retryUntil method on your queued event listeners.

45.3.4.3 Timeout

{note} The timeout feature is optimized for PHP 7.1+ and the pcntl PHP extension.

Likewise, the maximum number of seconds that jobs can run may be specified using the --timeout switch on the Artisan command line:

php artisan queue:work --timeout=30

However, you may also define the maximum number of seconds a job should be allowed to run on the job class itself. If the timeout is specified on the job, it will take precedence over any timeout specified on the command line:

<?php

namespace App\Jobs;

class ProcessPodcast implements ShouldQueue
{
    /**
     * The number of seconds the job can run before timing out.
     *
     * @var int
     */
    public $timeout = 120;
}

<a name=“rate-limiting”></a>

45.3.5 Rate Limiting

{note} This feature requires that your application can interact with a Redis server.

If your application interacts with Redis, you may throttle your queued jobs by time or concurrency. This feature can be of assistance when your queued jobs are interacting with APIs that are also rate limited. For example, using the throttle method, you may throttle a given type of job to only run 10 times every 60 seconds. If a lock can not be obtained, you should typically release the job back onto the queue so it can be retried later:

Redis::throttle('key')->allow(10)->every(60)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});

{tip} In the example above, the key may be any string that uniquely identifies the type of job you would like to rate limit. For example, you may wish to construct the key based on the class name of the job and the IDs of the Eloquent models it operates on.

Alternatively, you may specify the maximum number of workers that may simultaneously process a given job. This can be helpful when a queued job is modifying a resource that should only be modified by one job at a time. For example, using the funnel method, you may limit jobs of a given type to only be processed by one worker at a time:

Redis::funnel('key')->limit(1)->then(function () {
    // Job logic...
}, function () {
    // Could not obtain lock...

    return $this->release(10);
});

{tip} When using rate limiting, the number of attempts your job will need to run successfully can be hard to determine. Therefore, it is useful to combine rate limiting with time based attempts.

<a name=“error-handling”></a>

45.3.6 Error Handling

If an exception is thrown while the job is being processed, the job will automatically be released back onto the queue so it may be attempted again. The job will continue to be released until it has been attempted the maximum number of times allowed by your application. The maximum number of attempts is defined by the --tries switch used on the queue:work Artisan command. Alternatively, the maximum number of attempts may be defined on the job class itself. More information on running the queue worker can be found below.

<a name=“running-the-queue-worker”></a>

45.4 Running The Queue Worker

Laravel includes a queue worker that will process new jobs as they are pushed onto the queue. You may run the worker using the queue:work Artisan command. Note that once the queue:work command has started, it will continue to run until it is manually stopped or you close your terminal:

php artisan queue:work

{tip} To keep the queue:work process running permanently in the background, you should use a process monitor such as Supervisor to ensure that the queue worker does not stop running.

Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers.

45.4.0.1 Processing A Single Job

The --once option may be used to instruct the worker to only process a single job from the queue:

php artisan queue:work --once

45.4.0.2 Specifying The Connection & Queue

You may also specify which queue connection the worker should utilize. The connection name passed to the work command should correspond to one of the connections defined in your config/queue.php configuration file:

php artisan queue:work redis

You may customize your queue worker even further by only processing particular queues for a given connection. For example, if all of your emails are processed in an emails queue on your redis queue connection, you may issue the following command to start a worker that only processes only that queue:

php artisan queue:work redis --queue=emails

45.4.0.3 Resource Considerations

Daemon queue workers do not “reboot” the framework before processing each job. Therefore, you should free any heavy resources after each job completes. For example, if you are doing image manipulation with the GD library, you should free the memory with imagedestroy when you are done.

<a name=“queue-priorities”></a>

45.4.1 Queue Priorities

Sometimes you may wish to prioritize how your queues are processed. For example, in your config/queue.php you may set the default queue for your redis connection to low. However, occasionally you may wish to push a job to a high priority queue like so:

dispatch((new Job)->onQueue('high'));

To start a worker that verifies that all of the high queue jobs are processed before continuing to any jobs on the low queue, pass a comma-delimited list of queue names to the work command:

php artisan queue:work --queue=high,low

<a name=“queue-workers-and-deployment”></a>

45.4.2 Queue Workers & Deployment

Since queue workers are long-lived processes, they will not pick up changes to your code without being restarted. So, the simplest way to deploy an application using queue workers is to restart the workers during your deployment process. You may gracefully restart all of the workers by issuing the queue:restart command:

php artisan queue:restart

This command will instruct all queue workers to gracefully “die” after they finish processing their current job so that no existing jobs are lost. Since the queue workers will die when the queue:restart command is executed, you should be running a process manager such as Supervisor to automatically restart the queue workers.

{tip} The queue uses th