20210114のlaravelに関する記事は11件です。

【Laravel】Route::resourceとは?resouceメソッドの意味と使い方

Laravelのルートで使われるRoute::resourceについて、

Route::resourceはリソースコントローラという特殊なコントローラを作成し、そのルートを登録するためのメソッド

リソースコントローラとは?

DBへのCRUD操作を行うために必要なアクション(メソッド)が定義されているコントローラ。

CRUD操作が必要なページの処理を記述するための叩き台。

▼CRUDとは?
Create(登録)、Read(読み出し)、Update(変更)、Delete(削除)の4つの機能のこと。


リソースコントローラの作成方法

$ php artisan make:controller リソースコントローラ名 --resource

--resourceはショートオプションの-rでもOK。



▼実行例

$ php artisan make:controller TestResourceController -r
Controller created successfully.

app > Http > Controllers > TestResourceController.php が生成される。

image.png

リソースコントローラの内容

メソッドの概略
(1) public function index()
(2) public function create()
(3) public function store(Request $request)
(4) public function show($id)
(5) public function edit($id)
(6) public function update(Request $request, $id)
(7) public function destroy($id)

上記の7つのアクション(メソッド)が記載されている。
実際の処理は自分で記述する。CRUD操作に必要なメソッドの側を用意してくれている。


TestResourceController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestResourceController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}


リソースルートの登録

作成したアクションのルートはRouteファサードのresourceメソッドで登録できる。

Route::resource('$URI', 'リソースコントローラー名')

web.php
Route::resource('aaas', 'TestResourceController');



▼作成したルートの確認

$ php artisan route:list

+--------+-----------+-------------------+---------------+-----------------------------------------------------+------------+
| Domain | Method    | URI               | Name          | Action                                              | Middleware |
+--------+-----------+-------------------+---------------+-----------------------------------------------------+------------+
|        | POST      | aaas              | aaas.store    | App\Http\Controllers\TestResourceController@store   | web        |
|        | GET|HEAD  | aaas              | aaas.index    | App\Http\Controllers\TestResourceController@index   | web        |
|        | GET|HEAD  | aaas/create       | aaas.create   | App\Http\Controllers\TestResourceController@create  | web        |
|        | DELETE    | aaas/{aaa}        | aaas.destroy  | App\Http\Controllers\TestResourceController@destroy | web        |
|        | PUT|PATCH | aaas/{aaa}        | aaas.update   | App\Http\Controllers\TestResourceController@update  | web        |
|        | GET|HEAD  | aaas/{aaa}        | aaas.show     | App\Http\Controllers\TestResourceController@show    | web        |
|        | GET|HEAD  | aaas/{aaa}/edit   | aaas.edit     | App\Http\Controllers\TestResourceController@edit    | web        |
+--------+-----------+-------------------+---------------+-----------------------------------------------------+------------+

各ルートに対してアクションが指定されている。

ビューを開く

あとは、各アクションの中に呼び出すビューを指定すればいい。

public function index()
    {
        return view('users');
    }

/aaasにアクセスすると、users.blade.phpが表示される。

各アクション毎に対応するビューや処理を指定していけば完了。


まとめ

Route::resourceはCRUD操作用のアクションの叩き台が記述されたコントローラー(リソースコントローラーと呼ぶ)を登録するためのメソッド。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】引数のRequest $requestとは何か?メソッドインジェクション(依存注入)

Laravelのコントローラーでメソッドの引数にクラスが指定されていることがある。これらの役割について。

▼例

public function index(Request $request){ }
public function send(RequestContactSend $request){}


メソッドインジェクション

function 関数名(Request $request)のように、関数の引数にクラス名と変数を記述すると、指定した変数に、指定したクラスのインスタンスが入る

これをメソッドインジェクション(依存注入)という。


メソッドインジェクションのメリット

メソッドインジェクションを使うメリットは、コードを簡略化できること。

▼(例)Requestクラスのallメソッドを呼び出す

メソッドインジェクションなし
public function index()
    {
        $request = new Request();
        $request->all()
    }

メソッドインジェクションあり
public function index(Request $request)
    {
        $request->all();
    }

メソッドインジェクションを使うことて、new クラス名のようにインスタンスを作成する手間を省ける。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 【php artisan db:seed】時のエラーに関して

Laravel 【php artisan db:seed】を実行した時のエラー処理に関して

【目標】
Laravelで掲示板を作成中に、ダミーデータを生成し、一覧に表示したい

【手順】
seederファイルを下記のコードで生成する

Php artisan make:seeder ファイル名

生成したseederファイルを編集後に、

Php artisan db:seed

で実行したものの、下記のようなエラーが発生した・・・

image.png

Call to undefined method App\Models\Blog::factory()とあるので、Blog フォルダの、blogファイルに問題がありそうなので検索!

【原因】
下記の記事がヒットする、、
https://teratail.com/questions/304871
記事によると、HasFactoryがModels/ blogファイルに抜けている模様。。。

下記コードのように修正

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Blog extends Model
{
    use HasFactory;      ←新たに追加

    protected $table = 'blogs';

    protected $fillable = 
    [
        'title',
        'content'
    ];
}

再度実行すると成功

Php artisan db:seed

Once you stop learning, you start dying

誰かの学習の一助になりますように

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

E-Mail Verificationを実装中にTarget class [App\Listeners\LogVerifiedUser] does not exist. エラーに遭遇した時の対処法。  laravel6.20

errors.png

はじめに

laravelでwebサービスを開発中に詰まってしまったので、備忘録として投稿します

環境

laravel 6.20
Mailtrap
を使用していました。

実装に際して参考にしていたQiita記事

https://qiita.com/usaginooheso/items/d965f95191739f9335e8

こちらの記事にて確認メールを受信し、いざボタンをクリックしてみると...

errors.png

とエラー画面が表示されてしまう。
DBをみてみると、email_verified_atカラムは更新されており、処理は成功している。

解決

エラーの通り、LogVerifiedUserクラスが存在しないことが問題のようです。
調べてみるとこちらのコマンドを打てばLogVerifiedUserを作成されるそう。

php artisan event:generate

これで設定したリダイレクト先へ遷移するようになりました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】Routingとは?getメソッドを使ったルーティング方法の実例まとめ。

Routingを理解する。getメソッドを使った主要なルーティング方法の実例まとめ。

参考:Larave公式 routing

目次

  1. Routingとは?
  2. Routingファイルの場所
  3. Routerの主なメソッド一覧
  4. Route::getメソッド
    1. 文字列を指定
    2. viewを指定
    3. コントローラーとメソッドを指定
    4. パラメータを渡す
    5. パラメータを複数渡す
    6. パラメータの有無で条件分岐させる
    7. コントローラーにパラメータを渡す
    8. whereメソッドでパラメータを指定する
    9. パラメータをグローバルに指定する
  5. 名前付きルート
    1. nameメソッド
    2. asでルート名を指定する
  6. middlewareメソッドでフィルターをかける
  7. groupメソッドで複数のルートをまとめる
  8. redirectメソッドで転送する
  9. ルートとルート名の一覧を表示する


Routingとは?

入力されたURLに対し、表示するファイル(またはテキストなど)を指定する処理。


Routingファイルの場所

routes/web.phpに記述する。

image.png

routingの例
use Illuminate\Support\Facades\Route;

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

上記処理では、/greetingにアクセスすると、Hello Worldを表示する。

use Illuminate\Support\Facades\Route;
Routeファサードを使う宣言をする。
ファサードとはクラスのインスタンス的なもの。その中のメソッドを簡単に呼び出せるようになる。

・statelessやRESTfull APIの場合
セッション情報を保持しないstatelessなどのルーティングはapi.phpに記述する。



ルートファイルはApp\Providers\RouteServiceProviderによって自動的に読み込まれる。

image.png


Routerの主なメソッド一覧

メソッドではHTTP verbを指定する。

▼基本的な構文
Route::メソッド("$URI", 関数)

メソッド 内容 実例
get URIのデータ取得 Route::get("/", $callback);
post URIのリソースを作成 Route::post("/", $callback);
prefix URIを共通化 Route::prefix('main')->group(function () { });
name ルート名を共通化 Route::name('main.')->group(function () { });
group URI、ルート名を共通化 Route::view('/welcome', 'welcome');
view ビューファイルを指定 Route::view('/welcome', 'welcome');
put URIのリソースを新規作成または置換(更新) Route::put("/", $callback);
patch リソースの部分置換 (更新) Route::patch("/", $callback);
delete URIの内容を削除 Route::delete("/", $callback);
options URIに対して利用できるメソッドの一覧を取得 Route::option("/", $callback);
match 複数のHTTP verbを指定 Route::match(['get', 'post'], '/', function () { });
any すべてのHTTP verbに応答 Route::any('/', function () { });
redirect 指定したURIにリダイレクト Route::redirect('/here', '/there');

よく使うのはgetgroupprefixあたり。残りは使う頻度が低い。

Route::viewはよりシンプルなviewヘルパーで代替できる。

>HTTP verb (HTTP動詞)
get, post, put, patch, delete, optionsが該当。


Route::getメソッド

書き方が複数存在する。

1. 文字列を指定

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

/xxxにアクセスしたら「Hello World」を返す。


2. viewを指定

Route::get('xxx', function () {
    return view('hello');
});

/xxxにアクセスしたら、hello.balde.phpを表示する。

データも渡す場合

Route::get('xxx', function () {
    return view('hello', ['age'=>'25']);
});

25を格納したageという変数を渡す。hello.balde.phpの中で$ageで呼び出せる。

変数を格納することも可能。
view('hello', ['age'=>'$var']


3. コントローラーとメソッドを指定

Route::get('xxx', 'HelloController@message')

/xxxにアクセスしたら、HelloControllerのmessageメソッドを実行する。



▼コントローラーの例

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function message(){
        $msg = 'こんにちは';
        $title = 'this is title!';

        return view('child', ['hello'=>$msg, 'title'=>$title]);
    }
}

>コントローラーでページを表示する方法はこちら


4. パラメータを渡す

ルーティングのURIで{パラメータ名}と記述すると、該当するパスがパラメータとして変数に格納される。

functionの引数に渡せば、そのパラメータを利用できる。

Route::get('/パス/{パラメータ名}, function($パラメータ名){処理}'


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



▼ブラウザの表示

image.png


5. パラメータを複数渡す

パラメータは複数渡すことも可能。

Route::get('user/{name}/{id}', function($username, $number){
    return 'こんにちは。ユーザーID:'.$number.'の'.$username.'さん';
});



▼ブラウザの表示

image.png


6. パラメータの有無で条件分岐させる

パラメータ名に?をつけると、パラメータ名がない場合に変数に代入する値を指定できる。

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

/user/にアクセスすると、指定したJhonを返す。
/user/$名前/にアクセスすると、入力された名前を返す。

image.png
image.png


7. コントローラーにパラメータを渡す

第1引数にパラメータのあるURIを指定し、第2引数にコントローラーのメソッドを指定した場合、パラメータがコントローラーのメソッドの引数に渡される。


web.php
Route::get('user/{name}/{id}', 'HelloController@message');



▼コントローラーの例

HelloController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function message($name, $id){
        return 'こんにちは、ID:'.$id.'の'.$name.'さん';
    }
}



▼ブラウザの表示

image.png


8. whereメソッドでパラメータを指定する

whereメソッドを使うことでパラメータのフォーマットを指定できる。

where('パラメータ名', '正規表現')

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

※注意点
・whereメソッドで指定するパラメータ名は、getのURIで指定しているパラメータ名と合わせる。functionの引数の変数名ではない。



▼指定したフォーマットに合わなかった場合
該当するページがないと判断され404 | Not Foundとなる。

image.png


パラメータを2つ以上指定する場合

配列にして、ダブルアローで指定する。

where(['パラメータ名'=>'正規表現', 'パラメータ名'=>'正規表現')

->where(['name'=>'[ぁ-ん]+', 'id'=>'[1-9]+'])
実例
Route::get('user/{name}/{id}', function($username, $number){
    return 'こんにちは。ユーザーID:'.$number.'の'.$username.'さん';
})->where(['name'=>'[ぁ-ん]+', 'id'=>'[1-9]+']);



もしくは、->where()をメソッドチェーンでつなげるのでもOK。

->where('name', '[ぁ-ん]+')->where('id', '[1-9]+');


その他の指定方法

整数やアルファベットなどよく使うフォーマットには専用のメソッドが用意されている。

メソッド 内容
whereNumber() 整数
whereAlpha() アルファベット
whereAlphaNumeric() アルファベットか数値
whereUuid() ユニークな整数

▼使用例

->whereNumber('id')->whereAlpha('name')

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


9. パラメータをグローバルに指定する

App\Providers\RouteServiceProviderクラスのbootメソッド内でpatternメソッドを使って指定すると、グローバルにパラメータのフォーマットを制限できる。

image.png

Route:pattern('パラメータ名', '正規表現')

RouteServiceProvider.php
public function boot()
{
    Route::pattern('id', '[0-9]+');
}

指定したパラメータを使用する際は、自動的に指定したフォーマットが適用される。


名前付きルート

各ルートに名前をつけることができる。

名前をつけると、routeメソッドを使って、そのURIを呼び出すことができる

▼名前付きルートのメリット

元のURIはルートファイル(web.php)で定義するので、URIを変更する場合に、ルートファイルのみ変更すればいい

名前付きルートではなくURIを指定していた場合、該当するすべてのURIを探し出し変更しなくてはならない。

このため、基本的にルートには名前をつける



▼ルートに名前をつける方法
2つある。

1. name('ルート名')
2. 'as' => 'ルート名' 


nameメソッド

name('ルート名')

Route::get('パス', function () { })->name('usertop');

▼実例

Route::get('user', function () {
    return "ユーザーページTOP";
})->name('usertop');

Route::get('user/{id}/profile', function ($id) {
    return redirect()->route('usertop');
});

image.png

コントローラーアクションにもルート名を付けられる。

Route::get('user/profile', 'UserProfileController@show')->name('profile');


パラメータの値を指定する

パラメータありのルートをパスにした場合に、routeメソッドで呼び出し時にパラメータを指定できる。

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

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


データを渡す

パラメータ名以外の変数を指定した場合は、getでそのデータを渡せる。

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

$url = route('profile', ['id' => 1, 'photos' => 'yes']);
// /user/1/profile?photos=yes


asでルート名を指定する

getメソッドの第2引数を配列化し、'as' => 'ルート名'とすることでも指定できる。

Route::get('user', ['as' => 'usertop', function () {
    return "ユーザーページTOP";
}]);

ルーティングでasが使われていたら、ルート名前を指定しているということ。


コントローラーアクションを指定する場合

コントローラーの指定にusesを使う。

['uses' => 'コントローラー名@アクション名']

Route::get('xxx', ['as' => 'hello', 'uses' => 'StringController@hello']);


middlewareメソッドでフィルターをかける

middlewareメソッドを使うと、HTTP Requestをコントローラーに渡す前や、Responseをクライアントに返す前に、設定した条件のフィルターを介すことができる。

middlewareメソッドとは?


groupメソッドで複数のルートをまとめる

groupメソッドを使うと、共通のURI接頭語やルート名接頭語を省略表記できる。

また、middlewareメソッドにgroupメソッドをチェーンでつなぐこともできる。

groupメソッドとは?


redirectメソッドで転送する

301や302転送を指定して転送することができる。

redirectメソッドとは?


ルートとルート名の一覧を表示する

php artisan route:list

$ php artisan route:list
+--------+----------+-------------------+---------------+----------------------------------------------+------------+
| Domain | Method   | URI               | Name          | Action                                       | Middleware |
+--------+----------+-------------------+---------------+----------------------------------------------+------------+
|        | GET|HEAD | /                 |               | Closure                                      | web        |
|        | GET|HEAD | api/user          |               | Closure                                      | api        |
|        |          |                   |               |                                              | auth:api   |
|        | GET|HEAD | blade             |               | Closure                                      | web        |
|        | GET|HEAD | msg               |               | App\Http\Controllers\HelloController@title   | web        |
|        | GET|HEAD | topics            | topics.index  | App\Http\Controllers\TopicsController@index  | web        |
|        | GET|HEAD | topics/detail     | topics.detail | App\Http\Controllers\TopicsController@detail | web        |
|        | GET|HEAD | topics/show       | topics.show   | App\Http\Controllers\TopicsController@show   | web        |
|        | GET|HEAD | user              | usertop       | Closure                                      | web        |
|        | GET|HEAD | user/{id}/profile |               | Closure                                      | web        |
|        | GET|HEAD | xxx               | hello         | App\Http\Controllers\StringController@hello  | web        |
+--------+----------+-------------------+---------------+----------------------------------------------+------------+

各URI毎の、ルート名、アクション(関数かコントローラーか)、適用されているミドルウェアを確認することができる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】リダイレクト処理。Routeのredirectメソッドについて

Laravelのルーティングでリダイレクトを設定する方法について。

redirectメソッド

Routeファサードのredirectメソッドを使う。

デフォルトの設定(302)

Route::redirect('here', 'there');
 ┗ here: requestされたパス
 ┗ there: リダイレクト先のパス

デフォルトでは302リダイレクト(一時的なリダイレクト)になる。

▼実例

Route::redirect('xxx', '/');

image.png

xxxにアクセスすると、/が表示される。


恒久的なリダイレクト(301)

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

▼実例

Route::redirect('xxx', '/', 301);

image.png


恒久的なリダイレクト (permanentRedirectメソッド)

permanentRedirectメソッドを使っても301転送ができる。

Route::permanentRedirect('here', 'there');

▼実例

Route::permanentRedirect('xxx', '/');
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】ルーティングのミドルウェアとは?作成手順と実例 (Route::midlewareの意味など)

ルーティングで使われるmidlewareとは何かについて。

▼こういうの

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
    //省略
});
Route::group(['middleware' => 'auth.very_basic'], function () {
    Route::get('/', function () {
    //省略
});


目次

  1. ミドルウェアとは?
  2. フローで見るMiddleware
  3. Middlewareを実際に使うまでの流れ
  4. ミドルウェアの作成(条件ファイルの作成)
  5. Middlewareの中身
  6. ミドルウェアの条件作成
  7. ミドルウェアの登録
  8. ミドルウェアをルートに適用


ミドルウェアとは?

HTTPリクエスト(またはレスポンス)をチェックする機能のこと。
middlewareは自分で関数を定義して作成できる。

▼用途

  • 指定した変数が条件を満たしているか
  • 認証ユーザーかどうか

など、、

フローで見るMiddleware

▼通常のフロー

通常のフロー
HTTP Request
 ↓
Route
 ↓
Controller
 ↓
View(Application)
 ↓
Response



▼ミドルウェアがある場合

ミドルウェアありのフロー
HTTP Request
 ↓
Route
 ↓
**Before Middleware**
 ↓
Controller
 ↓
View(Application)
 ↓
**After Middleware**
 ↓
Response

・Before Middleware:リクエストをチェックする機能
・Afrter Middleware:レスポンスをチェックする機能

ミドルウェアは複数設置可能。

image.png

参考:midium.com


Middlewareを実際に使うまでの流れ

Middlewareを実際に使用するまでには大きく3つのステップがある。

1. ミドルウェアの作成(条件ファイルの作成)
2. ミドルウェアの登録
3. ミドルウェアをルートに適用


ミドルウェアの作成(条件ファイルの作成)

artisanコマンドの、make:middlewareで生成できる。

php artisan make:middleware ミドルウェア名

$ php artisan make:middleware test

Middleware created successfully.

▼保存場所
app > HTTP > Middleware > ミドルウェア名.php

image.png

Middlewareの中身

作成したミドルウェアの中身は以下のようになっている。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class test
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        return $next($request);
    }
}

namespace App\Http\Middleware;
app > HTTP > Middlewareに保存されるので、名前空間も対応している。

use Closure;
Closureクラスをインポート。

▼Clouseクラスとは?
無名関数と呼ぶ。https://www.php.net/closure
ここでは、次の処理に進める変数$nextを使えるようにしている。

use Illuminate\Http\Request;
Laravelのコンポーネントである、Requestクラスをインポート。

説明文(PHPDocs)

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */

受け取ったrequestを処理する。

  • @param: パラメータの説明
    ここでは、$request$nextを使っていますという説明。参照元のクラスが示してある。

  • @return: 戻り値
    ここでは、戻り値の型はmixed(何でもとりうる)であることを示している。



・処理内容
functionにミドルウェアの処理を記述する。

public function handle(Request $request, Closure $next)
    {
        //処理
        return $next($request);
    }

return $next($request);
リクエストを次のステップに進めるという意味。

他にミドルウェアが設定されてない場合は、リクエストがコントローラーに渡される。


ミドルウェアの条件作成

実際にミドルウェアの条件部分を作ってみる。

Before Middlewareの作成

requestに対して実行するBefore Middlewareの実例。

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        if ($request->age >= 50) {
            return redirect('home');
        }

        return $next($request);
    }
}

requestで渡されたデータageの値が50を超えている場合は、ルート名homeにリダイレクトする。

50以下の場合は次の処理に進む。


After MiddleWare

responseに対して実行するAfter Middlewareの実例。

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

        if ($response->age >= 50) {
            return redirect('home');
        }

        return $response;
    }
}


Before MiddlewareとAfter Middlewareの違い

▼Before Middleware
- $requestに対して条件を指定
- return $next($request);を返す(通常の処理)



▼After Middleware
- $response = $next($request);に対して条件を指定
- return $response;を返す(通常の処理)


ミドルウェアの登録

ミドルウェアをルートに登録する方法は3つある。

  1. グローバル登録
  2. ルート登録
  3. グループ登録

ルート全体に通すか、個別にルートを指定するか、複数のミドルウェアをまとめて登録するかの違い。

いずれもApp\Http\Kernelクラスの中に記述する。(デフォルトでミドルウェアが登録されている。)

image.png

1. グローバル登録

すべてのルートにミドルウェアを適用するには、app/Http/Kernel.phpの$middlewareプロパティに追加する。

protected $middleware = [ ];

Kernel.php
protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];


2. ルート登録

各ルートに個別にミドルウェアを適用するには、app/Http/Kernel.phpの$routeMiddlewareプロパティに追加する。

protected $routeMiddleware = [ 'ミドルウェア名' => 完全な名前空間::class];
Kernel.php
protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];


3. グループ登録

ミドルウェアをひとまとめにして適用するには、app/Http/Kernel.phpの$middlewareGroupsプロパティに追加する。

protected $middlewareGroups = [ 
   'グループミドルウェア名' => [
        完全な名前空間::class, 
        ,,,,
];

デフォルトでミドルウェア名webとapiが用意されている。(webはURIに、apiはAPIルートに適用する目的)

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

        'api' => [
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];


ミドルウェアをルートに適用

ルート登録したミドルウェア

$routeMiddlewareをルートに適用する方法。

->middleware('ミドルウェア名', 'ミドルウェア名',,,)



▼一つだけ適用する場合

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

URIにadmin/profileが入力された時、ミドルウェアauthを実行数する。



▼複数適用する場合

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

ホームディレクトリにアクセスした場合に、ミドルウェアfirstとsecondを実行する。



▼名前空間で指定
ミドルウェア名ではなく、名前空間で指定もできる。

use App\Http\Middleware\CheckAge;

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


グループ登録したミドルウェア

ルート登録した場合と同じように名前で指定できる。

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


グループ化したルートにミドルウェアを適用する

冒頭の
Route::middlewareや、
Route::group(['middleware' => 'auth.very_basic']
などの表記について。これらが何をやっているか。

Route::middleware

これまでの->middlewareを冒頭で呼び出している。後ろにグループ化したルートがくる場合に使われる。

Route::middleware('ミドルウェア名')->group()

後ろに続くグループ全体にミドルウェアを適用する。

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


Route::group(['middleware' => 'ミドルウェア名'], function(){ ルート });

groupメソッドの引数で適用するmiddlewareを指定している。

Route::group(['middleware' => 'auth.very_basic'], function () {
    Route::get('/', ['as' => 'top', 'uses' => 'TopController@index']);
    Route::get('privacy', 'PrivacyController@index')->name('privacy');
    Route::get('optout', 'OptoutController@index')->name('optout');
});

groupメソッドとは?


(補足)auth.very_basic

Laravel標準のauth.basicとは違い、実際のデータベースの情報を使うことなくBasic認証を追加するミドルウェア。

image.png
https://github.com/olssonm/l5-very-basic-auth/blob/master/README.jp.md

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】ルートのグループ化。Route::groupメソッドの役割について。(prefixとnameメソッドも))

Laravelのルートファイルで頻繁に登場するRoute::groupの意味について。

▼こういうの

web.php
Route::group(['prefix' => 'topics', 'as' => 'topics.'], function() {
        Route::get('/', 'TopicController@index')->name('index');
        Route::get('{filename}.html', 'TopicController@show')->name('show');
    });


目次

  1. Route::groupの意味
  2. 実例
  3. コントローラアクションの場合
  4. ミドルウェアを適用する場合
  5. prefixメソッド
  6. nameメソッド


Route::groupの意味

Routeファサードのgroupメソッドを呼び出している。
このメソッドで、URIの接頭部名前空間の接頭部を共通化できる。

類似したルートを複数記述する場合に便利なメソッド

groupメソッドの前に別のメソッドがきて、チェーンでつなぐパターンもある。

・例:Route::middleware()->group();


groupメソッドの構文

group(['prefix' => '共通するURI', 'as' => '共通するルート名' ]{ Route::get(); Route::get();,,,  })

prefixasはどちらか一方、あるいはどちらも無しでも作動する。


実例

view/topicsディレクトリに、index, show, detailの3つのビューがある場合

image.png

通常のルーティング

それぞれのルートを作成する場合は以下のようになる。

Route::get('topics', function () { return view('topics.index'); })->name('topics.index');
Route::get('topics/show', function () { return view('topics.show'); })->name('topics.show');
Route::get('topics/detail', function () { return view('topics.detail'); })->name('topics.detail');

ここでは、URIのtopicsと、ルート名(nameメソッド)のtopics.が共通。

↓ グループ化

Route::group(['prefix' => 'topics', 'as' => 'topics.'], function() {
    Route::get('/', function () { return view('topics.index'); })->name('index');
    Route::get('show', function () { return view('topics.show'); })->name('show');
    Route::get('detail', function () { return view('topics.detail'); })->name('detail');
});

groupメソッドを使うと表記を省略できる。グルーピングできるので視認性も向上する。


コントローラアクションの場合

Route::get('topics', 'TopicsController@index' )->name('topics.index');
Route::get('topics/show', 'TopicsController@show' )->name('topics.show');
Route::get('topics/detail', 'TopicsController@detail' )->name('topics.detail');

↓ グループ化

Route::group(['prefix' => 'topics', 'as' => 'topics.'], function() {
    Route::get('/', 'TopicsController@index' )->name('index');
    Route::get('show', 'TopicsController@show' )->name('show');
    Route::get('detail', 'TopicsController@detail' )->name('detail');
});


ミドルウェアを適用する場合

Route::group(['middleware' => 'auth.very_basic'], function () {
    Route::get('/', function () {
        //
    });

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



middlewareメソッドを使って、groupメソッドをチェーンすることもできる。

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

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

上記例のgroupはprefixやnameの指定がないバージョン。指定したミドルウェアを適用するために個別にルートをまとめる時はこのような記述になる。

ミドルウェアとは?


prefixメソッド

prefixメソッドで共通するURIを記述してから、groupに適用する方法もある。

prefix('共通するURI接頭部')

Route::prefix('topics')->group(['as' => 'topics.'], function() {
    Route::get('/', 'TopicsController@index' )->name('index');
    Route::get('show', 'TopicsController@show' )->name('show');
    Route::get('detail', 'TopicsController@detail' )->name('detail');
});

nameメソッド

naemメソッドで共通するルート名を記述してから、groupに適用する方法もある。

prefix('共通するURI接頭部')

Route::name('topics.')->group(['prefix'=>'topics'], function() {
    Route::get('/', 'TopicsController@index' )->name('index');
    Route::get('show', 'TopicsController@show' )->name('show');
    Route::get('detail', 'TopicsController@detail' )->name('detail');
});

prefixメソッドとnameメソッドをチェーンする

各メソッドのチェーニングも可能。

Route::name('topics.')->group(['prefix'=>'topics'], function() {
    Route::get('/', 'TopicsController@index' )->name('index');
    Route::get('show', 'TopicsController@show' )->name('show');
    Route::get('detail', 'TopicsController@detail' )->name('detail');
});
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】コメントアウトの@paramや@returnとは何か?読み方や書き方を理解する。

artisanコマンドでファイルを自動生成すると、コメントアウトで@param@returnが記載されていることがある。この意味について。


目次

  1. 実例
  2. PHPDoc
  3. 冒頭のアットマークの意味
  4. タグの書き方
  5. タグの種類

実例

例えば、php artisan make:middleware ミドルウェア名でミドルウェアを作成した場合、以下のようなファイルが自動生成される。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class test
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        return $next($request);
    }
}

このコメントアウトの部分。


PHPDoc

これは関数の説明を一定のルールに沿って記述したもの。

このルールをPHPDocs、コメントアウトで囲まれた人まとまりの説明文をDocブロックと呼ぶ。

Docブロックの書き方
/**
  * 説明の要約
  *
  * 説明の詳細(複数行)
  *
  * 要素(タグ)の説明
  *  
  */

PHPDocリファレンス

冒頭のアットマークの意味

@paramのように冒頭が@で始まる文字列をタグと呼ぶ。
タグづけすることで明示的にして説明をわかりやすくしている

各タグの書き方と種類

タグの書き方

タグの説明文の書き方の基本形は下記となる。

@タグ名 [型/クラス] [名前/変数名] [説明文]

タグ名と型のみ記述されていたり、説明文が無かったりなど、記述はまちまち。

//クラスと変数
* @param  \Illuminate\Http\Request  $request

//型のみ
* @return mixed


タグの種類

よく使われているタグ

タグ 内容 実例
@param 引数のデータ(1個) * @param \Closure $next
@return 関数やメソッドの戻り値。 * @return mixed
@version バージョン情報 * @version 1.0.1
@method 使用されているマジックメソッド * @method setString(integer $integer)
@author 作成者情報 * @author My Name <my.name@example.com>

タグ一覧

image.png

かなりの量のタグが用意されている。
PHPDocタグ一覧

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VercelでLaravelを動かす

https://vercel.com/

最初にまとめ

「データベースを使わない規模のちょっとしたLaravelアプリを無料で動かして公開するならVercelはちょうどいい」
なんだかんだで動かせるのがPHPのメリット。

本格的に使うなら「Laravel公式のサーバーレス」Vaporを使ったほうがいい。
https://vapor.laravel.com/

残りはここに書いてることとほとんど同じ。
https://github.com/invokable/laravel-vercel

動かし方

必要なファイルはvercel.jsonapi/index.php

これを参考にすればいいけどvercel.jsonが少し違う。
https://github.com/juicyfx/vercel-examples/tree/master/php-laravel

動くVIEW_COMPILED_PATHはこれ。

"VIEW_COMPILED_PATH": "/tmp"

東京リージョンで使うには

"regions": ["hnd1"],

Databases

https://vercel.com/docs/solutions/databases

AWSのRDSなどが使える。

Authentication

https://vercel.com/docs/solutions/authentication

DBが使えるならLaravelの認証が使えるはず。

Realtime

https://vercel.com/docs/solutions/realtime

Pusherが使えそうだけどVercelで動かすLaravelではやらないことかも。

Cron

https://vercel.com/docs/solutions/cron-jobs

VercelのドキュメントではGitHub Actionsで定期的にリクエストを送るとか書いてるけど
GitHub Actions使うならGitHub Actionsでartisanコマンドを実行すればいいだけなのでLaravelでは関係ない話。

Email

https://vercel.com/docs/solutions/email
SESなどが使える。

File Storage & Uploads

https://vercel.com/docs/solutions/file-storage
S3などが使えるはず。

Vercelで難しそうなのはキューワーカーやHorizonをずっと動かし続ける部分?
個人的にはそこが一番重要。

デプロイ時のartisanコマンド

composer scriptsにvercelを作ればデプロイ時に実行されるのでキャッシュやマイグレーションはこれでできそう。

    "scripts": {
        "vercel": [
            "@php artisan config:cache",
            "@php artisan route:cache",
            "@php artisan view:cache"
        ]
    }

セッション

databaseかcookieを使う。

Livewireを使うならセッションが必須。DBなしならcookieを使えばいい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel6 メールキャッチャーを使ったメール送信時にエラーが発生した

目的

  • laravel6とメールキャッチャーの組み合わせでメールの送信を実施したところエラーが発生したため解決までの経緯をまとめる

環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.11 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする
Laravel バージョン 6.X commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.21 for osx10.15 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

情報

  • 筆者はDockerなどは使用せずに直接MacにLaravelの環境構築とメールキャッチャーのサーバを立てて検証を行っていた。
  • メールキャッチャーは下記の方法でサーバを立てた。

エラーまでの経緯

  1. laravel6のアプリでメール送信機能を作成した。
  2. アプリからメールを送信した。

エラーの内容

  • 下記のエラーがブラウザ上に表示された。

    Connection could not be established with host 127.0.0.1 :stream_socket_client(): unable to connect to 127.0.0.1:1025 (Connection refused)
    
  • 下記画像ではsmtpのポート番号が1026になっているがこれは解決後、この記事のために意図的にエラーを発生させたため1026となってしまっている。みなさんの環境だと1025と表示されているはず。

    ?_Connection_could_not_be_established_with_host_127_0_0_1__stream_socket_client____unable_to_connect_to_127_0_0_1_1026__Connection_refused_.png

解決までの経緯

  • 下記コマンドを実行してメールキャッチャーをデフォルト設定で起動し直した。

    $ mailcathcer
    
  • laravelのアプリ名ディレクトリで下記コマンドを実行して設定のキャッシュをリセットした。

    $ php artisan config:cache
    
  • 問題は解決した。

本件でお困りの皆さんへ

  • 筆者の場合メールキャッチャーが起動していなかったことが本件の原因であった。
  • このエラーの場合、メールキャッチャーとlaravelアプリの通信がうまく行ってない状態である。
  • 起動しているメールキャッチャーのsmtpポート、smtpのIPが何になっているのか、また、.envファイルのMAIL_PORTとMAIL_HOSTの記載が間違えていないかを確認しよう。
  • 今起動しているメールキャッチャーの情報がわからなくなってしまったなら$ mailcatcherというコマンドを実行することでデフォルト設定でメールキャッチャーが再度起動する。(デフォルトだとsmtpポートは1025、 smtpのIPは127.0.0.1)
  • .envファイルの記載が正しいようなら$ php artisan config:cacheを実行して設定のキャッシュをクリアしてみよう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む