PHP
tips
laravel
laravel5.7

Laravelによるアプリ開発のための逆引きTips

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から値を受け取れます。


ResultController.php

return redirect('/contact/complete')->with([

'memberID'=> $memberID
]);


result.blade.php

<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の下記記事はテーブルで一覧表記となっており、ルールを探しやすいです。


オプションフィールドにもバリデーションをかけたい

オプションフィールド(任意の入力)にもバリデーションをかけたい時がありますが、入力した後に値を削除、再び入力してバリデーションをかけると空入力になっているのにバリデーションが働きエラーが起きるケースがあります。原因は$request値がnullとなり、他のバリデートがnullに対して行われるからです。そんな場合はnullableを設定することで対処できます。

$validatedData = $request->validate([

'key1' => 'required|numeric', //必須の入力値かつ数値のみを許容
'key2' => 'nullable|numeric', //任意の入力値かつ数値のみを許容
]);


validateでカスタムのバリデーションを作りたい

AppServiceProvider.phpに登録することで拡張が可能です。ここではひらがな表記のカスタムバリデーションを作る前提で説明します。

設置場所は問いませんが、バリデーション用のClassファイルを作成します。以下の例ではApp\Validator配下にRuleValidator.phpというファイルを新規で設置します。


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を登録します。


app/Provider/AppServiceProvider.php

// ~~省略~~

public function boot()
{
Validator::extend(
'hiragana', 'App\Validator\RuleValidator@validateHiragana' // 無名関数でも書ける
);
}
// ~~省略~~

エラーメッセージにも対応させるため、langフォルダ内(言語設定に合わせる)に含まれているvalidation.phpにkeyとvalueを登録。これで作業は完了です。


app/Resources/lang/ja/validation.php

// ~~省略~~

"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しています。

axiosでPOSTした画像をLaravel APIで保存する