Laravelは非常に使いやすいフレームワークですが、いざ仕事でアプリケーションを実装していくと、Laravelのお作法に従うことが推奨されるケースが多く、機能も膨大なので、当然ですが分からない事が次々出てきます。
この記事では備忘録も兼ね、逆引きTips的にLaravelでの各種実装方法を紹介していきます。
※記事執筆時に使っているLaravelのバージョンは5.7です。
紹介している項目
- Storage
- View
- Controller
- Route
- Database (Eloquent ORM)
- Validation
- その他
※加筆更新修正中
Storage
ファイルの存在をチェックしたい
try/catch
を使ってファイルが存在するかチェックします。
try {
$file = Storage::get('images/hoge.png');
return $file;
} catch (FileNotFoundException $exception) {
return 'File Not Found';
}
コメント欄で@sola-msrさんにexits
でもチェックできることをご指摘頂きました。こちらのほうが記述がシンプルですね。bool
が返されます。
Storage::exists('images/hoge.png');
// or
Storage::disk('s3')->exists('images/hoge.png'); // diskを指定してチェックする場合
ファイルを保存したい
// $requestからphotoというblob値を受け取っている前提。`storage/app/images`に画像が保存される
$filename = date('Ymd-His'). '.png';
$path = $request->photo->storeAs('images', $filename);
Storageのファイルを削除したい
storage/app
から先のディレクトリパスを指定して画像を削除します。
Storage::delete('images/' . $filename);
画像をbase64で出力したい
// `storage/app/images/hoge.png`をbase64に変換する
return base64_encode(Storage::get('images/' . $filename));
指定の全ファイルを取得したい
// 指定したディレクトリ`storage/app/images/`の全ファイルの配列を取得
Storage::files('images');
// 指定したディレクトリ`storage/app/images/`のサブディレクトリを含めた全てのファイルの配列を取得
Storage::allFiles('images');
指定の全ディレクトリを取得したい
// 指定したディレクトリ`storage/app/images/`の全ディレクトリの配列
Storage::directories('images');
// サブディレクトリ下の全ディレクトリも取得
Storage::allDirectories('images');
ディレクトリの作成・削除をしたい
// `storage/app/images/`を作成
Storage::makeDirectory('images');
// 削除(フォルダ内のファイルは削除される)
Storage::deleteDirectory('images');
View
リダイレクト先に値を渡したい
with
で値を渡すことでsessionから値を受け取れます。
return redirect('/contact/complete')->with([
'memberID'=> $memberID
]);
<dl>
<dt>会員No.</dt>
<dd><strong>{{ session('memberID') }}</strong></dd>
</dl>
Sessionの値で値を出し分けたい
@if(Session::has('message'))
<div class="alert alert-waring">
<strong>{{ session('message') }}</strong>
</div>
@endif
POST直前の入力値を復元したい
フォームの完了画面から入力画面に戻るときなどに使うことが多いです。テキスト入力などのinputタグはold
のみで復元できます。
<p>{{ old('message') }}</p>
セレクトボックスでPOST前の画面に戻った際、値を復元したい
<select name="year">
<option @if(old('year')=='2018') selected @endif>2018</option>
<option @if(old('year')=='2019') selected @endif>2019</option>
<option @if(old('year')=='2020') selected @endif>2020</option>
</select>
チェックボックスでPOST前の画面に戻った際、値を復元したい
in_array
でチェックした値でcheckedを出し分けます。
<label>
<input type="checkbox" name="tasks[]" value="1" {{ (is_array(old('tasks')) and in_array(1, old('tasks'))) ? ' checked' : '' }}> task1
</label>
Controller
Requestの値を全て取得したい
POSTされた内容を全て表示するときなどに利用します。
$request->all();
Requestの値から特定の値を取得したい
$request->user_name;
// or
$request['user_name'];
Route
CRUDのAPIを設定したい
makeコマンドでcontrollerを作る時に--resource
をオプションで付けるだけ。
$ php artisan make:controller HogeController --resource
routes/api.phpにRoute::resource
でRouteを指定します。
// CRUD全てを使いたい場合
Route::resource('sample', 'SampleController');
// CRUDの一部機能のみを使う場合
Route::resource('sample', 'SampleController', ['only' => ['index', 'create', 'edit', 'destroy']]);
ページネーション用データを取得したい
LaravelのCollectionクラスにはpagenate
メソッドが用意されており、ページネーション用のJSON書き出しをサポートしています。
Route::get('/users', function () {
return new UserCollection(User::paginate());
});
Database (Eloquent ORM)
Table内のすべてのデータを取得したい
User::all();
Table内の最新の1件を取得したい
もっともシンプルな方法。find
の引数はテーブル初期値に含まれているid
を使います。
User::find(1);
指定キーに該当する1件だけを取得したい
主にuserテーブルなど、レコード1件1件がユニークな時などに利用します。
User::where('member_id', $member_id)->first()
データの作成順に取得したい(降順・昇順)
標準のtableに含まれるcreated_at
をキーにソートして取得します。
# 昇順
User::orderBy('created_at', 'desc')->get()
# 降順
User::orderBy('created_at', 'asc')->get()
古いデータ順に取得したい(昇順)
引数を指定しない場合、'created_at'がデフォルトで指定されます。
User::oldest('created_at')->get();
指定する条件に一致するレコードが存在するかチェックしたい
User::where('member_id', $member_id)->exists() // boolを返す
新しくレコードを保存したい(store)
ModelUser
を作ってuse
していることが前提です。save()
することで簡単にデータベースに保存できます。定義された値が一つでも無いとエラーが出るので注意です。
$user = new User();
foreach ($request as $key => $value) {
$user[$key] = ($value != null)? $value : '';
}
$user->save();
指定キーに該当するレコードを更新したい(update)
->first()
などをつけるとうまく動作しない時がありました。基本ドキュメントに書かれているように、クエリビルダー単体にupdate
付けて実行してください。
User::where('member_id', $member_id)->update(['name' => 'yamada'])
指定キーに該当するレコードを削除したい(destory)
$user = User::where('member_id', $member_id)->first();
$user->delete();
Validation
validateで使えるルールを知りたい
公式サイト、またはQittaの以下サイトで確認できます。Qittaの下記記事はテーブルで一覧表記となっており、ルールを探しやすいです。
- Available Validation Rules - Laravel公式サイト
- [Laravelのバリデーションで指定できる内容をざっくりまとめ直しました]
- (https://qiita.com/fagai/items/9904409d3703ef6f79a2)
オプションフィールドにもバリデーションをかけたい
オプションフィールド(任意の入力)にもバリデーションをかけたい時がありますが、入力した後に値を削除、再び入力してバリデーションをかけると空入力になっているのにバリデーションが働きエラーが起きるケースがあります。原因は$request値がnull
となり、他のバリデートがnullに対して行われるからです。そんな場合はnullable
を設定することで対処できます。
$validatedData = $request->validate([
'key1' => 'required|numeric', //必須の入力値かつ数値のみを許容
'key2' => 'nullable|numeric', //任意の入力値かつ数値のみを許容
]);
validateでカスタムのバリデーションを作りたい
AppServiceProvider.php
に登録することで拡張が可能です。ここではひらがな表記
のカスタムバリデーションを作る前提で説明します。
設置場所は問いませんが、バリデーション用のClassファイルを作成します。以下の例ではApp\Validator
配下にRuleValidator.php
というファイルを新規で設置します。
namespace App\Validator;
class RuleValidator {
public function validateHiragana($attribute, $value, $parameters){
if (mb_ereg('^[ぁ-ん]+$', $value)) { // ひらがなにのみtrueを返す
return true;
}
return false;
}
}
AppServiceProvider.php
のbootにカスタムValidatorを登録します。
// ~~省略~~
public function boot()
{
Validator::extend(
'hiragana', 'App\Validator\RuleValidator@validateHiragana' // 無名関数でも書ける
);
}
// ~~省略~~
エラーメッセージにも対応させるため、langフォルダ内(言語設定に合わせる)に含まれているvalidation.php
にkeyとvalueを登録。これで作業は完了です。
// ~~省略~~
"hiragana" => ":attributeはひらがなを入力してください。",
// ~~省略~~
この例の場合、以下のように使用することができます。
$request->validate([
'first_kana' => 'required|hiragana',
]);
その他
Collection型からデータを取り出したい
取得したデータや作成データは、すべてEloquentのCollectionクラスで返ってきます。返ってきたデータをtoArray()
で配列化することも可能ですが、Collection型の場合は配列化しなくても、foreach
で取得が可能です。
$members = $request;
foreach($members as $member) {
dump($member->name);
}
Collection型から指定keyデータを除外する
request
からキーを指定して除外することが可能です。以下の例はフォーム値から必要のないデータを除外しています。
$input = $request->except('action', '_token');
blobデータをviewで受け取って、storageへ画像として保存したい
手前味噌ですが、以下記事を参考にしてください。JSでblob化、blob化したデータをLaravel APIへPOSTしています。