- 投稿日:2020-07-13T22:51:39+09:00
Laravel入門者向け 1時間でCRUDが使えるようになるLesson
Laravelのインストールや開発環境については既にそこら中にたくさん転がっているのでここでは割愛します。
さらにフォルダ構成についてもそこらへんに転がっているので必要最小限だけを解説します。基本的に個人の健忘録的なメモなのであまり期待しないで下さい。
Laravelのコマンドの基本
基本はLaravelのフォルダからコマンドを叩いて使います
よく使うコマンドだけ紹介php artisan // オプトインサーバー起動 php artisan serve // model制作(DB設定 カラム設計 バリデート) // -mオプションを付けるとMigrationファイルも同時に生成してくれる php artisan make:model ファイル名 -m // コントローラー生成 php artisan make:controller ファイル名Controller // コントローラー生成 CRUDリソース付き php artisan make:controller ファイル名Controller --resource // DB生成実行パート php artisan migrate // DB作り直し php artisan migrate:fresh // DB直前の命令を戻す php artisan migrate:rollback // ルーティングリスト確認 php artisan route:list私が基本的によく使うコマンドは上記です。
ここからサクッと必要項目についての流れ
ルーティングを理解する
**初期状態** Route::get('/', function () { return view('welcome'); });**ざっくりルーティングを理解する** Route::①アクセスしてきたメソッド('②グローバルアドレス', function () { return view('welcome'); ③ビューを選択 });とりあえず3つの要素で構成されている
Route:: はお約束として
- getはメソッドを表すがgetとpost以外は基本使わない
- getの引数にある '/' は http:://ドメイン/ にアクセスがあった場合
- ③はresorce/views フォルダにあるファイル名を指定している
views/配下にあるフォルダを指定する場合は「.」で繋ぐ**例** /resource/views/test/main.blade.php return view('test.main');とすればOK!
コントローラー&メソッドを呼び出す
Route::get('/sub','subsController@index');コントローラーファイルは基本 /app/http/controllers/ 配下にある
上記は http://ドメイン名/sub にアクセスがあった場合に /app/http/controllers/subsController.php ファイルのindex()メソッドを呼び出す例他にも出来るルーティング web.php
**初期状態** Route::get('/', function () { $math = 2 * 3; $data = '2x3は'.$math.'でした!'; return $data; });のようにViewを使わなくても表示されます。
モデルとマイグレーション
モデルはデータベースのことです。
マイグレーションは簡単に言えばDBテーブル設計のことで、リレーションを設定したりバリデーションルールを決めれます。
- 作りたいテーブルを生成
shell php artisan make:model tests -m
/database/migrations から 日付_create_tests_table.php が生成されるpublic function up() { Schema::create('tests', function (Blueprint $table) { $table->id(); $table->string('name','20'); $table->string('descript'); $table->timestamps(); }); }upの部分に必要なカラムを制作して php artisan migrate を実行するだけ
バリデーションとテーブルのルールを制作
/app 配下にテーブル名.phpのファイルが制作されているので該当するファイルを開く
protected $guarded = ['id']; または protected $fillable = [ 'name', 'email', 'password', ];などのルールを制作しておかないとデータ追加や更新の時にfill()メソッドが使えないのでどちらかを必ず設定しておくこと。
予約語 $guarded $fillable はホワイトリストとブラックリストの関係で成り立っており、$guaeded にidを指定しているとautoIncrementを設定していた時にIDが勝手に変更されてエラーが出ないように設定する意味がある。
必要最低限のバリデーションルールの設定
同じく/app/テーブル名.php を開いて設定
public static $rules = [ 'name' => 'required', 'descript' => 'required', ];not null にしたいカラムに上記のように設定しておくとNullの場合にエラーを吐きます。
migration補足と注意事項
注意:XAMPPのMariaDBを使う場合はマイグレーションを実行した時にエラーが出ます。
文字数問題のことなんですが初見殺しなので記載「/app/Providers/AppServiceProvider.php」に「use Illuminate\Support\Facades\Schema;」と「Schema::defaultStringLength(191);」の2行を追記すれば解決するとの事です。 ... use Illuminate\Support\Facades\Schema; ... public function boot() { Schema::defaultStringLength(191); } ... 作成に失敗したDB内のテーブルを全て削除して、再びmigrateを実行すると問題なくtableが作成されました。また /config/database.php のcharset設定で utf8mb4を utf8_unicode_ciに設定すればOKです。
エラー詳細はこちらコントローラー
コントローラーの役割は モデルとビューを繋ぐ役割だと考えています。
かなりざっくりですが最低限のCRUDを実装するためだけなら良いと思います(異論は認める)use宣言
Modelと連携する為にはどのテーブルを使うかを宣言する必要があります。
use App\テーブル名; (複数形)use宣言をしておいて各メソッドでテーブルの情報を呼び出しデータをビューに渡します。
またコントローラーはデータ加工パートでもあるのでごにょごにょした結果をビューに渡す流れもアリです。シンプルなコントローラーでテーブルデータ呼び出しの例 <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\テーブル名; class subsController extends Controller { public function index() { $data = テーブル名::get(); // dd($data); return view('sub',compact('data')); } }リクエストを受ける時
public function post(Request $req) { $data = new \App\テーブル名; $data->fill($req->all())->save(); return redirect('/sub')->with('flash_message', '投稿が完了しました'); }上記の(fill())フィルは(バリデーションとテーブルのルールを制作)で述べた予約語guardedかfillableを設定しておくことで使えます。
指定されたデータの検索
とりあえずfindでデータを表示出来る状態
public function edit(Request $id) { // echo $id->id; $data = $id->id; $ids = テーブル名::find($id->id); return view('test.edit',compact('ids','data')); }Bladeを使ったテンプレートレイアウト
Bladeを使ってびっくりしたのが子から親レイアウトを呼び出して使う流れです。
/resources/views/ に子ファイルを置き layouts にレイアウトの枠組みを設置して使う流れになってます。慣例では layouts/メソッド名のフォルダ/ を作ってその中にレイアウトの大枠を置く感じです。
別に好きに指定指定良いようなのでLaravelは自由度が高いですね。また、コントローラーの return view() で指定するのはあくまでコンテンツを呼び出すだけでOKです。
ちょっと疲れたので、この続きはまた後ほど書きたいと思いますw
- 投稿日:2020-07-13T18:22:10+09:00
Laravelフレームワーク内で使われているTrait一覧[laravel/framework 7.x]
はじめに
PHPのtraitの使いどころがいまいちわからないので、
Laravelフレームワークのコードを読んで勉強しよう!というモチベーションで一覧を作りました。trait一覧
合計102個のtraitが使われていました。
larvel/framework 7.xには 102個のTraitが使われてました。
- 投稿日:2020-07-13T14:28:04+09:00
laravel 6.x to 7.x upgrade
移行手順は以下のサイトを参考にする。
Laravel 7.x アップグレードガイドcomposer.jsonを修正する。
laravel/ui
も利用している場合はlaravel/ui
も修正する。composer.json{ "require" : { "laravel/framework": "^7.0", "laravel/tinker": "^2.0", "laravel/ui": "^2.0", "facade/ignition": "^2.0", "nunomaduro/collision": "^4.1", }, ]Exceptionクラスの修正
Symfony 5.xになりExceptionクラスからThrowableクラスに変わったので
Exceptionクラスで引数を渡している個所の修正が必要新規なら問題ないが既存アプリだと
app/Exception/Handler.php
のrender
やreport
の引数
ExceptionをThrowableに変更。app/Exception/Handler.php/* use Exception; */ use Throwable; /* public function report(Exception $exception) */ public function report(Throwable $exception)config/session.phpの修正
config/session.php/* 'secure' => env('SESSION_SECURE_COOKIE', false), */ 'secure' => env('SESSION_SECURE_COOKIE', null),
composer update
実行でアップグレード完了。
- 投稿日:2020-07-13T11:13:59+09:00
LaravelでQueryBuilder利用時にsql_safe_updatesを有効にする
Eloquent利用時は対象のモデルをUPDATE,DELETEしますが、QueryBuilderを利用する際は対象のレコードは
WHERE
を適切に利用しなければ関係のないレコードも対象になってしまう可能性があります。基本的には実装時、あるいはレビュー時点で気づくことと思いますが、MySQLの
sql_safe_updates
という機能を利用することで実装漏れをしてもレコードを守ることが出来ます。sql_safe_updatesとは
mysqlへのクエリ実行の際にこのフラグを有効にすることでUPDATE,DELETE時にWHEREもしくはLIMITまたその両方が指定されていない場合はクエリ実行ができなくなります。
mysql>SET sql_safe_updates=1これをQueryBuilder利用時にも有効にすることで事故を減らそうという試みです。
QueryBuilder利用時にsql_safe_updatesを有効にする
Illuminate\Database\DatabaseManager
からconnection
を取得し、SET sql_safe_updates=1
をstatement
で実行するようにします。$connection = $this->databaseManager->connection(); if ($this->databaseManager->getDriverName() === 'mysql') { $connection->statement('SET sql_safe_updates=1'); } return $connection->table($this->tableName);この
connection
を利用していれば意図しないUPDATEやDELETEを防ぐことができます。
また、実装時も例外になって処理が失敗してしまうのでWHERE漏れに気づくことが容易になります。
- 投稿日:2020-07-13T00:47:29+09:00
Laravel 最小限の記載でルーティングとコントローラの記載が正しいか確認する
目的
- 最小限のコードでルーティングとコントローラの記載が正しいことを確認するコードを紹介する。
実施環境
- ハードウェア環境
項目 情報 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.3 Homwbrewを用いて導入 Laravel バージョン 7.0.8 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする 紹介
- 投稿日:2020-07-13T00:31:59+09:00
フォームの書き方いろいろ
前提条件
- laravelで書いています。
- blade.phpの書き方
一般的なフォーム
フォームの中に、サーバーに送りたいデータ(inputタグ)があって、それをbuttonタグでサブミットしている。
<form action="{{ route('create') }}" method="post"> @csrf <div class="md-form"> <label for="name">名前</label> <input class="form-control" type="text" id="name" name="name" value="{{ old('name') }}" required> </div> <button class="btn btn-block" type="submit">送信</button> </form>ボタンを外出ししたもの。
formタグをblade.phpの下の方にまとめておいて、どのフォームとどのボタンが連携しているのかを
<form id="buttonタグのform属性と同じ名前"></form> <button form="formタグのidと同じ名前">送信</button>formタグの、id属性
buttonタグのform属性
で連携させているもの。<form id="buttonタグのform属性と同じ名前" action="{{ route('hoge') }}" method="post"> @csrf <div class="md-form"> <label for="name">名前</label> <input class="form-control" type="text" id="name" name="name" value="{{ old('name') }}" required> </div> </form> <button form="formタグのidと同じ名前" class="btn btn-block" type="submit">送信</button>formタグ、inputタグ、buttonタグをそれぞれ別にしたもの。
一つの画面で、何箇所もボタンがあったり
登録するデータの量が膨大なとき
以下のように書いている現場があった。formタグ、inputタグ、buttonタグをまとめるのではなく、
別々にすることで、コードを見やすくすることが目的。書き方の雛形としては、こう。
<button form="formタグのidと同じ名前" class="btn btn-block" type="submit">送信</button> <form id="buttonタグのform属性と同じ名前" action="{{ route('hoge') }}" method="post"> @csrf </form> <input form="formタグのidと同じ名前" type="text" id="name" name="name" value="{{ old('name') }}" required>なにか登録用のデータを流したいんだとしたら、自分ならこうする。(その現場に合わせるなら)
<button form="store" class="btn btn-block" type="submit">保存</button> <button form="search" class="btn btn-block" type="submit">検索</button> <form id="store" action="{{ route('store') }}" method="post"> @csrf </form> <form id="search" action="{{ route('search') }}" method="post"> @csrf </form> <input form="store" type="text" id="name" name="name" value="{{ old('name') }}" required> <input form="store" type="text" id="email" name="email" value="{{ old('email') }}" required> <input form="store" type="text" id="address" name="address" value="{{ old('addless') }}" required> <input form="store" type="text" id="tel" name="tel" value="{{ old('tel') }}" required> <input form="search" type="text" id="hoge" name="hoge" value="{{ old('hoge') }}" required> <input form="search" type="text" id="fuga" name="fuga" value="{{ old('fuga') }}" required>