Database migration: laravel

Introduction
Migrations are like version control for your database, allowing your team to easily modify and share the application’s database schema. Migrations are typically paired with Laravel’s schema builder to easily build your application’s database schema. If you have ever had to tell a teammate to manually add a column to their local database schema, you’ve faced the problem that database migrations solve.

The Laravel Schema facade provides database agnostic support for creating and manipulating tables across all of Laravel’s supported database systems.

Generating Migrations
To create a migration, use the make:migration Artisan command:

php artisan make:migration create_users_table

The new migration will be placed in your database/migrations directory. Each migration file name contains a timestamp which allows Laravel to determine the order of the migrations.

The –table and –create options may also be used to indicate the name of the table and whether the migration will be creating a new table. These options pre-fill the generated migration stub file with the specified table:

php artisan make:migration create_users_table --create=users

php artisan make:migration add_votes_to_users_table --table=users

If you would like to specify a custom output path for the generated migration, you may use the –path option when executing the make:migration command. The given path should be relative to your application’s base path.

Migration Structure
A migration class contains two methods: up and down. The up method is used to add new tables, columns, or indexes to your database, while the down method should reverse the operations performed by the up method.

Within both of these methods you may use the Laravel schema builder to expressively create and modify tables. To learn about all of the methods available on the Schema builder, check out its documentation. For example, this migration example creates a flights table:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateFlightsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('flights');
    }
}

Running Migrations
To run all of your outstanding migrations, execute the migrate Artisan command:
php artisan migrate

Forcing Migrations To Run In Production
Some migration operations are destructive, which means they may cause you to lose data. In order to protect you from running these commands against your production database, you will be prompted for confirmation before the commands are executed. To force the commands to run without a prompt, use the –force flag:
php artisan migrate –force

To rollback the latest migration operation, you may use the rollback command. This command rolls back the last “batch” of migrations, which may include multiple migration files:

php artisan migrate:rollback
You may rollback a limited number of migrations by providing the step option to the rollback command. For example, the following command will rollback the last five migrations:

php artisan migrate:rollback –step=5
The migrate:reset command will roll back all of your application’s migrations:

php artisan migrate:reset

Rollback & Migrate In Single Command
The migrate:refresh command will roll back all of your migrations and then execute the migrate command. This command effectively re-creates your entire database:

php artisan migrate:refresh

// Refresh the database and run all database seeds…
php artisan migrate:refresh –seed
You may rollback & re-migrate a limited number of migrations by providing the step option to the refresh command. For example, the following command will rollback & re-migrate the last five migrations:
php artisan migrate:refresh –step=5

Drop All Tables & Migrate
The migrate:fresh command will drop all tables from the database and then execute the migrate command:

php artisan migrate:fresh

php artisan migrate:fresh –seed

Creating Tables
To create a new database table, use the create method on the Schema facade. The create method accepts two arguments. The first is the name of the table, while the second is a Closure which receives a Blueprint object that may be used to define the new table:

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
});

Database Connection & Table Options
If you want to perform a schema operation on a database connection that is not your default connection, use the connection method:

Schema::connection(‘foo’)->create(‘users’, function (Blueprint $table) {
$table->increments(‘id’);
});

Command Description
$table->engine = ‘InnoDB’; Specify the table storage engine (MySQL).
$table->charset = ‘utf8’; Specify a default character set for the table (MySQL).
$table->collation = ‘utf8_unicode_ci’; Specify a default collation for the table (MySQL).
$table->temporary(); Create a temporary table (except SQL Server).

Creating Columns
The table method on the Schema facade may be used to update existing tables. Like the create method, the table method accepts two arguments: the name of the table and a Closure that receives a Blueprint instance you may use to add columns to the table:
Schema::table(‘users’, function (Blueprint $table) {
$table->string(’email’);
});

Available Column Types
Of course, the schema builder contains a variety of column types that you may specify when building your tables:

Command Description
$table->bigIncrements(‘id’); Auto-incrementing UNSIGNED BIGINT (primary key) equivalent column.
$table->bigInteger(‘votes’); BIGINT equivalent column.
$table->binary(‘data’); BLOB equivalent column.
$table->boolean(‘confirmed’); BOOLEAN equivalent column.
$table->char(‘name’, 100); CHAR equivalent column with an optional length.
$table->date(‘created_at’); DATE equivalent column.
$table->dateTime(‘created_at’); DATETIME equivalent column.
$table->dateTimeTz(‘created_at’); DATETIME (with timezone) equivalent column.
$table->decimal(‘amount’, 8, 2); DECIMAL equivalent column with a precision (total digits) and scale (decimal digits).
$table->double(‘amount’, 8, 2); DOUBLE equivalent column with a precision (total digits) and scale (decimal digits).
$table->enum(‘level’, [‘easy’, ‘hard’]); ENUM equivalent column.
$table->float(‘amount’, 8, 2); FLOAT equivalent column with a precision (total digits) and scale (decimal digits).
$table->geometry(‘positions’); GEOMETRY equivalent column.
$table->geometryCollection(‘positions’); GEOMETRYCOLLECTION equivalent column.
$table->increments(‘id’); Auto-incrementing UNSIGNED INTEGER (primary key) equivalent column.
$table->integer(‘votes’); INTEGER equivalent column.
$table->ipAddress(‘visitor’); IP address equivalent column.
$table->json(‘options’); JSON equivalent column.
$table->jsonb(‘options’); JSONB equivalent column.
$table->lineString(‘positions’); LINESTRING equivalent column.
$table->longText(‘description’); LONGTEXT equivalent column.
$table->macAddress(‘device’); MAC address equivalent column.
$table->mediumIncrements(‘id’); Auto-incrementing UNSIGNED MEDIUMINT (primary key) equivalent column.
$table->mediumInteger(‘votes’); MEDIUMINT equivalent column.
$table->mediumText(‘description’); MEDIUMTEXT equivalent column.
$table->morphs(‘taggable’); Adds taggable_id UNSIGNED BIGINT and taggable_type VARCHAR equivalent columns.
$table->multiLineString(‘positions’); MULTILINESTRING equivalent column.
$table->multiPoint(‘positions’); MULTIPOINT equivalent column.
$table->multiPolygon(‘positions’); MULTIPOLYGON equivalent column.
$table->nullableMorphs(‘taggable’); Adds nullable versions of morphs() columns.
$table->nullableTimestamps(); Alias of timestamps() method.
$table->point(‘position’); POINT equivalent column.
$table->polygon(‘positions’); POLYGON equivalent column.
$table->rememberToken(); Adds a nullable remember_token VARCHAR(100) equivalent column.
$table->smallIncrements(‘id’); Auto-incrementing UNSIGNED SMALLINT (primary key) equivalent column.
$table->smallInteger(‘votes’); SMALLINT equivalent column.
$table->softDeletes(); Adds a nullable deleted_at TIMESTAMP equivalent column for soft deletes.
$table->softDeletesTz(); Adds a nullable deleted_at TIMESTAMP (with timezone) equivalent column for soft deletes.
$table->string(‘name’, 100); VARCHAR equivalent column with a optional length.
$table->text(‘description’); TEXT equivalent column.
$table->time(‘sunrise’); TIME equivalent column.
$table->timeTz(‘sunrise’); TIME (with timezone) equivalent column.
$table->timestamp(‘added_on’); TIMESTAMP equivalent column.
$table->timestampTz(‘added_on’); TIMESTAMP (with timezone) equivalent column.
$table->timestamps(); Adds nullable created_at and updated_at TIMESTAMP equivalent columns.
$table->timestampsTz(); Adds nullable created_at and updated_at TIMESTAMP (with timezone) equivalent columns.
$table->tinyIncrements(‘id’); Auto-incrementing UNSIGNED TINYINT (primary key) equivalent column.
$table->tinyInteger(‘votes’); TINYINT equivalent column.
$table->unsignedBigInteger(‘votes’); UNSIGNED BIGINT equivalent column.
$table->unsignedDecimal(‘amount’, 8, 2); UNSIGNED DECIMAL equivalent column with a precision (total digits) and scale (decimal digits).
$table->unsignedInteger(‘votes’); UNSIGNED INTEGER equivalent column.
$table->unsignedMediumInteger(‘votes’); UNSIGNED MEDIUMINT equivalent column.
$table->unsignedSmallInteger(‘votes’); UNSIGNED SMALLINT equivalent column.
$table->unsignedTinyInteger(‘votes’); UNSIGNED TINYINT equivalent column.
$table->uuid(‘id’); UUID equivalent column.
$table->year(‘birth_year’); YEAR equivalent column.

Column Modifiers
In addition to the column types listed above, there are several column “modifiers” you may use while adding a column to a database table. For example, to make the column “nullable”, you may use the nullable method:

Modifier Description
->after(‘column’) Place the column “after” another column (MySQL)
->autoIncrement() Set INTEGER columns as auto-increment (primary key)
->charset(‘utf8’) Specify a character set for the column (MySQL)
->collation(‘utf8_unicode_ci’) Specify a collation for the column (MySQL/SQL Server)
->comment(‘my comment’) Add a comment to a column (MySQL)
->default($value) Specify a “default” value for the column
->first() Place the column “first” in the table (MySQL)
->nullable($value = true) Allows (by default) NULL values to be inserted into the column
->storedAs($expression) Create a stored generated column (MySQL)
->unsigned() Set INTEGER columns as UNSIGNED (MySQL)
->useCurrent() Set TIMESTAMP columns to use CURRENT_TIMESTAMP as default value
->virtualAs($expression) Create a virtual generated column (MySQL)
->generatedAs($expression) Create an identity column with specified sequence options (PostgreSQL)
->always() Defines the precedence of sequence values over input for an identity column (PostgreSQL)

Updating Column Attributes
The change method allows you to modify some existing column types to a new type or modify the column’s attributes. For example, you may wish to increase the size of a string column. To see the change method in action, let’s increase the size of the name column from 25 to 50:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

Laravel pagenation

In other frameworks, pagination can be very painful. Laravel’s paginator is integrated with the query builder and Eloquent ORM and provides convenient, easy-to-use pagination of database results out of the box. The HTML generated by the paginator is compatible with the Bootstrap CSS framework.

Basic Usage
Paginating Query Builder Results

There are several ways to paginate items. The simplest is by using the paginate method on the query builder or an Eloquent query. The paginate method automatically takes care of setting the proper limit and offset based on the current page being viewed by the user. By default, the current page is detected by the value of the page query string argument on the HTTP request. Of course, this value is automatically detected by Laravel, and is also automatically inserted into links generated by the paginator.

In this example, the only argument passed to the paginate method is the number of items you would like displayed “per page”. In this case, let’s specify that we would like to display 15 items per page:

amespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * Show all of the users for the application.
     *
     * @return Response
     */
    public function index()
    {
        $users = DB::table('users')->paginate(15);

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

“Simple Pagination”
If you only need to display simple “Next” and “Previous” links in your pagination view, you may use the simplePaginate method to perform a more efficient query. This is very useful for large datasets when you do not need to display a link for each page number when rendering your view:

$users = DB::table(‘users’)->simplePaginate(15);

Paginating Eloquent Results
You may also paginate Eloquent queries. In this example, we will paginate the User model with 15 items per page. As you can see, the syntax is nearly identical to paginating query builder results:

$users = App\User::paginate(15);

Sometimes you may wish to create a pagination instance manually, passing it an array of items. You may do so by creating either an Illuminate\Pagination\Paginator or Illuminate\Pagination\LengthAwarePaginator instance, depending on your needs.

The Paginator class does not need to know the total number of items in the result set; however, because of this, the class does not have methods for retrieving the index of the last page. The LengthAwarePaginator accepts almost the same arguments as the Paginator; however, it does require a count of the total number of items in the result set.

In other words, the Paginator corresponds to the simplePaginate method on the query builder and Eloquent, while the LengthAwarePaginator corresponds to the paginate method.

When calling the paginate method, you will receive an instance of Illuminate\Pagination\LengthAwarePaginator. When calling the simplePaginate method, you will receive an instance of Illuminate\Pagination\Paginator. These objects provide several methods that describe the result set. In addition to these helpers methods, the paginator instances are iterators and may be looped as an array. So, once you have retrieved the results, you may display the results and render the page links using Blade:

<div class="container">
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }}
Route::get('users', function () {
    $users = App\User::paginate(15);

    $users->withPath('custom/url');

    //
});
{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            // Result Object
        },
        {
            // Result Object
        }
   ]
}

$results->count()
$results->currentPage()
$results->firstItem()
$results->hasMorePages()
$results->lastItem()
$results->lastPage() (Not available when using simplePaginate)
$results->nextPageUrl()
$results->onFirstPage()
$results->perPage()
$results->previousPageUrl()
$results->total() (Not available when using simplePaginate)
$results->url($page)

Query builder

Introduction
Laravel’s database query builder provides a convenient, fluent interface to creating and running database queries. It can be used to perform most database operations in your application and works on all supported database systems.

The Laravel query builder uses PDO parameter binding to protect your application against SQL injection attacks. There is no need to clean strings being passed as bindings.

Retrieving Results
Retrieving All Rows From A Table
You may use the table method on the DB facade to begin a query. The table method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results using the get method:

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * Show a list of all of the application's users.
     *
     * @return Response
     */
    public function index()
    {
        $users = DB::table('users')->get();

        return view('user.index', ['users' => $users]);
    }
}
foreach ($users as $user) {
    echo $user->name;
}
$user = DB::table('users')->where('name', 'John')->first();
echo $user->name;
$email = DB::table('users')->where('name', 'John')->value('email');

Retrieving A List Of Column Values
If you would like to retrieve a Collection containing the values of a single column, you may use the pluck method. In this example, we’ll retrieve a Collection of role titles:

$titles = DB::table('roles')->pluck('title');
foreach ($titles as $title) {
    echo $title;
}
$roles = DB::table('roles')->pluck('title', 'name');
foreach ($roles as $name => $title) {
    echo $title;
}

Chunking Results
If you need to work with thousands of database records, consider using the chunk method. This method retrieves a small chunk of the results at a time and feeds each chunk into a Closure for processing. This method is very useful for writing Artisan commands that process thousands of records. For example, let’s work with the entire users table in chunks of 100 records at a time:

DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    foreach ($users as $user) {
        //
    }
});
DB::table('users')->where('active', false)
    ->chunkById(100, function ($users) {
        foreach ($users as $user) {
            DB::table('users')
                ->where('id', $user->id)
                ->update(['active' => true]);
        }
    });
$users = DB::table('users')->count();
$price = DB::table('orders')->max('price');
$price = DB::table('orders')
                ->where('finalized', 1)
                ->avg('price');
$users = DB::table('users')->select('name', 'email as user_email')->get();
$users = DB::table('users')->distinct()->get();
$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();
$orders = DB::table('orders')
                ->selectRaw('price * ? as price_with_tax', [1.0825])
                ->get();
$orders = DB::table('orders')
                ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
                ->get();
$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get();

Laravel Database: Getting Started

Introduction
Laravel makes interacting with databases extremely simple across a variety of database backends using either raw SQL, the fluent query builder, and the Eloquent ORM. Currently, Laravel supports four databases:
-MySQL
-PostgreSQL
-SQLite
-SQL Server

Configuration
The database configuration for your application is located at config/database.php. In this file you may define all of your database connections, as well as specify which connection should be used by default. Examples for most of the supported database systems are provided in this file.

By default, Laravel’s sample environment configuration is ready to use with Laravel Homestead, which is a convenient virtual machine for doing Laravel development on your local machine. Of course, you are free to modify this configuration as needed for your local database.

'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
        ],

        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

        'pgsql' => [
            'driver' => 'pgsql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'schema' => 'public',
            'sslmode' => 'prefer',
        ],

        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
        ],

    ],

SQLite Configuration
After creating a new SQLite database using a command such as touch database/database.sqlite, you can easily configure your environment variables to point to this newly created database by using the database’s absolute path:

DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
'sqlite' => [
    // ...
    'foreign_key_constraints' => true,
],

Read & Write Connections
Sometimes you may wish to use one database connection for SELECT statements, and another for INSERT, UPDATE, and DELETE statements. Laravel makes this a breeze, and the proper connections will always be used whether you are using raw queries, the query builder, or the Eloquent ORM.

To see how read / write connections should be configured, let’s look at this example:

'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'    => '',
],

Note that three keys have been added to the configuration array: read, write and sticky. The read and write keys have array values containing a single key: host. The rest of the database options for the read and write connections will be merged from the main mysql array.

You only need to place items in the read and write arrays if you wish to override the values from the main array. So, in this case, 192.168.1.1 will be used as the host for the “read” connection, while 192.168.1.2 will be used for the “write” connection. The database credentials, prefix, character set, and all other options in the main mysql array will be shared across both connections.

The sticky Option
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.

Using Multiple Database Connections
When using multiple connections, you may access each connection via the connection method on the DB facade. The name passed to the connection method should correspond to one of the connections listed in your config/database.php configuration file:

$users = DB::connection('foo')->select(...);
$pdo = DB::connection()->getPdo();

Running Raw SQL Queries
Once you have configured your database connection, you may run queries using the DB facade. The DB facade provides methods for each type of query: select, update, insert, delete, and statement.

Running A Select Query
To run a basic query, you may use the select method on the DB facade:

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * Show a list of all of the application's users.
     *
     * @return Response
     */
    public function index()
    {
        $users = DB::select('select * from users where active = ?', [1]);

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

Listening For Query Events
If you would like to receive each SQL query executed by your application, you may use the listen method. This method is useful for logging queries or debugging. You may register your query listener in a service provider:

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        DB::listen(function ($query) {
            // $query->sql
            // $query->bindings
            // $query->time
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

You may use the transaction method on the DB facade to run a set of operations within a database transaction. If an exception is thrown within the transaction Closure, the transaction will automatically be rolled back. If the Closure executes successfully, the transaction will automatically be committed. You don’t need to worry about manually rolling back or committing while using the transaction method:

Laravel Task Scheduling

Introduction
In the past, you may have generated a Cron entry for each task you needed to schedule on your server. However, this can quickly become a pain, because your task schedule is no longer in source control and you must SSH into your server to add additional Cron entries.

Laravel’s command scheduler allows you to fluently and expressively define your command schedule within Laravel itself. When using the scheduler, only a single Cron entry is needed on your server. Your task schedule is defined in the app/Console/Kernel.php file’s schedule method. To help you get started, a simple example is defined within the method.

Starting The Scheduler
When using the scheduler, you only need to add the following Cron entry to your server. If you do not know how to add Cron entries to your server, consider using a service such as Laravel Forge which can manage the Cron entries for you:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

This Cron will call the Laravel command scheduler every minute. When the schedule:run command is executed, Laravel will evaluate your scheduled tasks and runs the tasks that are due.

Defining Schedules
You may define all of your scheduled tasks in the schedule method of the App\Console\Kernel class. To get started, let’s look at an example of scheduling a task. In this example, we will schedule a Closure to be called every day at midnight. Within the Closure we will execute a database query to clear a table:

namespace App\Console;

use DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            DB::table('recent_users')->delete();
        })->daily();
    }
}

In addition to scheduling using Closures, you may also use invokable objects. Invokable objects are simple PHP classes that contain an __invoke method:

$schedule->call(new DeleteRecentUsers)->daily();

Scheduling Artisan Commands
In addition to scheduling Closure calls, you may also schedule Artisan commands and operating system commands. For example, you may use the command method to schedule an Artisan command using either the command’s name or class:

$schedule->command(’emails:send –force’)->daily();
$schedule->command(EmailsCommand::class, [‘–force’])->daily();

Scheduling Queued Jobs
The job method may be used to schedule a queued job. This method provides a convenient way to schedule jobs without using the call method to manually create Closures to queue the job:

$schedule->job(new Heartbeat)->everyFiveMinutes();
// Dispatch the job to the “heartbeats” queue…
$schedule->job(new Heartbeat, ‘heartbeats’)->everyFiveMinutes();

Scheduling Shell Commands
The exec method may be used to issue a command to the operating system:
$schedule->exec(‘node /home/forge/script.js’)->daily();

Schedule Frequency Options
Of course, there are a variety of schedules you may assign to your task:

Method Description
->cron(‘* * * * *’); Run the task on a custom Cron schedule
->everyMinute(); Run the task every minute
->everyFiveMinutes(); Run the task every five minutes
->everyTenMinutes(); Run the task every ten minutes
->everyFifteenMinutes(); Run the task every fifteen minutes
->everyThirtyMinutes(); Run the task every thirty minutes
->hourly(); Run the task every hour
->hourlyAt(17); Run the task every hour at 17 mins past the hour
->daily(); Run the task every day at midnight
->dailyAt(’13:00′); Run the task every day at 13:00
->twiceDaily(1, 13); Run the task daily at 1:00 & 13:00
->weekly(); Run the task every week
->weeklyOn(1, ‘8:00′); Run the task every week on Monday at 8:00
->monthly(); Run the task every month
->monthlyOn(4, ’15:00’); Run the task every month on the 4th at 15:00
->quarterly(); Run the task every quarter
->yearly(); Run the task every year
->timezone(‘America/New_York’); Set the timezone
These methods may be combined with additional constraints to create even more finely tuned schedules that only run on certain days of the week. For example, to schedule a command to run weekly on Monday:

$schedule->call(function () {
    //
})->weekly()->mondays()->at('13:00');

// Run hourly from 8 AM to 5 PM on weekdays...
$schedule->command('foo')
          ->weekdays()
          ->hourly()
          ->timezone('America/Chicago')
          ->between('8:00', '17:00');

Below is a list of the additional schedule constraints:

Method Description
->weekdays(); Limit the task to weekdays
->sundays(); Limit the task to Sunday
->mondays(); Limit the task to Monday
->tuesdays(); Limit the task to Tuesday
->wednesdays(); Limit the task to Wednesday
->thursdays(); Limit the task to Thursday
->fridays(); Limit the task to Friday
->saturdays(); Limit the task to Saturday
->between($start, $end); Limit the task to run between start and end times
->when(Closure); Limit the task based on a truth test
->environments($env); Limit the task to specific environments

$schedule->command('reminders:send')
                    ->hourly()
                    ->between('7:00', '22:00');
$schedule->command('reminders:send')
                    ->hourly()
                    ->unlessBetween('23:00', '4:00');
$schedule->command('emails:send')->daily()->when(function () {
    return true;
});
$schedule->command('emails:send')->daily()->skip(function () {
    return true;
});
$schedule->command('report:generate')
         ->timezone('America/New_York')
         ->at('02:00')

Laravel Queues

Creating Jobs
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 ProcessPodcast
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.

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:

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.

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:

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);
    }
}

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:

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)
                ->delay(now()->addMinutes(10));
    }
}

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();

Chain Connection & Queue
If you would like to specify the default connection and queue that should be used for the chained jobs, you may use the allOnConnection and allOnQueue methods. These methods specify the queue connection and queue name that should be used unless the queued job is explicitly assigned a different connection / queue:

ProcessPodcast::withChain([
    new OptimizePodcast,
    new ReleasePodcast
])->dispatch()->allOnConnection('redis')->allOnQueue('podcasts');

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:

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');
    }
}

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:

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');
    }
}
ProcessPodcast::dispatch($podcast)
              ->onConnection('sqs')
              ->onQueue('processing');

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
namespace App\Jobs;

class ProcessPodcast implements ShouldQueue
{
    /**
     * The number of times the job may be attempted.
     *
     * @var int
     */
    public $tries = 5;
}

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:

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.

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:

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.

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

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

Processing All Queued Jobs & Then Exiting
The –stop-when-empty option may be used to instruct the worker to process all jobs and then exit gracefully. This option can be useful when working Laravel queues within a Docker container if you wish to shutdown the container after the queue is empty:

php artisan queue:work –stop-when-empty
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.

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’));
php artisan queue:work –queue=high,low

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

Dealing With Failed Jobs
Sometimes your queued jobs will fail. Don’t worry, things don’t always go as planned! Laravel includes a convenient way to specify the maximum number of times a job should be attempted. After a job has exceeded this amount of attempts, it will be inserted into the failed_jobs database table. To create a migration for the failed_jobs table, you may use the queue:failed-table command:

Laravel Queues

queueはデータ構造 データを先入れ先出しのリスト構造で保持するもの
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.

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:

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:

Redis
In order to use the redis queue driver, you should configure a Redis database connection in your config/database.php configuration file.

Redis Cluster

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

Laravel Package Development

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 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 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.

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"
        }
    }
},

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.

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:

public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
    ]);
}

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:

public function boot()
{
    $this->loadMigrationsFrom(__DIR__.'/path/to/migrations');
}

public function boot()
{
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}

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:

public function boot()
{
    if ($this->app->runningInConsole()) {
        $this->commands([
            FooCommand::class,
            BarCommand::class,
        ]);
    }
}

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:

public function boot()
{
    $this->publishes([
        __DIR__.'/path/to/assets' => public_path('vendor/courier'),
    ], 'public');
}

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:

public function boot()
{
    $this->publishes([
        __DIR__.'/../config/package.php' => config_path('package.php')
    ], 'config');

    $this->publishes([
        __DIR__.'/../database/migrations/' => database_path('migrations')
    ], 'migrations');
}

Laravel notification

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.
すげーな、こんなサイトあるんだ。
Nexmo
https://www.nexmo.com/

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
laravelからエンドユーザーにnotifyか?

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.

Sending Notifications
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:

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;
}

Authenticatable使うんか。

use App\Notifications\InvoicePaid;

$user->notify(new InvoicePaid($invoice));
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));

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.

public function via($notifiable)
{
    return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}

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:

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;

    // ...
}

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@example.com')
            ->route('nexmo', '5555555555')
            ->notify(new InvoicePaid($invoice));

Mail Notifications
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:

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!');
}

このへんはカスタマイズだ。laravelでできるってことは、別にframework使わずに自分でも作れるってことかな。

public function toMail($notifiable)
{
    return (new MailMessage)->view(
        'emails.name', ['invoice' => $this->invoice]
    );
}

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:

public function toMail($notifiable)
{
    return (new MailMessage)
                ->error()
                ->subject('Notification Subject')
                ->line('...');
}

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:

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:

public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('Notification Subject')
                ->line('...');
}

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’)

@component('mail::button', ['url' => $url, 'color' => 'green'])
View Invoice
@endcomponent

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

Database Notifications
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

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;
}

Broadcast Notifications
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.

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:

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);
    });

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',
],

Formatting SMS Notifications
If a notification supports being sent as an 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:

public function toNexmo($notifiable)
{
    return (new NexmoMessage)
                ->content('Your SMS message content');
}

Slack Notifications
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.

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.');
                });
}

Laravel Mail

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.

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

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',
],

If you are not using the “US” Mailgun region, you may define your region’s endpoint in the services configuration file:

'mailgun' => [
    'domain' => 'your-mailgun-domain',
    'secret' => 'your-mailgun-key',
    'endpoint' => 'api.eu.mailgun.net',
],

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’,
],
If necessary, you may also configure which API endpoint should be used:

‘sparkpost’ => [
‘secret’ => ‘your-sparkpost-key’,
‘options’ => [
‘endpoint’ => ‘https://api.eu.sparkpost.com/api/v1/transmissions’,
],
],

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
],
If you need to include additional options when executing the SES SendRawEmail request, you may define an options array within your ses configuration:

'ses' => [
    'key' => 'your-ses-key',
    'secret' => 'your-ses-secret',
    'region' => 'ses-region',  // e.g. us-east-1
    'options' => [
        'ConfigurationSetName' => 'MyConfigurationSet',
        'Tags' => [
            [
                'Name' => 'foo',
                'Value' => 'bar',
            ],
        ],
    ],
],

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

Configuring The Sender
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:

public function build()
{
    return $this->from('example@example.com')
                ->view('emails.orders.shipped');
}

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’],
In addition, you may define a global “reply_to” address within your config/mail.php configuration file:

‘reply_to’ => [‘address’ => ‘example@example.com’, ‘name’ => ‘App Name’],

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.

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:

public function build()
{
    return $this->view('emails.orders.shipped')
                ->text('emails.orders.shipped_plain');
}

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:

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:

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:

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,
]);
}
}

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:

 public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file');
    }

public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attach('/path/to/file', [
                        'as' => 'name.pdf',
                        'mime' => 'application/pdf',
                    ]);
    }

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:

public function build()
    {
        return $this->view('emails.orders.shipped')
                    ->attachData($this->pdf, 'name.pdf', [
                        'mime' => 'application/pdf',
                    ]);
    }
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));
    }
}