- 投稿日:2020-02-07T18:54:22+09:00
【Laravel】デフォルトの管理画面に左メニューをサクッと設置
最近Laravelはじめました。
Laravelにはデフォでユーザ管理機能が存在しますが、そのログイン後の画面はコンテンツエリアのみのレイアウトとなってます。これをよくある固定左メニュー+コンテンツエリアのレイアウトにしてみます。
0. 管理機能の有効化
ver5系では
php artisan make:auth
コマンドでユーザ管理機能がセットアップできたのですが、6系の場合は以下のリンク等を参考にセットアップしてください。Laravel 6系でmake:authを使う方法
Laravel6 備忘録 −ユーザー認証(Auth)−うまくセットアップできれば、
/resources/views
下に以下のファイルが生成されているはずです。
home.blade.php
今回は認証後の最初のビューであるこれを元に話をすすめます。1. home.blade.phpから左メニューの元ネタをコピー
<div class="col-md-12">から閉じの</div>までをコピーします。
/resources/views/home.blade.php<div class="container"> <div class="row justify-content-center"> <div class="col-md-12"> <div class="card"> // 略2. menu.blade.phpを新規作成
1でコピッたソースを貼り付けて、
col-md-12
をcol-md-2
に変更してお好みに応じてカスタマイズします。/resources/views/menu.blade.php<div class="col-md-2"> <div class="card"> <div class="card-header"><i class="fas fa-th-list"></i></i> MENU</div> <div class="card-body"> <div class="panel panel-default"> <ul class="nav nav-pills nav-stacked" style="display:block;"> <li><i class="fas fa-user-alt"></i> <a href="#">XXXXXXXX</a></li> <li><i class="fas fa-user-alt"></i> <a href="#">XXXXXXXX</a></li> <li><i class="fas fa-user-alt"></i> <a href="#">XXXXXXXX</a></li> </ul> </div> </div> </div> </div>3. home.blade.phpを修正
col-md-12
をcol-md-10
に変更して、その直前の行に@include('menu')
を。menu.blade.php<div class="container"> <div class="row justify-content-center"> <!-- left menu --> @include('menu') <div class="col-md-10"> <div class="card"> // 略ちなみに今回はこんなCSSをあててみました。
.col-md-2 .card-body { padding:0; } .col-md-2 ul { padding: 0; position: relative; } .col-md-2 ul li { line-height: 1.8; padding: 0.5em 0.5em 0.5em 0.7em; list-style-type: none!important; background: -webkit-linear-gradient(top, #whitesmoke 0%, whitesmoke 100%); background: linear-gradient(to bottom, whitesmoke 0%, #dadada 100%); text-shadow: 1px 1px 1px whitesmoke; color: black; }以上、LaravelというようりBootstrapのグリッドシステムを利用した小ネタでした。今回は2:10でメニューとコンテンツエリアを分割しましたが、12(グリッドの個数は最大12)の範囲内で3分割なども可能です。
- 投稿日:2020-02-07T16:24:43+09:00
laravel6.0でのauthの実装
- 投稿日:2020-02-07T14:23:04+09:00
Laravel で .env の値が取得できない
おさらい
- Laravel では環境変数の設定に
.env
を使う.env
の値にアクセスするにはenv('<config>.<key>')
とする
- 例:
env('app.url')
- 設定 5.7 Laravel
問題
- ある状況で
env('app.url')
でnull
が返ってくるようになった
- とくになにもアプリケーションコードさわってない
原因
- 設定ファイルをキャッシュすると、
env()
関数がnull
を返すようになる
php artisan config:cache
ねNote: 開発過程の一環としてconfig:cacheコマンド実行を採用する場合は、必ずenv関数を設定ファイルの中だけで使用してください。設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返します。
設定 5.7 Laravel https://readouble.com/laravel/5.7/ja/configuration.html#configuration-caching
対策
- config ファイルで
env
関数を使うconfig/app.php<?php return [ 'name' => env('APP_NAME', 'Laravel'), 'env' => env('APP_ENV', 'production'), 'debug' => env('APP_DEBUG', false), // ...
- そして
config()
関数でアクセスする
- 投稿日:2020-02-07T11:02:02+09:00
Laravel用コマンドチートシート
Laravelプロジェクトの作成
composer create-project --prefer-dist laravel/laravel プロジェクト名起動
$ cd SampleProject $ php artisan serveモデルの作成
$ php artisan make:model CreateModelコントローラーの作成
$ php artisan make:controller CreateControllerマイグレーションコマンド系
$ php artisan make:migration make_migration マイグレーションファイル作成 $ php artisan migrate マイグレーションの実行 $ php artisan migrate:refresh 全てのマイグレーションをリセットし、再度実行 $ php artisan migrate:reset 全てのマイグレーションをロールバックシーダーコマンド系
$ php artisan make:seeder UsersSeeder シーダーファイル作成 $ php artisan db:seed シーダー実行 $ php artisan db:seed --class=UsersSeederSeederを逆生成する
サーバーを移行する際に、データベースを引っ越すときに使えるかもしれない。
あとは新規でプロジェクトに入った人とかにローカル環境のデータを皆で共有するときとかに$ composer require --dev "orangehill/iseed" $ vim config/app.php 'providers' => [ Orangehill\Iseed\IseedServiceProvider::class, #追加 ],$ php artisan iseed {table_name}仮に、categoriesテーブルだとすると、以下のようになります。
CategoriesTableSeeder.php// database/seeds/CategoriesTableSeeder.php <?php use Illuminate\Database\Seeder; class CategoriesTableSeeder extends Seeder { /** * Auto generated seed file * * @return void */ public function run() { \DB::table('categories')->delete(); \DB::table('categories')->insert(array ( 0 => array ( 'id' => 1, /* ...(中略)... */ ), 1 => array ( 'id' => 2, /* ...(中略)... */ ), 2 =>キャッシュクリア系
Laravel、Apacheやnginxを再起動したとしても、内部のキャッシュが残っててしまって、更新したプログラムをうまく反映してくれない時がある。
$ php artisan cache:clear $ php artisan config:clear $ php artisan route:clear $ php artisan view:clear随時追加予定。
- 投稿日:2020-02-07T10:11:29+09:00
laravel: パスワードリセット by Auth
参考
Laravelパスワードリセットメールの文面・デザインを変更する
Laravel5.6でバリデーションなどのエラーメッセージを日本語化する方法
laravel-resources-lang-ja
Laravel 5.6 パスワードリセット
php - Laravel 58でカスタムPasswordBroker sendResetLink()メソッドを拡張または作成する方法は?.env//メール送信設定 MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=465 MAIL_USERNAME={address_id}@gmail.com MAIL_PASSWORD={mail_pass} MAIL_ENCRYPTION=ssl MAIL_FROM_ADDRESS={email_address} MAIL_FROM_NAME={name}ここまでで下記画面からのパスワードリセットメールが送信できるようになります。
パスワードリセットメールのテンプレートビュー
resource/view/mail/passwordreset.blade.php//参考サイト様より <!DOCTYPE html> <html lang="ja"> <style> body { background-color: #fffacd; } h1 { font-size: 16px; color: #ff6666; } #button { width: 200px; text-align: center; } #button a { padding: 10px 20px; display: block; border: 1px solid #2a88bd; background-color: #FFFFFF; color: #2a88bd; text-decoration: none; box-shadow: 2px 2px 3px #f5deb3; } #button a:hover { background-color: #2a88bd; color: #FFFFFF; } </style> <body> <h1> パスワードリセット </h1> <p> 以下のボタンを押下し、パスワードリセットの手続きを行ってください。 </p> <p id="button"> <a href="{{$reset_url}}">パスワードリセット</a> </p> </body> </html>通知クラス(Notification)を継承するパスワードリセットクラスの作成
$ php artisan make:notification PasswordResetNotificationapp/Notification/PasswordResetNotification.php//追加 public $token; protected $title = 'パスワードリセット 通知'; //変更 public function __construct($token) { $this->token = $token; } public function toMail($notifiable) { return (new MailMessage) ->subject($this->title) ->view('mail.passwordreset', [ 'reset_url' => url('password/reset', $this->token), ]); }作成したPasswordResetNotificationクラスを利用するために。
app/User.php//追加 use App\Notifications\PasswordResetNotification; //メソッドのオーバーライド public function sendPasswordResetNotification($token) { $this->notify(new PasswordResetNotification($token)); }これでパスワードリセットできるようになります。
カスタマイズ
期限の変更設定
config/auth.php//expireオプションで設定 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 30, // <- ココ ], ],パスワードリセット後のリダイレクト先
app/Http/Controller/Auth/ResetPasswordController.php//プロパティを変更 protected $redirectTo = '/home';フラッシュメッセージの日本語化
resource/lang/ja/password.php<?php return [ 'password' => 'パスワードは6文字以上にして、確認用入力欄と一致させてください。', 'reset' => 'パスワードは再設定されました!', 'sent' => 'パスワード再設定用のURLをメールで送りました。', 'token' => 'パスワード再設定用のトークンが不正です。', 'user' => "メールアドレスに一致するユーザーが存在しません。", ];メールアドレスが見つからなくても同じメッセージを出力
app/Http/Controller/Auth/ForgetPasswordController.php//追加 use Illuminate\Http\Request; //オーバーライド public function sendResetLinkEmail(Request $request) { $this->validateEmail($request); $response = $this->broker()->sendResetLink( $request->only('email') ); return back()->with('status', 'パスワード再設定用のURLをメールで送りました。'); }
- 投稿日:2020-02-07T03:09:14+09:00
Laravelの認可処理はGateとPolicyどっちを使えばいいのかわからない
概要
Laravelには認可処理として、GateとPolicyというものが用意されています。
最初はよくわからなくてどっちがどっちなんだ?と思うでしょう。
結論
わからなかったらGateをつかえばよい。
そもそも認可処理を担当するクラスは
Illuminate/Auth/Access/Gate.php
で、Policyも結局はGateを使っています。Policyはあくまでもモデルに対しての認可処理を簡単にかけるようにしたものです。
Policyのmiddlewareでの指定方法
Policyでの認可処理の書き方の一つにルートでミドルウェアとして書く方法があります。
Route::post('/book', 'HogeController@update')->middleware('can:update,book');
can
は固定で、:
のあとの1つめはポリシーのメソッド名になります。そのあとのは主に書き方が2種類あります。モデルをつかわないメソッドの場合
ポリシーで以下のようなメソッドを定義したとします。
public function create(User $user) { }このメソッドは引数にユーザーしか受け取っていません。
引数にモデルを渡さない場合の書き方は、
Route::get('/create', 'HogeController@create')->middleware('can:create,App\\Book');とこのように完全修飾名を渡してあげます。この文字列はサービスプロバイダーに登録されたポリシーを探し出すためのkeyとしてのみ使用されます。
モデルをつかうメソッドの場合
public function update(User $user, Book $book) { }このメソッドは引数にユーザーしか受け取っていません。
引数にモデルを渡さない場合の書き方は、
Route::put('/{book}', 'HogeController@store')->middleware('can:update,book');としてあげます。第一引数の
{}
の中身と同じ名前を指定しなければいけないことに注意してください。ルートモデルバインディングを利用しているので合わせる必要があります。
Policyを使うときには
AuthServiceProvider
に登録するのを忘れないようにしましょう。(よく忘れて怒られる...)
- 投稿日:2020-02-07T01:18:54+09:00
認可処理であるPolicyのソースコードリーディング(middleware編)
ポリシーのソースコードリーディング
がんばりましょう。
Gateファサード
解決されるクラス
Illuminate/Auth/Access/Gate.php
ポリシーの登録
ポリシーのマッピングは
app/Providers/AuthServiceProvider
に記述します。keyに関連するモデル、valueにポリシーを記述します。
app/Providers/AuthServiceProviderprotected $policies = [ // 'App\Model' => 'App\Policies\ModelPolicy', ]
boot()
の中で呼ばれているregisterPolicies()
で登録していきます。Illuminate/Foundation/Support/Providers/AuthServiceProvider.phppublic function registerPolicies() { foreach ($this->policies() as $key => $value) { Gate::policy($key, $value); } }
$this->policies()
は先程のpolicies
プロパティを返します。
Illuminate/Auth/Access/Gate::policies()
が呼ばれます。Illuminate/Auth/Access/Gate.phppublic function policy($class, $policy) { $this->policies[$class] = $policy; return $this; }
Illuminate/Auth/Access/Gate
のpolicies
プロパティに同じ形で値を格納していきます。これにてポリシーの登録は終了。
ポリシーをつかう
主なポリシーの使用方法は3つで、
- User.phpから使う
- Controllerから使う
- ミドルウェアで使う
中身は大体同じなので、今回はミドルウェアで使うを例に見ていきます。
想定ルート、ミドルウェア
Route::get('/{book}/{comment}', 'BookController@index')->middleware('can:view,book,comment');実際にアクセスされたURL
/1/2
book
はルートモデルバインディングで解決され、comment
は解決されないものとします。ここでの注意点は、
middleware()
内に書いた文字列のbook
やcomment
に当たる部分は必ず同じ名前でURIに記載してください。たとえば、
Route::get('/{book}/hoge', 'BookController@index')->middleware('can:view,book,comment');のように、
middleware()
内にcomment
と書いてあるのに、get
の第一引数の中に{comment}
が含まれていないと怒られます。ポリシーはリソース(モデル)に対しての認可を提供するので、ルートモデルバインディングで解決されたインスタンスを利用します。(なのでミドルウェアの順番も重要です)
想定ポリシー
protected $polices = [ Book::class => BookPolicy::class ]B
BookPolicy::view()
が定義されている。みていこう
まずは
'can:view,book,comment'
がどのようにミドルウェアに変換されるか見ていきましょう。ミドルウェアをごにょごにょしているのはここです。
Illuminate/Pipeline/Pipeline.phpprotected function carry() { return function ($stack, $pipe) { return function ($passable) use ($stack, $pipe) { [$name, $parameters] = $this->parsePipeString($pipe); $pipe = $this->getContainer()->make($name); $parameters = array_merge([$passable, $stack], $parameters); $carry = method_exists($pipe, $this->method) ? $pipe->{$this->method}(...$parameters) : $pipe(...$parameters); return $this->handleCarry($carry); }; }; }
$pipe
には'can:view,book'
という文字列が入り、$passable
にはRequestクラス、$stack
は次のミドルウェアが入っています。
parsePipeString()
でミドルウェア名とその他に分けます。Illuminate/Pipeline/Pipeline.phpprotected function parsePipeString($pipe) { [$name, $parameters] = array_pad(explode(':', $pipe, 2), 2, []); if (is_string($parameters)) { $parameters = explode(',', $parameters); } return [$name, $parameters]; }
$name = 'can'
$parameters = ['view', 'book', 'comment']
$this->getContainer()->make($name)
でIlluminate/Auth/Middleware/Authorize.php
インスタンスを生成します。
(文字列とミドルウェアの対応はapp/Http/Kernel.php
に書いてあります。)
$this->method
にはhandle
が入っているので、Illuminate/Auth/Middleware/Authorize::handle()
が実行されます.Illuminate/Auth/Middleware/Authorize.phppublic function handle($request, Closure $next, $ability, ...$models) { $this->gate->authorize($ability, $this->getGateArguments($request, $models)); return $next($request); }
$ability
にview
が入り、...$models
に残りもの(book
comment
)が渡されます。まずは
getGateArguments()
を見ていきましょう。Illuminate/Auth/Middleware/Authorize.phpprotected function getGateArguments($request, $models) { if (is_null($models)) { return []; } return collect($models)->map(function ($model) use ($request) { return $model instanceof Model ? $model : $this->getModel($request, $model); })->all(); }コレクションクラスの
map()
で一つずつ処理をしていきます。今回
$models
は文字列なのでgetModel()
が呼ばれます。Illuminate/Auth/Middleware/Authorize.phpprotected function getModel($request, $model) { if ($this->isClassName($model)) { return trim($model); } else { return $request->route($model, null) ?: ((preg_match("/^['\"](.*)['\"]$/", trim($model), $matches)) ? $matches[1] : null); } }
isClassName
で完全修飾名かどうかを判定しています。完全修飾名だとそのまま返すようです。完全修飾名出ない場合を見ていきましょう。
Illuminate/Http/Request.phppublic function route($param = null, $default = null) { $route = call_user_func($this->getRouteResolver()); if (is_null($route) || is_null($param)) { return $route; } return $route->parameter($param, $default); }
$route
には現在のルートの情報を保持するRouteクラスが入ってきます。Routeクラスの
parameters
プロパティにはルートモデルバインディングで解決されたモデルなどが入っています。protected $parameters = [ 'book' => 解決されたBookモデル, 'comment' => 2,
$route->parameter()
は第一引数をkeyに$parameters
から値を取得します。今回の
getGateArguments()
の返り値は配列になります。中身は[解決されたBookモデル, 2]です。
$this->gate->authorize('view', [解決されたBookモデル, 2])
を見てきます。Illuminate/Auth/Access/Gate.phppublic function authorize($ability, $arguments = []) { return $this->inspect($ability, $arguments)->authorize(); }
inspcet
が呼ばれて、Illuminate/Auth/Access/Gate.phppublic function inspect($ability, $arguments = []) { try { $result = $this->raw($ability, $arguments); if ($result instanceof Response) { return $result; } return $result ? Response::allow() : Response::deny(); } catch (AuthorizationException $e) { return $e->toResponse(); } }
raw
が呼ばれ、Illuminate/Auth/Access/Gate.phppublic function raw($ability, $arguments = []) { $arguments = Arr::wrap($arguments); $user = $this->resolveUser(); $result = $this->callBeforeCallbacks( $user, $ability, $arguments ); if (is_null($result)) { $result = $this->callAuthCallback($user, $ability, $arguments); } return $this->callAfterCallbacks( $user, $ability, $arguments, $result ); }
Arr:wrap
は配列でないときは配列でラップしてくれるだけです。
$user
にはログイン済みのユーザーが入ってきます。
callBeforeCallbacks()
とcallAfterCallbacks()
は、それぞれGate::before()
、Gate::after()
で定義したコールバックが呼ばれます。今回は関係ないので
callAuthCallback()
を見ていきます。Illuminate/Auth/Access/Gate.phpprotected function callAuthCallback($user, $ability, array $arguments) { $callback = $this->resolveAuthCallback($user, $ability, $arguments); return $callback($user, ...$arguments); }
resolveAuthCallback
は...Illuminate/Auth/Access/Gate.phpprotected function resolveAuthCallback($user, $ability, array $arguments) { if (isset($arguments[0]) && ! is_null($policy = $this->getPolicyFor($arguments[0])) && $callback = $this->resolvePolicyCallback($user, $ability, $arguments, $policy)) { return $callback; } //... }
$arguments
は[解決されたBookモデル, 2]なので、issetはtrueになり、getPolicyFor()
は、Illuminate/Auth/Access/Gate.phppublic function getPolicyFor($class) { if (is_object($class)) { $class = get_class($class); } if (isset($this->policies[$class])) { return $this->resolvePolicy($this->policies[$class]); } //... foreach ($this->policies as $expected => $policy) { if (is_subclass_of($class, $expected)) { return $this->resolvePolicy($policy); } } }ポリシーは
protected $polices = [ Book::class => BookPolicy::class ]と登録したので、
$this->policies[$class]
の返り値はBookPolicy::class
になります。
resolvePolicy
でクラス名からインスタンスを生成します。resolveAuthCallback()
に戻ります。Illuminate/Auth/Access/Gate.phpprotected function resolveAuthCallback($user, $ability, array $arguments) { if (isset($arguments[0]) && ! is_null($policy = $this->getPolicyFor($arguments[0])) && $callback = $this->resolvePolicyCallback($user, $ability, $arguments, $policy)) { return $callback; } //... }
resolvePolicyCallback()
はコールバックを返すみたいなのでコールバックが呼ばれるときに見てみることにします。呼び出し元に戻ります。
Illuminate/Auth/Access/Gate.phpprotected function callAuthCallback($user, $ability, array $arguments) { $callback = $this->resolveAuthCallback($user, $ability, $arguments); return $callback($user, ...$arguments); }コールバックを呼び出してその返り値を返しているようです。案外登場が早かったのでコールバックの中身を見てみましょう。
Illuminate/Auth/Access/Gate.phpprotected function resolvePolicyCallback($user, $ability, array $arguments, $policy) { return function () use ($user, $ability, $arguments, $policy) { $result = $this->callPolicyBefore( $policy, $user, $ability, $arguments ); if (! is_null($result)) { return $result; } $method = $this->formatAbilityToMethod($ability); return $this->callPolicyMethod($policy, $method, $user, $arguments); }; }
$user
はログインユーザー、$ability
はview
、$argument
は[解決されたBookモデル, 2]、$policy
はさっき解決したBookPolicyインスタンス。ポリシーにも
before()
がありますが今回は関係ないのでスルー。Illuminate/Auth/Access/Gate.phpprotected function callPolicyMethod($policy, $method, $user, array $arguments) { if (isset($arguments[0]) && is_string($arguments[0])) { array_shift($arguments); } if (! is_callable([$policy, $method])) { return; } if ($this->canBeCalledWithUser($user, $policy, $method)) { return $policy->{$method}($user, ...$arguments); } }
$arguments[0]
が文字列ならばここで抹消されます。最終的に
$policy->{$method}($user, ...$arguments)
でポリシー内のメソッドが呼ばれます。ポリシーのメソッドはboolを返します。なので、
callAuthCallback()
の返り値は、ポリシーの指定されたメソッドの返り値ということになります。Illuminate/Auth/Access/Gate.phppublic function raw($ability, $arguments = []) { $arguments = Arr::wrap($arguments); $user = $this->resolveUser(); if (is_null($result)) { $result = $this->callAuthCallback($user, $ability, $arguments); } return $this->callAfterCallbacks( $user, $ability, $arguments, $result ); }
after
を指定していないので、callAuthCallback()
の返り値がそのまま返ります。Illuminate/Auth/Access/Gate.phppublic function inspect($ability, $arguments = []) { try { $result = $this->raw($ability, $arguments); if ($result instanceof Response) { return $result; } return $result ? Response::allow() : Response::deny(); } catch (AuthorizationException $e) { return $e->toResponse(); } }
$result
にポリシーのメソッドの返り値が格納されます。Illuminate/Auth/Access/Response.phppublic static function deny($message = null, $code = null) { return new static(false, $message, $code); } public static function allow($message = null, $code = null) { return new static(true, $message, $code); }
Illuminate/Auth/Access/Response.php
を生成して返していますね。Illuminate/Auth/Access/Gate.phppublic function authorize($ability, $arguments = []) { return $this->inspect($ability, $arguments)->authorize(); }
inspct()
はIlluminate/Auth/Access/Response
を返すので、Illuminate/Auth/Access/Response::authorize()
が呼ばれます。Illuminate/Auth/Access/Response.phppublic function authorize() { if ($this->denied()) { throw (new AuthorizationException($this->message(), $this->code())) ->setResponse($this); } return $this; }ここでエラーレスポンスを返すか、次のミドルウェアへ処理を移すかの分岐になっていますね。
以上でポリシーの認可は終わりです!
まとめ
ポリシーはリソース(モデル)を利用するGateの糖衣のようなもの。
ルートモデルバインディングを前提としている。
before, afterなどのhookが用意されている。
- 投稿日:2020-02-07T00:02:24+09:00
Laravel バリデーションで変数を利用
Laravelのバリデーションで変数の使い方
なぜ気になったのか
ECサイトを制作中に、商品をカートに追加する際にデータベース上の商品の在庫数以上の数を買い物かごに入れることができてしまう。
バリデーションを利用するときに商品の在庫数はそれぞれ異なるので固定の値は設定できない。
商品ごとにデータベースの商品の在庫数をMAXとしてそれ以上買い物かごに入れる時にはバリデーションを発動してエラーメッセージを出したかったから。まず試したこと
$data['test'] = 5; $max = 10; $validator = Validator::make($data, [ 'test' => 'max:$max', ]);これでは全くバリデーションは効かず
ではどうするべきか。
PHPで変数を文字列内で展開したい場合は変数を
{ }
(波括弧)で囲って書くことで、文字列の中に変数があること明示している。
ただし、文字列の中に変数を入れる場合は、文字列を必ず" "
(ダブルクォーテーション)で囲む必要がある。
詳しくはPHPマニュアルこれを踏まえて下記で実行してみました。
$data['test'] = 5; $max = 10; $validator = Validator::make($data, [ 'test' => "max:{$max}", ]);しかしこれでもうまくいきませんでした。
何が必要なのか。
Laravelバリデーションの
min
max
size
などを利用するときは指定された値を判断する。
そのため、上記の書き方では文字列と判断され値は文字長を判断する。
詳しくはLaravel5.5 バリデーション
在庫数などの数値を判断する場合にはmax
の前に整数値であるバリデーションが必要なためinteger
を記述する必要がある。これを踏まえると下記の書き方になる。
$data['test'] = 5; $max = 10; $validator = Validator::make($data, [ 'test' => "integer|max:{$max}", ]);細かい部分ですが、つまずいたポイントなので復習がてらにまとめてみました。