ウェブログラム

実践しながらじっくり学ぶ、Webプログラム習得サイトです。自作サービスの公開までWeb開発を実践していきましょう!

Webrogram

自分のオリジナルサービスを作って運営しよう!

【Laravel5.6】Eloquent 入門

Eloquentについて入門していきましょう。

Eloquentモデルは色々な場面で多用しますので、ぜひ覚えて置きたい技術です。 今回は初回のため簡単な触りだけ説明してみます。

Eloquentとは

Eloquentというのは、データベース上のデータをプログラムで簡単に扱えるような仕組みのことです。

これらの仕組みを総称してORM(ORマッパー)と呼んだりします。

ユーザテーブルがあったとして、プログラム上ではUserというモデルを作成し、そこからデータを引っ張ってきたり、保存したりします。 このユーザモデルというのがEloquentにあたります。

利用してみる

実際にコードをみて、どういうものなのかということを理解していきましょう。

例としてユーザモデルを利用します。 ユーザテーブルがDB上にあって、それをEloquentとして扱う場合は、Userモデルを作成します。これはクラスですが、LaravelではデフォルトでUserモデルのクラスがありますので、そのまま利用できると思います。

データを全件取得する

ユーザテーブルの全てのデータを取得するには以下のように記述します。

User::all();

これで全件取得できたことになります。 例えば、これをSQLで書いた場合は

select * from users;

となり、かなり記述は省略されるのが分かります。

検索をかける

ユーザテーブル内のデータで特定のデータのみ取得したい場合は以下のように記述します。

User::where('name', 'takeshi');

このようにすることで、nameカラムがtakeshiのデータのみ取得できます。 これをSQLで記述すると

select * from where name = "takeshi";

と同じ意味になります。

データを取得し検索をかける

Eloquentを使用すると、一度取得したデータから更に検索をかけたりすることが出来ます。 これはかなり便利なので、この機会に是非覚えて見て下さい。

// 名前がtakeshiのユーザを取得
$user = User::where('name', 'takeshi');

// 取得したユーザから更に、メールがtakeshi@gmail.comのユーザのみ取得
$user->where('email', 'takeshi@gmail.com');

こういう風に一度変数に入れたデータから、さらに検索をかけたりすることも可能です。 実は上の書き方は以下のようにまとめて書くことも出来ます(メソッドチェーンでつなぐ感じですね)。

$user = User::where('name', 'takeshi')->where('email', 'takeshi@gmail.com');

まとめて書くと良い場合や、分けて書くと良い場合、様々な場合に柔軟に対応できます。

まとめ

今回、簡単な触りのみ紹介しました また後日実際のデータを作成して、結果を見ながら高度なEloquentの使い方を学んで行きましょう。

Laravel5.6 ミドルウェアの一歩踏み込んだ使い方

前回、ミドルウェアのメリットと簡単な使いかを説明しました。 webrogram.hatenadiary.jp

前回の作成したミドルウェアとコントローラを引き続き使うので、前回の記事も見ておいて下さい。

今回は、ミドルウェアのもう一歩踏み込んだ使い方を学んでみましょう。

ミドルウェアの事後処理

前回の記事では、コントローラのアクションの前に「helloだよ」と表示する、 事前処理を試しました。

アクションの後にしたい場合は、ミドルウェアに特殊な書き方をすることで実現できます。

とはいっても、とても簡単で、

以下のように書き換えて見て下さい。

app/Http/Middleware/HelloMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;

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

        dump("helloだよ");

        return $response;
    }
}

これで以下のように表示されるはずです。

f:id:iku8:20180909180844p:plain

ルーティング時のグループ化

前回、以下のようにHelloMiddlewareを、それぞれのルートに一つずつ定義してたと思います。

// TOP画面
Route::get('/', 'IndexController@index')->middleware('hello');
// 詳細画面
Route::get('/show', 'IndexController@show')->middleware('hello');

他にも画面が増えた場合、

...->middleware('hello');という記述をたくさんしないといけなくなります。 それはかなり冗長なので、グループ化という方法で解決します。

グループ化

以下のように書き換えて下さい。

routes/web.php

Route::group(['middleware' => ['hello']], function () {
    // TOP画面
    Route::get('/', 'IndexController@index');
    // 詳細画面
    Route::get('/show', 'IndexController@show');
});

このようにすることで、group内に入っているルートに関しては、 必ずHelloMiddlewareが呼ばれるようになります。

この仕組を使えば、ログイン中の処理とか、非ログイン中の処理に対応できたりします。

routes/web.php

Route::group(['middleware' => ['auth']], function () {
    // ....ここにログイン中のルーティング
});

// .... ここに非ログイン時のルーティング(ログイン画面、新規登録画面とか)

複数のミドルウェアを指定

また、['middleware' => ['hello']]と、ミドルウェアを定義している箇所は配列になっており、

複数ミドルウェアを定義することも出来ます。

試しに、GoodbyeMiddlewareを使って試してみましょう。

php artisan make:middleware GoodbyeMiddleware

以下のように書き換えます(コメントは省略しました)。

app/Http/Middleware/GoodbyeMiddleware.php

namespace App\Http\Middleware;

use Closure;

class GoodbyeMiddleware
{
    public function handle($request, Closure $next)
    {
        dump("goodbyeだよ");
        return $next($request);
    }
}

GoodByeMiddlewareをhelloの後に登録しましょう。

app/Http/Kernel.php

    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'hello' => \App\Http\Middleware\HelloMiddleware::class, // 追加
        'goodbye' => \App\Http\Middleware\GoodbyeMiddleware::class, // 追加
    ];

これで、先程のルーティングファイルを書き換えてあげましょう。

routes/web.php

Route::group(['middleware' => ['hello', 'goodbye']], function () {
    // TOP画面
    Route::get('/', 'IndexController@index');
    // 詳細画面
    Route::get('/show', 'IndexController@show');
});

TOPページを表示してみてください。

f:id:iku8:20180909183423p:plain

このように表示出来ていれば成功です(goodbyeとhello逆な方がよかったですね)。

今回は、groupの中で2つのミドルウェアを指定しましたが、 もちろん1ルートずつ指定する箇所でも、複数のミドルウェアを指定できます。

routes/web.php

Route::get('/', 'IndexController@index')->middleware(['hello', 'goodbye']);

ミドルウェアグループの使用

上記のグループとはまた異なる、グループの仕組みがミドルウェアにはあります。

前述したグループ化はルーティング上で行うものでしたが、これから紹介するのは、 複数のミドルウェアを一つのグループとして扱う方法です。

例えば、今HelloMiddlewareとGoodbyeMiddlewareがあると思いますが、 これらをまとめて、「say」というグループ名を名付けます。

ルーティングの際にはsayだけを指定するだけ、helloもgoodbyeも呼ばれるようになります。

Kernel.phpにグループ登録

さっきまでは、$routeMiddlewareに作成した、ミドルウェアを登録していましたが、 次は$middlewareGroupsに登録します。

以下のように記述して下さい。

app/Http/Kernel.php

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        // 追加
        'say' => [
            \App\Http\Middleware\HelloMiddleware::class,
            \App\Http\Middleware\GoodbyeMiddleware::class,
        ],

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

していることは、sayというグループ名を付けて HelloMiddlewareとGoodbyeMiddlewareをそのグループに登録しています。

つまり、sayを呼び出すだけで、両方呼ばれるということですね。

では、実際にルーティングにsayを指定して、動きを見てみましょう。

routes/web.php

Route::group(['middleware' => ['say']], function () {
    // TOP画面
    Route::get('/', 'IndexController@index');
    // 詳細画面
    Route::get('/show', 'IndexController@show');
});

ブラウザから各画面を確認してみると、

f:id:iku8:20180909185207p:plain

f:id:iku8:20180909185208p:plain

これで、ミドルウェアグループもバッチリです。

強制的なミドルウェアの使用

最後に、ミドルウェアが強制的に呼ばれるようにしてみましょう。

すべてのルーティングに対して、強制的にミドルウェアを実行することも可能で、

app/Http/Kernel.phpの$routeMiddlewareでも、$middlewareGroupsでもなく、

$middlewareに登録してあげればOKです。

app/Http/Kernel.php

    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
        \App\Http\Middleware\HelloMiddleware::class,  // 追加
        \App\Http\Middleware\GoodbyeMiddleware::class, // 追加
    ];

次にルーティングで指定しているミドルウェアは取っ払ってあげましょう。

routes/web.php

// TOP画面
Route::get('/', 'IndexController@index');
// 詳細画面
Route::get('/show', 'IndexController@show');

ブラウザで確認してみると、ルーティングでミドルウェアを指定していないにもかかわらず、

「goodbyeだよ」、「helloだよ」

が表示されていると思います。

この強制的なミドルウェアはどこで約に立つかというと

例えば、IP制限したい場合などです。

「すべてのルーティングは特定のIPからしか接続できないようにする」

と、いった場合にとても効果的です。

まとめ

今回以下について、解説しました。

これだけ知っておけば、どういう状況にもほとんど対応できるかと思います。

実際に手を動かして、「あーこう設定したら、こうなるのか」と理解してみて下さい。

Laravelのミドルウェアとは?メリットと使い方も解説

Laravel入門記事一覧はこちら webrogram.hatenadiary.jp

今回はLaravelのミドルウェアについて紹介します。

ミドルウェアの利用場面は非常に多く、とても重要な仕組みなのでしっかりと抑えておきましょう。

結構簡単に利用できますよ。ミドルウェアの使い方だけ知りたい方は「ミドルウェアとは」と「ミドルウェアのメリット」は読み飛ばしちゃってください。

さて、実践していきましょう。

ミドルウェアとは

ミドルウェアというのは、コントローラのアクションが実行される前か後に、特定の処理が出来るものになります。

例えば、Userコントローラにindexアクションがあったとして、このindexアクションが実行される前に、何かの処理をしたり、 indexアクションが実行された後に、何かの処理をしたりします。

流れ的には

  1. ルーティングからUserコントローラのindexアクションが呼ばれる
  2. ミドルウェアの何らかの前処理が実行される
  3. indexアクションが実行される
  4. ミドルウェアの何らかの後処理が実行される

2、4どちらに任意の処理を挟むかは自由に選べます。

ミドルウェアのメリット

ミドルウェアがコントローラのアクションの前後で何か処理をすることが出来ると言いましたが、 では、これの何が嬉しいのか?

ログインしているかチェックに使える

例えば、ログインしている事をアクションの前処理で確認したい場合。

indexアクションを呼ばれ、TOPページが表示されるとして、 TOPページ遷移出来るのは、ログインをしている人のみとすると、 ミドルウェアでindexアクションの前処理として、ログインチェックのミドルウェアを作成し差し込みます。

これで、ログインしている人はTOPページに遷移でき、ログインしていない人はエラーページに飛ばすことなどが出来ます。

indexアクションでログインしているかチェックすれば?

確かに、ミドルウェアをいちいち挟まなくても、 そもそもindexアクションにログインしているかどうかのチェック処理を書けば良さそうです。

もちろん、これでも期待通りの結果になりますが、 indexアクション以外に、他のアクションがある場合、ミドルウェアはとても便利になります。

例えば、すべてのアクションの前にログインチェックミドルウェアを設定するだけで、 すべてのアクションで、複雑なログインチェックが出来たりします。

この他にも、このアクションとこのアクションには、このミドルウェアとこのミドルウェア、こっちのアクションは....といった具合に 柔軟にミドルウェアの差込が行えるので、非常に使いやすく、プログラムも見通しが良くなります。

ミドルウェアの設定は、ルーティングの箇所で設定します。

ミドルウェアの使い方

それでは、基本的なミドルウェアの使い方を見ていきましょう。

今回、アクションの前処理として、「helloだよ」と表示するミドルウェアを作成していきます。

コントローラとルーティング準備

IndexControllerを作成し、indexアクションと、showアクションを作成し、それぞれ文字を表示してます。

app/Http/Controllers/IndexController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class IndexController extends Controller
{
  // TOP画面
  public function index()
  {
    dump("TOP画面だよ");
  }

  // 詳細画面
  public function show()
  {
    dump("詳細画面だよ");
  }
}

ルーティングは以下の通りです。

routes/web.php

// TOP画面
Route::get('/', 'IndexController@index');
// 詳細画面
Route::get('/show', 'IndexController@show');

これで「/」にアクセスしたときは、「TOP画面だよ」と表示され、 「/show」にアクセスしたときは「詳細画面だよ」と表示されます。

ミドルウェアの作成

HelloMiddlewareを作成しましょう。 プロジェクト直下で以下のコマンドを実行してください。

php artisan make:middleware HelloMiddleware

app/Http/Middleware/HelloMiddleware.phpが作成されたと思います。 以下のように書き換えて下さい(コメントは省略しました)

namespace App\Http\Middleware;

use Closure;

class HelloMiddleware
{
    public function handle($request, Closure $next)
    {
        dump("helloだよ");
        return $next($request);
    }
}

これで、アクションの前に「helloだよ」と表示するミドルウェアが作成できました。

ミドルウェアの登録

ミドルウェアを作成することは出来ましたが、ルーティングの際に使えるようにするため、

app/Http/Kernel.phpというファイルにミドルウェアと登録します。

$routeMiddlewareの一番下に追加しました。

    // ミドルウェアに名前をつける
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'hello' => \App\Http\Middleware\HelloMiddleware::class, // 追加
    ];

これでhelloという名前で、HelloMiddlewareが使えるようになりました。

次に、ルーティングで使ってみましょう。

routes/web.php

// TOP画面
Route::get('/', 'IndexController@index')->middleware('hello');
// 詳細画面
Route::get('/show', 'IndexController@show')->middleware('hello');

これで、「/」と「/show」にアクセスしてみて下さい。

以下のように表示されれば成功です。

f:id:iku8:20180909151547p:plain

f:id:iku8:20180909151552p:plain

もっとミドルウェアについて詳しく知りたい方は以下を読んでください。

webrogram.hatenadiary.jp