初心者向けのLaravelでECサイト制作①初期設定と登録商品の表示

5424 回閲覧されました

みなさんこんにちは、jonioです。

最近Laravelで簡易ECサイトを作ったのですがアウトプットするために今回の記事を書きました。(この記事を参考にしました、記事を書いた方ありがとうございます。あなたは神です)

またLaravelで簡易のECサイトの作りたいけどどうすればいいかやり方が分からない方向けの無料チュートリアルにする為に参考記事を自分なりにカスタムして追加機能も付けました。

解説を自分なりにたくさん付けているつもりで多分ネット上の解説の中で情報量は一番多いです。

解説の内容で実装できるかの確認もしていますのでコードの間違いはないと思います。

ProgateでPHPを勉強したばかりだからもう少し簡単な内容を勉強したい人はそんな人向けの記事を書いていますが↓で勉強した方がいいです。

↑は今回の内容よりもかなり易しくなっています。

解説の前に環境とLaravelのバージョン・解説の記事で実装する内容・1回目の解説で説明する内容について説明します。

 

環境とLaravelのバージョン

環境はMAMPを使ってLaravelのバージョンは8です。

この記事を書いているのが2023年3月ですがバージョンが7はもう古い気がします。

 

実装する内容と今回解説する内容

情報量が多すぎるので複数回に分けて解説の記事を書きますがその中で実装する内容は下記となります。

  1. 初期設定と仮の形で商品を表示してデータベースの内容を表示できる様に変更する
  2. ログインするとマイカートに商品を追加できる
  3. マイカートに入れた商品の削除
  4. マイカートに入れた商品を購入
  5. 購入してからブラウザバックをした場合はエラーになる
  6. 購入したページをリロードした時にエラーにならなくする
  7. 登録した商品の管理画面で商品の編集と削除

とりあえず4までができればいいと思います。

1回目の解説で解説する内容は1です。

全部でかなりボリュームがあるので頑張って下さい。

また1回目の解説が恐らく一番ボリュームがあります。

それでは解説します。

 

MAMPの導入とLaravelのインストール

他の開発環境を使っている方はここは無視して下さい。

開発環境ですが導入するのにMAMPが一番簡単かつエラーが少ないと思うので開発環境をまだ導入してない人はオススメします。

開発環境は何を使えばいいか分からない・まだ導入してない方は↓の記事を読んで導入して欲しいです。

 

ログイン機能の実装

ログイン機能はlaravel/uiでできますがこれはLaravelのバージョン8からは非推奨になっているのでBreezeを使います。

これはLaravelで使えるログイン機能ですが↓を読んで導入して下さい。

ログイン機能が実装できて「http://localhost:8888/login」や「http://localhost:8888/register」にアクセスすると項目が↓の様に英語になっています。

↑の赤枠を日本語にするのは↓の記事を読んでやって下さい。

それではまずは登録商品を仮で表示するまでを説明します。

 

ページを表示するまでの流れ

Laravelでページを表示するまでの流れは「ルーティング→コントローラー→ビュー」なのでまずはルーティングから記述します。

「ルーティング?コントローラー?ビュー?」って思った方は↓の記事を読んで下さい。

図付きで解説していますが初めて見る人にとって理解がキツいと思うので時間をかけて理解して下さい。

ルーティング・コントローラー・ビューで何ができるのかを理解しておかないとアプリを作成する事はできないので頑張りましょう。

それでは商品一覧ページを表示するまでの流れを見ていきます。

 

ルーティング(商品一覧ページ)

ルーティングは「Laravelのプロジェクト > routes > web.php」に記述します。

web.phpのコードを↓にします。(コントローラーはShopControllerとしますがこれは後で作成します)

この書き方をするとブラウザを再読み込みした時にコントローラーがありませんとエラーが出ます。

エラーにならない為の設定をします。

「Laravelのプロジェクト > app >Providers > RouteServiceProvider.php」の29行目辺りに↓のコードがあってコメントアウトの状態になっているのですがそれを外します。

これでエラーがなくなります。

ルーティングのコードを見て意味不明な方は↓を読んで実装してから今回の記事を読んだ方が理解ができると思います。

一応今回もルーティングのコードの解説をします。

「Route::get(/index,ShopController@index)->name(shop);」ですが背景色が黄色・青色・緑色・オレンジ色・紫色の部分を考えないといけません。

それぞれの色について説明します。

get」はhttpメソッドと言って色々ありますがとりあえずgetとpostを知っていればいいと思います。

使い分けはとりあえず以下の感じで理解すると楽だと思います。

  • get : 表示する
  • post : 保存する

/index」はアクセスするURLで今回だと「http://localhost:8888/index」になります。

ShopControllerはコントローラー名です。

indexはコントローラーの中で書くメソッド名です。(メソッドをアクションとも言います)

shopはビューでshopと書くとshop.blade.phpになります。

ビューは「Laravelのプロジェクト > resources > views 」の下に配置します。

次はコントローラーです。

 

コントローラー(商品一覧ページ)

「/shop」を表示する設定をしますがコントローラーを記述する為のファイルがないので作成します。

ターミナルを使います。

コントローラーを作成する為のコードは「php artisan make:controller コントローラー名」となります。

今はShopControllerを作成したいのでLaravelのプロジェクトに移動して「php artisan make:controller ShopController」とコマンド入力をします。

成功すると「Laravelのプロジェクト > app > Http > Controllers > ShopController.php」が作成されているのが確認できます。

ShopController.phpに↓の記述をします。

12行目〜15行目で自分で決めるのは2行目の「index」と14行目の「shop」です。

indexはアクション名でshopはビュー(shop.blade.php)です。

アクション名はweb.phpに記述した名称と同じにして下さい。

14行目の「return view(‘shop’);」はshop.blade.phpを表示するという意味になります。

次はビューです。

 

ビュー(商品一覧ページ)

shop.blade.phpに↓の記述をします。

6行目に「{{ asset(css/shop.css) }}」 ・7行目に「{{ asset(css/reset.css) }}」がありますがassetはすぐに説明するのでひとまずおいておきshop.cssとreset.cssをします。

cssに記述するのではなくscssに記述してscssを変換してcssにして使います。

申し訳ないですがECサイトを作る解説中にscssについては解説しませんので自分で理解するかとりあえずこんな物と思って使ってLaravelを理解するのに集中した方がいいと思います。

cssがよく分かってない方は今scssをやっても絶対に理解できないのでそんな物と思って先に進めた方がいいです。

Laravel-Mixを使ってshop.scssからshop.cssに変換してreset.scssからreset.cssに変換します。

scssやJavaScriptを変換する時はLaravelのプロジェクト直下にwebpack.mix.jsがあるのでそれを編集します。

scssを書くファイルですが「Laravelのプロジェクト > resources」の下にsassフォルダを作成してその中にshop.scssとreset.scssを作成して下さい。

また「Laravelのプロジェクト > public」の下にcssフォルダを作ってその下にreset.cssとshop.cssを作成して下さい。

reset.scssを↓にしますがこれはresetcssの為のファイルとします。

resetcssが何か分からない人は調べて下さい。

内容としては凄く単純ですが重要な物で何かを知らないと今後コーディングが大変になると思います。

shop.scssを↓にします。

そしてshop.scssをshop.css変換してreset.scssをreset.cssに変換します。

ターミナルでLaravelのプロジェクトに移動して「npm run dev」を叩いて成功するとcssに変換されます。(今後scssを作成した場合は記述の後に必ず「npm run dev」をして下さい)

それでは6行目・7行目の「asset」について説明します。

これを使うと読み込み(cssまでのパス)のスタートがLaravelのプロジェクトの直下にあるpublicになります。

例えばreset.cssだとcssフォルダの中のreset.cssなので「{{ asset(css/reset.css) }}」という書き方になります。

shop.cssに関しても同様です。

これで「http://localhost:8888/index」にアクセスすると↓の表示になります。

商品はshop.blade.phpの14行目〜43行目で表示されていますがこれを商品登録フォームのページで登録した内容が表示される様にします。(後で解説します)

商品登録フォームで登録した内容をいきなり表示するのよりもとりあえずHTMLで表示してLaravelの書き方に変えた方が実装が楽だと思います。

それでは商品登録ページで商品の登録をしますが一旦商品登録ページを表示します。

 

ルーティング(表品登録ページ)

web.phpを↓にします。

次はコントローラーです。

 

コントローラー(表品登録ページ)

ShopController.phpのコードを↓にします。

次はビューです。

 

ビュー(商品登録ページ)

「Laravelのプロジェクト > resources > views」の下にproductCreate.blade.phpを作成します。

一旦HTMLで作成してからあとでLaravelのコードに変えます。

productCreate.blade.phpのコードを↓にします。

6行目に「productCreate.css」があるので新たにproductCreate.scss作成をしてcssに変換します。

先程作成した(resourcesフォルダの中の)sassフォルダの下にproductCreate.scssを作成して(publicフォルダの中の)cssフォルダの下にproductCreate.cssを作成してproductCreate.scssを↓にします。

そしてwebpack.mix.jsを↓にします。

そして「npm run dev」をしてから「http://localhost:8888/productCreate」にアクセスすると↓の見た目になります。

14行目〜17行目のname属性ですがあとで説明しますのでひとまずそんな物と思って下さい。

それでは商品の登録をします。

あるページで商品を登録する時はルーティング→コントローラー→ビューを2回書かないといけません。

それは下記についてです。

  • 商品を登録するページを表示する
  • 商品を登録する

ページを表示するだけではなくそこで何かをしたい時は表示用・何かをする用にルーティング→コントローラー→ビューを2回書かないといけないと覚えましょう。(これを知らなくてLaravelを始めたての時は苦労しました)

それでは商品の登録をします。

 

モデルの使い方

商品の登録はデータベースのテーブルにしますがデータベースへのアクセスはモデルがやります。

モデルについては↓で図付きで解説していますので何か知らない方は読んで下さい。

またデータベースに情報を反映させる為のマイグレーションファイルという物があってそれも使うのですが↓の「つぶやきを保存する為のコントローラー」の項目で解説しています。

まずモデルとマイグレーションファイルを作成します。

 

モデル・マイグレーションファイルの作成とカラムの追加

モデルとマイグレーションファイルを別々に作成する事もできますが今回はその必要がないので一緒に作成します。

モデルと一緒にマイグレーションファイルを作成する時のコマンドは「php artisan make:model モデル名 -m」です。

モデル名はstockとします。

だからコマンドは「php artisan make:model Stock -m」になります。

ちなみにモデルを作成すると自動的にテーブルも作成されテーブル名は「モデル名s」です。

今はモデル名がstockなのでテーブル名はstocksです。

モデルとマイグレーションファイルが作成されたらマイグレーションファイルを使ってstocksテーブルにカラムを追加する為にマイグレーションファイルの設定をします。

「Laravelのプロジェクト > database > migrations > 本日の日付_create_stocks_table.php」に↓の記述します。

21行目〜24行目に「string」や「integer」がありますがデータ型と言います。

この記事に解説がありますが最初は何となく知っていればいいと思います。

記述が終わったら「php artisan migrate」をして下さい。

成功したらカラムが作成されているのを確認できると思います。

MAMPの場合にデータベースの確認をする方法はWebStartをクリックします。

そしてTools(↓の赤枠)をクリックしてからphpMyAdmin(↓の青枠)をクリックします。

これでデータベースを見る事ができるのでstocksテーブルに追加したカラムが表示されているかを確認して下さい。

次はデータベースに情報を追加できるカラムの指定をモデルを使って行います。

 

情報を追加できるカラムの指定

モデルは「Laravelのプロジェクト > app > Models > Stock.php」です。

Stock.phpに↓の記述をします。

14行目の「$fillable」ですが情報の追加を許可するカラムに対して指定します。

反対に許可しない場合は「$guarded」にします。

これでstocksテーブルの「name」・「detail」・「fee」・「imgpath」カラムに情報を追加できる様になりました。

それではデータベースに登録しますがルーティング→コントローラー→ビューの順に見ていきます。

 

ルーティング(データベースに登録)

web.phpを↓にします。

33行目の「post」の部分は27行目と30行目は「get」でしたが使い分けを覚えていますか?

もう一度説明しますが下記で考えればとりあえずはいいです。

  • get : ページを表示する時
  • post : 保存する時

今回は商品情報を保存する時なのでpostを使います。

次はShopControllerでしたがデータベースに登録するのはモデルの担当なのでモデル(Stock.php)に記述をします。

モデルの役割が何かを忘れた方は↓を読んで下さい。

モデルでデータベースにアクセスする記述をした時はそれをコントローラーで使います。

よってモデルとコントローラーの両方の記述をします。

 

モデルとコントローラー(データベースに登録)

まずはモデルですがStock.phpに↓の記述をします。

21行目〜38行目はメソッドにしていますがモデルに記述した内容をコントローラーで使う場合はモデルではメソッドで書いてコントローラーでそのメソッドを使うという形式にします。

メソッドインジェクションと言いますが↓で解説しています。

 

バリデーション

23行目〜28行目はバリデーションをかけています。

例えば24行目に「required」を付けていますがこれは「必須」という意味です。

「required|max:100」とすると最大100文字までと文字数の制限をする事ができます。

バリデーションはどんな時に役に立つかですが例えば投稿サイトで悪意がある異常な文字数の投稿があるとサーバーを圧迫する可能性がありますがそれを弾くのでサーバーの圧迫を防ぐ事ができます。

 

カラム名を揃える

$this->name」の$thisとnameの部分(他にdetailfeeimgpathがあり)について説明します。

30行目・31行目・32行目・36行目・37行目に「$this」がありますがこれはStockモデルの事です。

30行目に「name」・31行目に「detail」・32行目に「fee」・36行目に「imgpath」があってこれはstocksテーブル(↓の赤枠)のカラム名(↓の青枠)が対応しています。

またproductCreate.blade.php(ビュー)の14行目〜17行目のinputタグの中のname属性も対応しています。

「name」・「detail」・「fee」・「imgpth」の全ての名称をモデルとテーブルで同じに揃えて下さい。

 

データベースに保存する設定

30行目〜37行目はデータベースに情報を保存するための設定です。

まずは商品名(nameカラム)から説明します。

30行目の「$this->name」がstocksテーブルのnameカラムで「$inputs[‘name’]」がproductCreate.blade.phpの中の14行目の「<input type=text name=name placeholder=商品タイトル>」のname=”name”の事です。

Stock.phpの31行目と32行目も同じ考え方です。

33行目〜36行目は画像に関してですが商品のタイトル・説明・金額と違って少し複雑になります。

 

シンボリックリンク

まずはLaravelにおける画像の保存先について知っておかないといけない事があります。

Laravelの仕様ですが公開したアプリが参照されるのはpublicのフォルダの中身です。

それに対して画像が保存されるのはstorageフォルダの中になります。

だから今のままだと保存した画像はpublicフォルダにないので表示する事ができません。

画像の表示ができる様にする為にシンボリックリンクというpublicフォルダの中にstorageフォルダのショートカットを作成します。

ターミナルでLaravelのプロジェクトに移動して「php artisan storage:link」を叩きます。

成功するとpublicフォルダの下にstorageフォルダのショートカットがあるのが確認できます。

そしてstorageフォルダのショートカットの下に「images」フォルダを作成して下さい。

これはproductCreate.blade.phpで登録する商品の画像を置く為のフォルダです。

それでは33行目〜36行目の画像を登録するコードの説明をします。

 

画像の登録

Laravelでは画像を保存する時に別の名前に自動的に変わります。

それを元の名前のままにしておくのが33行目の「getClientOriginalName()」で33行目で画像の名前を元のまま保存できる様にします。

しかしこれには欠点があり、もしも同じ名前の別の画像を後で登録したら前に登録した同じ名前の画像は後の画像に置き換わります。

それを防ぐ為に34行目があり「date(‘Yms_His’)」で日付を画像名の前に付ける事で画像が同じ名前になるのを防ぎます。

そして35行目で画像を先ほど作成した「Laravelのプロジェクト > public > storage > images」の下に保存します。

そして36行目で画像の名前をstocksテーブルのimgpathカラムに保存して37行目でproductCreate.blade.phpで登録した商品の情報をデータベースに書き込んだ状態を保存します。

これでモデルの記述が終わりでstoreメソッドをShopController.phpで使います。

 

コントローラー

ShopController.phpのコードを↓にします。

6行目でStockモデルを使える様にしています。

24行目のstoreメソッドの引数に$requestがありますがこれを先程Stockモデル(の21行目)で説明したstoreメソッドに渡しています。

25行目の「return back()」は商品の登録が終わったら商品登録のページに戻ってくるという意味で「->with(‘message’,‘商品の投稿が完了しました’)」で商品情報を追加するページで商品の登録が完了した時に「商品の投稿が完了しました」と表示させます。(productCreate.blade.phpのコードを書き換える時に説明します)

次はビュー(productCreate.blade.php)です。

 

ビュー(データベースに登録)

productCreate.blade.phpのコードを↓にします。

またproductCreate.scssを↓にします。

productCreate.scssを書いたら「npm run dev」でcssに変換して下さい。

それではproductCreate.blade.phpの説明をします。

15行目〜19行目ですがこれはStockモデルの説明の時に後で説明しますと言ってた「->with(‘message’,‘商品の投稿が完了しました’)」を表示する為のコードです。

20行目〜26行目は商品登録の時にバリデーションに引っ掛かったらエラーを表示する為のコードです。

試しに商品登録のページ(http://localhost:8888/productCreate)で何も入力せずに「登録する」を押すと↓の赤枠が表示されます。

バリデーションエラーに引っかかると入力フォームに書いた内容は消えますが36行目の「{{old(name)}}」・38行目の「{{old(detail)}}」・39行目の「{{old(fee)}}」があると入力した内容が保持した状態になります。

これをold関数と言います。

試しに商品名だけ入力して「登録する」を押すとエラーが表示されますが商品名だけ入力した状態になっているのが確認できます。

画像に関してはバリデーションエラーに引っかかった場合は画像の保持がされません。(そんなもんだと思って下さい)

namedetailfeeはstocksテーブルのカラム名です。

31行目の「enctype=multipart/form-data」はformタグで文字の形式や画像の形式など複数の形式を一緒に使う時に記述しないといけないのですが↓を読んで下さい。

32行目ですがLaravelでformタグを使う時は絶対に「@csrf」を書きます(書かないとエラーになります)がこれはクロスサイトリクエストフォージェリ対策です。

長いので省略して「csrf」と書きますが↓でcsrfが何かを解説しています。

これで商品登録のページ(http://localhost:8888/productCreate)にアクセスして商品を登録してデータベースのstocksテーブルを見ると情報が入っているのが確認できます。

37行目の「accept=image/jpg,image/png」は登録できる画像の拡張子の形式の設定をしています。

最後はデータベースに登録した商品を商品一覧ページ(http://localhost:8888/index)で表示します。

データベースに登録した内容をビューで表示するのでルーティング→モデル→コントローラー→ビューの順に記述します。

 

ルーティング(登録商品の表示)

商品一覧ページのルーティングはもう記述済みです。

27行目です。

だからモデルの記述に進みます。

 

モデル(登録商品の表示)

まずはモデルですがStock.phpのコードを↓にします。

43行目の「Stock::all();」 でデータベースに登録した情報の全てを取得します。

そして45行目でその情報をコントローラーで使える様にしています。

次はコントローラーです。

既に記述したindexアクションを修正します。

 

コントローラー(登録商品の表示)

ShopController.phpのコードを↓にします。

既に作成していた17行目のindexアクションを修正しました。

20行目の「compact(‘stocks’)」(compact関数と言います)で19行目の$stocksを変数としてビューに渡します。

compact関数を使ってビューに渡す変数は$を取ります。

次はビューです。

既に記述したshop.blade.phpを修正します。

 

ビュー(登録商品の表示)

shop.blade.phpのコードを↓にします。

コントローラーでcompact関数を使って$stocksを変数としてビューに渡していましたがそれを52行目〜58行目の中で使います。

52行目の$stocksがビューに渡された変数です。

54行目の「$stock->name」の「name」はstocksテーブルのカラム名です。

54行目の「fee」・55行目の「imgpath」・56行目の「detail」も同様です。

55行目の「asset」ですが覚えていますでしょうか?

これを書く事で画像のパスのスタートをpublicにしています。

また55行目の画像のパス({{asset(storage/images/.$stock->imgpath)}})で↓の赤枠の画像を読み込んでいる事になります。

これで「http://localhost:8888/index」にアクセスすると商品一覧はstocksテーブルに登録した内容が表示されているのが確認できます。

今回はここまでです。

次回はログインすると商品の登録ができてマイカートに追加できるのとマイカートに入れた商品の削除を解説しますが↓からどうぞ。