『PHPの基礎から学ぶ Laravel本格入門:手を動かして学ぶ「セミナー受付システム」開発』
はじめに
本書を手にとってくださった新人エンジニアの皆さんへ
はじめまして、著者の山崎有生です。
この度は、数ある技術書の中から本書を手に取っていただき、本当にありがとうございます。
エンジニアとして社会人としての第一歩を踏み出した今、皆さんの胸の中は、きっと大きな希望と、ほんの少しの不安が入り混じった状態なのではないでしょうか。
「早く一人前のエンジニアとして活躍したい」
「たくさんのことを学ばなければいけないけれど、何から手をつければいいのだろう?」
「プログラミングは少し経験があるけれど、チームでの開発や実践的なアプリケーション作りは初めてで、ついていけるだろうか…」
もし皆さんがそんな気持ちを抱えているとしたら、心配ありません。それは、成長したいと強く願う、向上心あふれるエンジニアの誰もが通る道です。
この本は、そんな皆さんのような、情熱あふれる新人エンジニアの皆さんのために書きました。単にLaravelというフレームワークの使い方を解説するだけではありません。本書は、皆さんがプロのエンジニアとして歩み始めるための「最初の心強い相棒」となり、一つのアプリケーションを自らの手で完成させる「成功体験」をプレゼントすることを、最大の目的としています。
本書のゴール:自分の力でWebアプリケーションを完成させる体験
本書のゴールは、とてもシンプルです。それは、「セミナー受付システム」という一つのWebアプリケーションを、PHPの基礎から始めて、最終的に皆さん自身の力でゼロから完成させることです。
プログラミングの学習は、よく料理に例えられます。レシピ本を読んで「カレーの作り方」の知識を得ることはできますが、それだけでは本当に料理ができるようになったとは言えませんよね。実際にキッチンに立ち、野菜を切り、お肉を炒め、ルーを溶かすという一連の工程を自分の手でやってみて、初めて「美味しいカレー」が完成します。
この本で目指すのは、まさにその後者です。ルーティング、コントローラー、データベースといった一つ一つの知識(レシピの材料)を学びながら、それらを組み合わせて「セミナー受付システム」という一つの料理を完成させる。そして、完成したアプリケーションがブラウザで動いた瞬間の、「できた!」という感動を味わっていただくこと。
この「完成させた」という経験こそが、バラバラだった知識を結びつけ、「分かったつもり」を「本当に分かった」に変えてくれる、何よりの近道なのです。そしてその経験は、これから先皆さんがエンジニアとして歩んでいく上で、揺るぎない自信となるはずです。
作成する「セミナー受付システム」の機能紹介
本書で皆さんと一緒に作っていくのは、実践的な機能を盛り込んだ「セミナー受付システム」です。なぜこのシステムを題材に選んだかというと、現代のWebアプリケーションに求められる基本的な要素が、コンパクトに、しかしバランス良く詰まっているからです。
このシステムには、大きく分けて二つの役割を持つユーザーが登場します。
役割 | 主な機能 |
一般ユーザー(セミナー参加者) | ・開催されるセミナーの一覧を見ることができる<br>・各セミナーの詳細情報を確認できる<br>・参加したいセミナーに申し込むことができる<br>・申し込み完了時に、確認メールを受け取ることができる |
管理者 | ・安全なログインページから管理画面に入ることができる<br>・新しいセミナーの情報を登録・編集・削除することができる<br>・各セミナーへの申込者の一覧を確認することができる |
データベースとの連携、ログイン認証、メール送信といった、どのWebサービスを作る上でも必要となるであろう基本機能を、このシステム開発を通して一通り体験することができます。
本書の効果的な学習の進め方と心構え
最後に、皆さんがこの本を最大限に活用し、挫折することなくゴールにたどり着くための、いくつかのヒントと心構えをお伝えします。
- 必ず、自分の手でコードを書いてくださいサンプルコードをただ眺めたり、コピー&ペーストしたりするだけでは、力はつきません。面倒に感じても、ぜひ自分の手で一文字一文字タイプしてみてください。タイプミスからエラーが出ることもあるでしょう。しかし、そのエラーを解決する過程こそが、皆さんを大きく成長させてくれます。
- エラーを恐れないでくださいプログラミングにエラーはつきものです。エラーメッセージは、皆さんを困らせるものではなく、「ここがちょっと違うみたいだよ」と教えてくれる、コンピューターからの親切なヒントです。本書では、エラーが出たときの考え方や対処法も解説していきます。エラーは成長のチャンスだと捉えましょう。
- 「なぜ?」を大切にしてくださいただ手順通りに進めるだけでなく、「なぜ今このコードを書くのだろう?」「このコマンドは何のために実行するのだろう?」と、常に小さな疑問を持つことを意識してみてください。その「なぜ?」の答えを探すことで、表面的な知識ではなく、応用が利く本質的な理解が深まります。
- 焦らず、自分のペースで進めましょう学習のペースは人それぞれです。本書は、一歩ずつ進めるように構成されていますが、もし分からない部分があれば、前の章に一度戻って読み返してみるのも良いでしょう。大切なのは、完璧に理解することよりも、最後まで諦めずに歩き続けることです。
さあ、準備はよろしいでしょうか?
プロのWebアプリケーション開発者への、エキサイティングな冒険の旅へ、私と一緒に出発しましょう!
「第1章:LaravelのためのPHP速習コース」の導入部分にあたる「1-1 なぜPHPの基礎が重要なのか?」を執筆します。
第1部:開発の準備をしよう - プロの土台を固める
おめでとうございます!皆さんは今、プロのWebアプリケーション開発者になるための、大きな一歩を踏み出しました。この第1部では、本格的な開発に入る前に、絶対に欠かすことのできない知識と環境を整えていきます。いわば、冒険に出る前の武器と防具を揃える、大切な準備の章です。
第1章:LaravelのためのPHP速習コース
1-1 なぜPHPの基礎が重要なのか?
「Laravelのテキストなのに、どうしてPHPの勉強から始めるの?」
「一刻も早く、格好いいLaravelの機能を学びたいんだけど…」
きっと、そう思われた方も少なくないでしょう。その気持ちは、とてもよく分かります。新しい技術を学ぶときのワクワク感は、何物にも代えがたいですよね。
しかし、あえて断言します。Laravelを本当に使いこなし、将来にわたって活躍できるエンジニアになるために、PHPの基礎を固めることこそが「最強の近道」なのです。
この関係を、家づくりに例えてみましょう。
Laravelは、デザインも性能も素晴らしい、最新式の「家(建物)」です。キッチンやお風呂といった設備も完璧で、住むだけで毎日が楽しくなるような、魅力的な家です。
一方で、PHPは、その家を支える「土地と基礎」にあたります。地面を固め、コンクリートを流し込み、鉄筋を組む、あの部分です。
皆さんは、どんな土地の上に家を建てたいでしょうか?
当然、固く、頑丈に整備された土地の上ですよね。もし、フカフカの砂地や、グラグラの沼地のような不安定な土地(PHPの知識が曖昧な状態)の上に、いくら立派な家(Laravel)を建てても、どうなるでしょうか。
最初は良くても、少し大きな地震が来たり、大雨が降ったりすると、家は傾き、壁にはヒビが入ってしまうでしょう。そして、いざ修理しようにも、土台がしっかりしていないので、どこから手をつけていいか分かりません。
プログラミングも全く同じです。
Laravelは、PHPというプログラミング言語を使って作られています。つまり、Laravelの便利な機能や美しいコードは、すべてPHPという土台の上で動いているのです。
学習を進めていくと、必ずエラーに遭遇します。そのとき、エラーメッセージが示しているのは、Laravelの機能の奥にある、PHPの根本的な文法ミスであることがほとんどです。PHPの基礎知識がなければ、そのメッセージの意味を理解できず、解決までに膨大な時間がかかってしまいます。
また、この本のゴールである「セミナー受付システム」のような、オリジナルのアプリケーションを作るとき、Laravelが用意してくれた部品を組み合わせるだけでは足りない場面が必ず出てきます。その「あと少し」を埋めるためには、皆さん自身でPHPのコードを書く力が必要不可欠なのです。
この章では、PHPの全てをマスターすることを目指しません。安心してください。
Laravelという立派な家を建てるために必要十分な、固くて信頼できる「土地と基礎」を作ることに専念します。具体的には、変数、配列、条件分岐、繰り返し、そしてクラスの本当に基本的な考え方など、これさえ押さえておけば大丈夫、という内容に絞って解説していきます。
少しだけ遠回りに見えるかもしれませんが、ここでしっかりと基礎を固めることが、後々の学習スピードを何倍にも加速させてくれます。
さあ、まずはLaravelという素晴らしい家を建てるための、最高の土地づくりから一緒に始めていきましょう!
1-2 変数とデータ型:データを入れる「箱」
プログラミングのあらゆる活動は、「データ」を扱うことから始まります。ユーザーの名前、商品の価格、セミナーの開催日など、これら全ての情報をコンピューターに記憶させ、操作する必要があります。
そのために必要なのが、データを入れておくための「箱」です。プログラミングの世界では、この箱のことを「変数(へんすう)」と呼びます。
このセクションでは、プログラミングの最も基本的な要素である「変数」と、その箱に入れるデータにはどんな「種類」があるのかについて学んでいきましょう。
変数とは?名前をつけたデータ格納箱
変数をイメージする一番簡単な方法は、「名前を書いたラベルを貼った、空っぽの箱」を想像することです。
この箱には、3つのルールがあります。
- 箱には必ず「名前(変数名)」をつけます。後からどの箱か分かるようにするためです。
- 箱の中には「データ」を一つだけ入れることができます。
- 箱の中身は、後から別のデータに入れ替えることができます。(だから「変」数と呼ばれます)
PHPという言語では、この変数を次のようなルールで書きます。
- 変数名の前には、必ずドルマーク
$
をつけます。これは「これは変数ですよ」というPHPとのお約束です。 - 箱にデータを入れる(代入する)ときには、イコール
=
を使います。
実際にコードを見てみましょう。
$seminarName = 'Laravel Introduction Course';
$capacity = 30;
echo $seminarName;
echo $capacity;
このように、一度箱に入れてしまえば、後は箱の名前を呼ぶだけで、いつでも中身を取り出して使うことができるのです。とても便利ですね。
データ型とは?箱に入れるデータの種類
さて、データを入れるための「箱」の準備はできました。では、その箱には一体どんな種類のデータを入れることができるのでしょうか?
例えば、人の名前のような「文字」と、セミナーの定員のような「数字」では、性質が全く違いますよね。コンピューターも、データが文字なのか数字なのかを正しく理解していないと、適切に扱うことができません。(例えば、「あいうえお」に「10」を足す、といった計算はできませんよね)
そこで登場するのが「データ型」という考え方です。データ型とは、そのデータがどんな種類のものかを示す分類のことです。
ここでは、Laravel開発で最低限必要となる、代表的なデータ型を3つ紹介します。
1. 文字列型 (string)
「文字列(もじれつ)」は、その名の通り、文字の連なりのことです。人の名前、文章、メールアドレスなど、テキストデータを扱うときに使います。PHPでは、データをシングルクォーテーション ''
か、ダブルクォーテーション ""
で囲むことで、「これは文字列ですよ」と示します。
$userName = 'Taro Yamada';
$message = "Thank you for your application.";
2. 整数型 (integer)
「整数(せいすう)」は、-1, 0, 1, 2, 3... といった、小数点のつかない数字のことです。商品の値段や在庫数、年齢など、数値を扱うときに使います。数値なので、足し算や引き算などの計算ができます。文字列と違い、クォーテーションで囲まずにそのまま書きます。
$price = 5000;
$stock = 15;
$totalPrice = $price * 3;
3. 論理型 (boolean / ブール型)
「論理型(ろんりがた)」は、少し特殊なデータ型です。この型が持つデータは、true
(真) と false
(偽) のたった2種類しかありません。これは、「はい/いいえ」や「ON/OFF」のような、物事が正しいか正しくないか、という状態を表すのに使われます。
例えば、「ユーザーはログインしていますか?」という問いの答えは、「はい (true
)」か「いいえ (false
)」のどちらかですよね。このように、後の章で学ぶ「条件分岐」という処理で非常に重要な役割を果たします。
$isLoggedIn = true;
$hasCoupon = false;
このセクションでは、プログラミングの基本となる「変数」と「データ型」について学びました。一見地味に見えるかもしれませんが、これから作る全ての機能は、この変数という箱にデータを入れたり、出したり、加工したりすることの繰り返しです。
さて、今は一つの箱に一つのデータしか入れられませんでした。しかし、もし「セミナーの参加者一覧」のように、たくさんのデータを一つのまとまりとして扱いたい場合はどうすれば良いでしょうか?
次のセクションでは、そんなときに大活躍する「配列」という、たくさんの引き出しを持った特殊な箱について学んでいきましょう。
1-3 配列と繰り返し:たくさんのデータを効率よく扱う
前のセクションでは、「変数」という箱を使ってデータを一つずつ格納する方法を学びました。しかし、実際のアプリケーションでは、もっとたくさんのデータを一つのまとまりとして扱いたい場面が頻繁に登場します。
例えば、「セミナーの参加者名簿」や「ウェブサイトのナビゲーションメニューの項目一覧」などです。これらを $user1
, $user2
, $user3
, ... のように、一つ一つ別の変数として作っていたら、管理が大変で日が暮れてしまいますよね。
そこで登場するのが、今回のテーマである「配列(はいれつ)」です。たくさんのデータを効率よく扱うための、プログラミングにおける最重要ツールの一つです。
配列とは?たくさんの引き出しを持つ、特殊な箱
配列とは、複数のデータを入れることができる、特殊な変数です。
イメージとしては、「たくさんの引き出しがついた、一つの大きな整理棚」を想像してください。
この整理棚には、次のような特徴があります。
- 整理棚全体には「一つの名前」がついています。(例:
$attendees
) - それぞれの引き出しには、データが一つずつ入っています。
- 各引き出しには、「0」から始まる通し番号がついています。この番号を「インデックス」と呼びます。
この「0から始まる」という点が、プログラミングの非常に重要なポイントなので、ぜひ覚えておいてください。最初の引き出しは1番ではなく、0番です。
PHPでは、配列を角括弧 []
を使って作成します。
PHP
$attendees = ['Tanaka', 'Suzuki', 'Sato'];
これで、$attendees
という名前の整理棚が作られ、0番目の引き出しに 'Tanaka'
、1番目に 'Suzuki'
、2番目に 'Sato'
が入った状態になります。
特定の引き出しの中身を取り出したいときは、インデックス番号を指定します。
PHP
echo $attendees[0]; // 0番目の引き出しの中身、「Tanaka」が表示される
echo $attendees[2]; // 2番目の引き出しの中身、「Sato」が表示される
新しいデータをリストの末尾に追加するのも簡単です。
PHP
$attendees[] = 'Watanabe'; // 「Watanabe」がリストの最後(3番目の引き出し)に追加される
繰り返し処理(ループ):退屈な作業はコンピューターにおまかせ
さて、参加者名簿を配列として一つにまとめることができました。では、この名簿に載っている全員の名前を、画面に表示するにはどうすれば良いでしょうか?
もちろん、次のように書くこともできます。
PHP
echo $attendees[0];
echo $attendees[1];
echo $attendees[2];
echo $attendees[3];
しかし、もし参加者が100人いたら、このコードを100行も書かなければなりません。それは現実的ではありませんし、何より退屈ですよね。プログラミングは、このような退屈な繰り返し作業を自動化するためにあるのです。
そこで使うのが「繰り返し処理(ループ)」です。
PHPにはいくつかループの種類がありますが、配列のデータを一つずつ順番に処理する場合、foreach (フォーイーチ) という構文を使うのが最も簡単で一般的です。
foreach
は、「配列の中の各要素について(for each)、以下の処理を行う」という意味です。
執事にお願いする様子を想像してみてください。
あなた:「この参加者名簿(配列)があるんだけど、この中の一人一人(各要素)について、名前を読み上げてくれないかな?」
執事(foreach):「かしこまりました。お一人目、タナカ様。お二人目、スズキ様…」
このように、リストの最後まで自動で処理を繰り返してくれます。
foreach
の書き方は、次のようになります。
PHP
foreach ($array as $variable) {
// ここに繰り返したい処理を書く
}
$array
の部分には、処理したい配列(参加者名簿)を指定します。$variable
の部分には、配列から一つずつ取り出したデータを入れておくための一時的な変数(執事が今手に持っている名刺)を指定します。この変数名は、自分で分かりやすい名前をつけることができます。
実際のコードを見てみましょう。
PHP
$attendees = ['Tanaka', 'Suzuki', 'Sato', 'Watanabe'];
foreach ($attendees as $person) {
echo $person;
}
このコードが実行されると、コンピューターは次のように動きます。
$attendees
配列の最初の要素'Tanaka'
を取り出し、一時的な変数$person
に入れる。そしてecho $person;
を実行し、「Tanaka」と表示する。- 次に、2番目の要素
'Suzuki'
を取り出して$person
に入れ、同じ処理を行う。 - これを配列の最後の要素
'Watanabe'
まで繰り返す。 - 処理する要素がなくなったら、ループは自動的に終了する。
このセクションでは、たくさんのデータをまとめて扱うための「配列」と、その中身を効率よく処理するための「foreach
ループ」について学びました。この「配列とループ」の組み合わせは、Webアプリケーション開発において、ありとあらゆる場面で登場する、まさに最強のコンビです。
さて、データを箱に入れ、それを一つずつ処理できるようになりました。次のステップは、そのデータの内容に応じて、処理の流れを変える方法です。例えば、「もしログインしているユーザーが管理者だったら、特別なボタンを表示する」といった処理です。
次のセクションでは、プログラムの流れをコントロールするための「条件分岐」について学んでいきましょう。
1-3 配列と繰り返し:たくさんのデータを効率よく扱う
前のセクションでは、「変数」という箱を使ってデータを一つずつ格納する方法を学びました。しかし、実際のアプリケーションでは、もっとたくさんのデータを一つのまとまりとして扱いたい場面が頻繁に登場します。
例えば、「セミナーの参加者名簿」や「ウェブサイトのナビゲーションメニューの項目一覧」などです。これらを $user1
, $user2
, $user3
, ... のように、一つ一つ別の変数として作っていたら、管理が大変で日が暮れてしまいますよね。
そこで登場するのが、今回のテーマである「配列(はいれつ)」です。たくさんのデータを効率よく扱うための、プログラミングにおける最重要ツールの一つです。
配列とは?たくさんの引き出しを持つ、特殊な箱
配列とは、複数のデータを入れることができる、特殊な変数です。
イメージとしては、「たくさんの引き出しがついた、一つの大きな整理棚」を想像してください。
この整理棚には、次のような特徴があります。
- 整理棚全体には「一つの名前」がついています。(例:
$attendees
) - それぞれの引き出しには、データが一つずつ入っています。
- 各引き出しには、「0」から始まる通し番号がついています。この番号を「インデックス」と呼びます。
この「0から始まる」という点が、プログラミングの非常に重要なポイントなので、ぜひ覚えておいてください。最初の引き出しは1番ではなく、0番です。
PHPでは、配列を角括弧 []
を使って作成します。
$attendees = ['Tanaka', 'Suzuki', 'Sato'];
これで、$attendees
という名前の整理棚が作られ、0番目の引き出しに 'Tanaka'
、1番目に 'Suzuki'
、2番目に 'Sato'
が入った状態になります。
特定の引き出しの中身を取り出したいときは、インデックス番号を指定します。
echo $attendees[0]; // 0番目の引き出しの中身、「Tanaka」が表示される
echo $attendees[2]; // 2番目の引き出しの中身、「Sato」が表示される
新しいデータをリストの末尾に追加するのも簡単です。
$attendees[] = 'Watanabe'; // 「Watanabe」がリストの最後(3番目の引き出し)に追加される
繰り返し処理(ループ):退屈な作業はコンピューターにおまかせ
さて、参加者名簿を配列として一つにまとめることができました。では、この名簿に載っている全員の名前を、画面に表示するにはどうすれば良いでしょうか?
もちろん、次のように書くこともできます。
echo $attendees[0];
echo $attendees[1];
echo $attendees[2];
echo $attendees[3];
しかし、もし参加者が100人いたら、このコードを100行も書かなければなりません。それは現実的ではありませんし、何より退屈ですよね。プログラミングは、このような退屈な繰り返し作業を自動化するためにあるのです。
そこで使うのが「繰り返し処理(ループ)」です。
PHPにはいくつかループの種類がありますが、配列のデータを一つずつ順番に処理する場合、foreach (フォーイーチ) という構文を使うのが最も簡単で一般的です。
foreach
は、「配列の中の各要素について(for each)、以下の処理を行う」という意味です。
執事にお願いする様子を想像してみてください。
あなた:「この参加者名簿(配列)があるんだけど、この中の一人一人(各要素)について、名前を読み上げてくれないかな?」
執事(foreach):「かしこまりました。お一人目、タナカ様。お二人目、スズキ様…」
このように、リストの最後まで自動で処理を繰り返してくれます。
foreach
の書き方は、次のようになります。
foreach ($array as $variable) {
// ここに繰り返したい処理を書く
}
$array
の部分には、処理したい配列(参加者名簿)を指定します。$variable
の部分には、配列から一つずつ取り出したデータを入れておくための一時的な変数(執事が今手に持っている名刺)を指定します。この変数名は、自分で分かりやすい名前をつけることができます。
実際のコードを見てみましょう。
$attendees = ['Tanaka', 'Suzuki', 'Sato', 'Watanabe'];
foreach ($attendees as $person) {
echo $person;
}
このコードが実行されると、コンピューターは次のように動きます。
$attendees
配列の最初の要素'Tanaka'
を取り出し、一時的な変数$person
に入れる。そしてecho $person;
を実行し、「Tanaka」と表示する。- 次に、2番目の要素
'Suzuki'
を取り出して$person
に入れ、同じ処理を行う。 - これを配列の最後の要素
'Watanabe'
まで繰り返す。 - 処理する要素がなくなったら、ループは自動的に終了する。
このセクションでは、たくさんのデータをまとめて扱うための「配列」と、その中身を効率よく処理するための「foreach
ループ」について学びました。この「配列とループ」の組み合わせは、Webアプリケーション開発において、ありとあらゆる場面で登場する、まさに最強のコンビです。
さて、データを箱に入れ、それを一つずつ処理できるようになりました。次のステップは、そのデータの内容に応じて、処理の流れを変える方法です。例えば、「もしログインしているユーザーが管理者だったら、特別なボタンを表示する」といった処理です。
次のセクションでは、プログラムの流れをコントロールするための「条件分岐」について学んでいきましょう。
1-5 関数:同じ処理をまとめる便利な道具
これまでのセクションで、プログラミングの基本的な部品はほとんど揃いました。しかし、アプリケーションが複雑になってくると、同じようなコードの塊を、あちこちのファイルで何度も書かなければならない場面が出てきます。
例えば、「税込み価格を計算する」という処理を考えてみてください。商品の価格を表示するとき、カートの合計金額を計算するとき、注文確認メールを送るとき…様々な場所で同じ計算式が必要になりますよね。
もし、この計算式を毎回コピー&ペーストしていたらどうなるでしょうか?
- コードが長くなり、読みにくくなる。
- もし将来、消費税率が変わったら、その処理が書かれている全ての場所を探し出して修正しなければならない。一つでも修正し忘れたら、重大なバグに繋がります。
このような問題を解決してくれるのが、今回学ぶ「関数(かんすう)」です。
関数とは?いつでも呼び出せる、便利な道具箱
関数とは、特定の処理をひとまとめにし、名前をつけた「再利用可能なコードのブロック」です。
料理の「レシピ」に例えると分かりやすいかもしれません。
一度「美味しいカレーの作り方」というレシピを完成させておけば、カレーが食べたくなった時はいつでもそのレシピを参照するだけで、また同じ美味しいカレーが作れますよね。毎回、スパイスの調合から研究し直す必要はありません。
関数もこれと同じです。一度作っておけば、その処理が必要になるたびに、関数の名前を「呼び出す」だけで、いつでも同じ処理を実行させることができます。
PHPで関数を作るには、次のように書きます。
function 関数名(引数1, 引数2, ...) {
// ここに実行したい処理を書く
return 戻り値;
}
function
: これから関数を作りますよ、という合図のキーワードです。関数名
: あなたが自由につける、その関数の名前です。何をする関数か分かりやすい名前をつけましょう。( )
(引数): 関数に渡す「材料」です。例えば、税込み価格を計算する関数なら、材料として「税抜き価格」が必要ですよね。この引数は、無い場合もあります。{ }
: この中に、実行したい具体的な処理を書きます。return
(戻り値): 関数の処理結果として返す「完成品」です。処理結果が不要な場合は、return
も無い場合があります。
関数の使い方を学んでみよう
言葉の説明だけでは難しいので、具体的な例を3つのステップで見ていきましょう。
ステップ1:シンプルな関数
まずは、挨拶を表示するだけの簡単な関数です。この関数は、材料(引数)も完成品(戻り値)も必要ありません。
function showWelcomeMessage() {
echo 'Welcome to our seminar!';
}
この関数を使うには、名前を呼び出すだけです。
showWelcomeMessage();
ステップ2:引数のある関数
次に、特定の名前の人に挨拶する関数を考えてみましょう。この場合、「誰に」挨拶するかの情報が、材料(引数)として必要になります。
function greetByName($name) {
echo 'Hello, ' . $name . '!';
}
$name
という部分が、外からデータを受け取るための窓口です。呼び出すときに、この窓口に具体的なデータを入れてあげます。
greetByName('Yusei');
greetByName('Sato');
ステップ3:引数と戻り値のある、最も一般的な関数
最後に、冒頭で例に出した「税込み価格を計算する」関数を作ってみましょう。これが、最も実践的でよく使われる関数の形です。
- 材料(引数): 税抜き価格 (
$price
) - 完成品(戻り値): 計算された税込み価格
function calculatePriceWithTax($price) {
$taxRate = 0.10;
$result = $price * (1 + $taxRate);
return $result;
}
この関数を使えば、様々な商品の税込み価格を簡単に計算できます。
$bookPrice = 1500;
$dvdPrice = 3000;
$bookPriceWithTax = calculatePriceWithTax($bookPrice);
$dvdPriceWithTax = calculatePriceWithTax($dvdPrice);
echo $bookPriceWithTax;
echo $dvdPriceWithTax;
もし将来、税率が10%から変わったとしても、修正するのは calculatePriceWithTax
関数の内側、たった1箇所だけで済みます。これが、関数を使う最大のメリットです。
このセクションでは、同じ処理をまとめ、再利用可能にするための「関数」について学びました。関数をうまく使うことで、コードは整理され、見通しが良くなり、メンテナンスも格段にしやすくなります。
これで、PHPの基本的な操作は一通りマスターしたことになります。変数でデータを扱い、配列とループでたくさんのデータを処理し、if文で条件を判断し、そして関数で処理を部品化する。これらの知識があれば、様々なプログラムを組むことができます。
さて、第1章の最後のテーマは、いよいよLaravelの核心に迫る「オブジェクト指向」の考え方です。関数によって処理を「部品」にできましたが、もしデータと処理をひとまとめにした、もっと高度な「モノ」を作れたらどうでしょうか?
次のセクションで、その第一歩となる「クラス」と「オブジェクト」の世界を覗いてみましょう。
1-6 オブジェクト指向の第一歩(クラスとオブジェクト)
お疲れ様です。いよいよ、この準備体操の章も最後のセクションとなりました。そして、このセクションで学ぶことは、今後のLaravel学習の「考え方の根幹」となる、非常に重要なテーマです。
前のセクションでは、「関数」を使って処理を「部品」としてまとめる方法を学びました。これはとても便利ですが、実際の世の中の「モノ」は、もっと複雑だと思いませんか?
例えば、一台の「車」を考えてみましょう。車には、
- データ(情報): 「色」「車種名」「現在の速度」など
- ふるまい(操作): 「加速する」「ブレーキをかける」「ウインカーを出す」など
というように、「データ」と、そのデータを操作する「ふるまい」がセットになっています。
これまでの知識だけだと、これらの情報はバラバラに管理するしかありませんでした。
この「データ」と「ふるまい」を一つのまとまりとして扱えるようにしよう、というのが「オブジェクト指向(Object-Oriented Programming)」という考え方です。そして、Laravelはこのオブジェクト指向の考え方で設計されています。
クラスとオブジェクト:設計図と、それから作られた実体
オブジェクト指向を学ぶ上で、絶対に欠かせないのが「クラス」と「オブジェクト」という二つの言葉です。これは、**「設計図」と「設計図から作られた家」**の関係に例えるのが一番分かりやすいでしょう。
クラス (Class)
クラスとは、**「設計図」**です。
例えば、「家」のクラス(設計図)には、「家というものには、必ず『住所』と『部屋数』という情報があり、『ドアを開ける』という操作ができる」といった定義が書かれています。
重要なのは、設計図そのものは家ではないということです。設計図だけでは、雨風をしのぐことはできませんよね。
オブジェクト (Object)
オブジェクトとは、その**「設計図(クラス)を元に、実際に建てられた家」**のことです。
一つの「家」の設計図から、「山田さんの家(オブジェクト)」も「佐藤さんの家(オブジェクト)」も建てることができます。山田さんの家と佐藤さんの家は、同じ設計図から作られていますが、住所も部屋数も違う、それぞれが独立した「実体」です。
この「実際に作られたモノ」であるオブジェクトのことを、「インスタンス」と呼ぶこともあります。
PHPでクラスとオブジェクトを扱ってみよう
では、実際にPHPで「ユーザー」を管理するための、User
というクラス(設計図)を作ってみましょう。
クラス(設計図)の定義
クラスの中では、変数のことを「プロパティ」、関数のことを「メソッド」と呼びます。
class User
{
public $name;
public $email;
public function sayHello() {
echo 'Hello, my name is ' . $this->name;
}
}
class User { ... }
:User
という名前のクラス(設計図)を定義しています。public $name;
,public $email;
: この設計図から作られるオブジェクトが持つことになるデータ(情報)です。これをプロパティと呼びます。public function sayHello() { ... }
: このオブジェクトができる操作(ふるまい)です。これをメソッドと呼びます。$this->name
:$
this
sayHello
メソッドの中で、「このオブジェクト自身の名前(nameプロパティ)」を使いたい、という意味になります。
オブジェクト(実体)の作成と利用
設計図(クラス)ができたので、new
というキーワードを使って、実際のユーザー(オブジェクト)を作ってみましょう。
$user1 = new User();
$user2 = new User();
これで、User
の設計図を元に、$user1
さんと$user2
さんという、二人の独立したオブジェクトが生まれました。
次に、それぞれのオブジェクトのプロパティ(情報)を設定し、メソッド(操作)を呼び出してみます。オブジェクトのプロパティやメソッドにアクセスするには、アロー演算子 ->
を使います。
$user1 = new User();
$user1->name = 'Yamada';
$user1->email = 'yamada@example.com';
$user2 = new User();
$user2->name = 'Sato';
$user2->email = 'sato@example.com';
$user1->sayHello();
$user2->sayHello();
これを実行すると、$user1
は自分の名前を使って「Hello, my name is Yamada」と挨拶し、$user2
は自分の名前を使って「Hello, my name is Sato」と挨拶します。同じ設計図から作られても、それぞれが独立したモノとして振る舞うことが分かりますね。
なぜこれがLaravelで重要なのか?
「なんだか難しそうだな」と感じたかもしれません。しかし、この「クラス(設計図)」と「オブジェクト(実体)」の区別こそ、Laravelを理解する上で非常に重要になります。
今後の章で、私たちはUserモデルを扱います。これはUserというクラスです。
そして、User::find(1)のようなコードでデータベースから取得した一件のユーザー情報は、一人のユーザーのデータを持ったUserオブジェクトなのです。
$user->name
のように、->
を使ってユーザー名にアクセスできるのは、まさに今回学んだオブジェクトのプロパティにアクセスしているからなのです。
お疲れ様でした!これで、第1章「開発の準備をしよう」は全て終了です。
皆さんは、変数や配列といったデータの扱い方から、ループや条件分岐、関数、そしてオブジェクト指向の第一歩まで、PHPという言語の基本的な文法と概念を学び終えました。これで、Laravelという家が建つための、頑丈な基礎ができたことになります。
さあ、準備は万端です。
次の第2部から、いよいよ本書の主役であるLaravelフレームワークそのものの探検を始めます。私たちが作ったこの土台の上に、どんなに美しく、機能的な家を建てることができるのか。ぜひ、楽しみにしていてください。
第2部:Laravelの世界へようこそ - 基本の歩き方
おめでとうございます!皆さんは、Webアプリケーション開発の土台となるPHPの基礎知識を身につけ、プロのエンジニアとしての第一歩を踏み出しました。
この第2部から、いよいよ本書の主役である「Laravel」そのものの世界を探検していきます。第1部で築いた頑丈な基礎の上に、Laravelがどんなに機能的で、開発者をワクワクさせるような美しい「家」を建てさせてくれるのかを、実際に手を動かしながら体験していきましょう。
この部を終える頃には、あなたはLaravelの基本的な操作方法をマスターし、Webアプリケーションがどのようにリクエストを受け取り、画面を表示し、データベースと対話するのか、その一連の流れを理解できるようになっているはずです。
第2章:最高の開発環境をあなたの手に
Laravelの旅を始める前に、まず取り組むべきことがあります。それは、あなたのパソコンをLaravelアプリケーション開発に最適な「開発環境」にすることです。
この章では、スムーズで快適な開発を実現するために必要なツールを揃え、設定する方法を学びます。
2-1 なぜ開発環境が重要なのか?
「開発環境って、何だか難しそう…」
「ただコードが書ければいいんじゃないの?」
そう思う方もいるかもしれません。なぜ、わざわざ「環境」を整える必要があるのでしょうか?
これを、料理人のキッチンに例えてみましょう。
腕の良いシェフは、必ず自分のキッチンを最高の状態に整えています。切れ味の良い包丁、火加減を調整しやすいコンロ、整理された調味料棚、清潔なまな板…。これらの道具が完璧に揃っているからこそ、シェフは調理そのものに集中し、最高の料理を生み出すことができます。
もし、薄暗い部屋で、切れ味の悪い包丁と、火力が安定しないカセットコンロだけで料理をしようとしたら、どうなるでしょうか?きっと、料理の味以前に、作業のやりにくさでストレスが溜まってしまいますよね。
プログラミングにおける開発環境も、このシェフのキッチンと全く同じです。
快適な開発環境とは、私たちがストレスなくコードを書き、作ったアプリケーションを正しく動かすために必要な、以下のものが全て揃って連携している状態を指します。
- PHP本体: プログラムを実行するためのエンジン
- Webサーバー: ブラウザからのリクエストを受け付ける受付係
- データベース: データを保存しておくための倉庫
- Laravelフレームワーク: アプリケーションの骨組みとなる道具一式
- コードエディタ: コードを書くための高機能なノート
これらのツールがそれぞれバラバラに存在していると、うまく連携できずに「自分のパソコンでは動いたのに、本番のサーバーでは動かない」といった、開発現場で最も恐れられる問題の原因になります。
開発環境をしっかりと整えることは、これらの問題を未然に防ぎ、私たちが本来集中すべき「アプリケーション作りの楽しさ」に没頭させてくれる、非常に重要な準備なのです。
かつては、この環境構築こそが、初心者にとって最初の、そして最大の壁でした。しかし、現代には素晴らしい解決策があります。
次のセクションでは、このプロフェッショナルなキッチン一式を、魔法のように一瞬で用意してくれる「Laravel Sail」という画期的なツールを使って、あなたのパソコンに最高の開発環境を構築していきます。
2-2 DockerとLaravel Sailで未来の開発環境を体験しよう
前のセクションでは、開発環境をシェフのキッチンに例えました。そして、その準備は大変だとお伝えしました。しかし、もし「プロ仕様のキッチン一式が、箱詰めされて届くサービス」があったら、どうでしょうか?
今回紹介する「Laravel Sail(セイル)」は、まさにそのようなサービスです。そして、その魔法を実現しているのが「Docker(ドッカー)」という技術です。
このセクションでは、これらのモダンなツールを使って、あなたのパソコンをクリーンに保ちながら、最高の開発環境を一瞬で手に入れる方法を学びます。
Dockerって何? ソフトウェアの「水槽」です
まず、Sailの土台となっているDockerについて理解しましょう。
Dockerとは、一言で言うと「コンテナ型仮想化」という技術を使って、アプリケーションの実行環境を構築・運用するためのプラットフォームです。
…と言われても、きっとピンとこないですよね。もっと簡単な例え話をしましょう。
あなたのパソコンを、一軒の「大きな家」だと考えてください。
昔ながらの方法では、PHPを動かすために、家の水道管(OS)に直接PHP用の配管を繋ぎ、データベースを動かすために、専用の部屋をリフォームする必要がありました。もし、別のプログラムが違うバージョンの配管を必要としたら、家の中はグチャグチャになり、互いに干渉しあってしまいます。
そこで登場したのが「コンテナ」という考え方です。
コンテナとは、**「自己完結した、魔法の水槽」**のようなものです。
この水槽の中には、魚(ソフトウェア)が生きるために必要な、水、空気、エサ、水草などが全て揃っています。水槽の中は完全に独立した世界なので、家の他の部屋で何が起きていようと、全く影響を受けません。
Dockerは、この魔法の水槽を管理してくれるシステムです。
「PHP 8.2が入った水槽」や「MySQL 8.0が入った水槽」を、あなたの家(パソコン)の中に、好きなだけ置くことができます。それぞれの水槽は完全に隔離されているので、互いに干渉することはありません。そして、あなたの家自体は、何も汚れることがないのです。
これが、世界中の開発者がDockerを愛用する理由です。
Laravel Sailの役割とは?
では、Laravel Sailとは何でしょうか?
Sailは、このDockerを、Laravel開発のために「超簡単」に使えるようにしてくれる、Laravel公式のツールです。
例えるなら、Sailは**「Laravel専門の、腕利きの水槽管理人」**です。
私たちは、どの水槽(PHP, MySQLなど)が必要で、それらをどうやって繋げばいいのか、といった専門知識を知らなくても大丈夫です。Sailに「Laravelプロジェクトを始めたい!」と一言お願いするだけで、この水槽管理人が、必要な水槽を全て用意し、完璧に設置してくれるのです。
実際に開発環境を構築してみよう
それでは、実際に手を動かして、あなたのパソコンに開発環境を構築していきましょう。
ステップ0:Docker Desktopのインストール
SailはDockerを利用するため、まず大元であるDockerをパソコンにインストールする必要があります。「Docker Desktop」というアプリケーションをインストールしましょう。
公式サイトにアクセスし、お使いのOS(Mac or Windows)に合ったインストーラーをダウンロードして、他のアプリケーションと同じようにインストールしてください。インストール後、Docker Desktopを起動しておきましょう。(Windowsの方は、WSL2という機能の有効化も必要になります。詳細は公式サイトの指示に従ってください)
ステップ1:Laravelプロジェクトを新規作成する
ターミナル(macOS)またはWSL2のターミナル(Windows)を開き、プロジェクトを作成したいディレクトリに移動してください。そして、次のコマンドを実行します。
curl -s "https://laravel.build/seminar-app" | bash
この一行のコマンドが、魔法の呪文です。Laravelのサーバーからプロジェクト作成用のスクリプトをダウンロードし、それを使ってDocker上に「seminar-app」という名前の新しいLaravelプロジェクトを自動で構築してくれます。
ステップ2:プロジェクトのディレクトリに移動する
作成が完了したら、プロジェクトのディレクトリに移動します。
cd seminar-app
ステップ3:Sailを起動する
いよいよ、用意された開発環境(水槽たち)を起動します。次のコマンドを実行してください。
./vendor/bin/sail up
sail up
は、「全ての水槽の電源を入れてくれ!」という命令です。初めて実行する際は、水槽の材料(Dockerイメージ)をインターネットからダウンロードするため、少し時間がかかります。しかし、2回目以降はすぐに起動します。
ターミナルがこの処理で専有されます。バックグラウンドで起動させたい場合は、./vendor/bin/sail up -d
と入力します。
ステップ4:動作確認
Sailが起動したら、別のターミナルウィンドウを開き(または sail up -d
を利用し)、同じ seminar-app
ディレクトリで次のコマンドを実行して、データベースとの接続をテストします。
./vendor/bin/sail artisan migrate
Migration completed successfully.
のようなメッセージが表示されれば成功です。
ステップ5:ブラウザでアクセス!
全ての準備が整いました。Webブラウザを開き、アドレスバーに http://localhost
と入力してください。
おなじみのLaravelのウェルカムページが表示されましたか?
表示されたなら、大成功です!あなたのパソコンには今、プロ仕様の開発環境が完璧にセットアップされました。
お疲れ様でした。少し複雑に見えたかもしれませんが、皆さんは今、世界中の多くの企業で採用されている、非常にモダンでクリーンな開発環境を手に入れました。
さて、プロのキッチンは用意できました。次のセクションでは、最高の料理を作るための、使いやすい包丁やまな板にあたる「コードエディタ」を準備し、さらに快適な開発ができるように設定していきましょう。
2-3 Visual Studio Codeのセットアップと便利な拡張機能
プロ仕様のキッチン(Laravel Sailによる開発環境)の準備ができましたね。これで、いつでも料理(開発)を始められる状態になりました。
最後に、最高の料理を作るために欠かせない、シェフ愛用の「包丁」と「まな板」にあたる「コードエディタ」を準備しましょう。コードエディタとは、プログラミングのコードを書くことに特化した高機能なテキストエディタのことです。
世の中にはたくさんのコードエディタがありますが、本書では、現在のWeb開発において世界標準とも言える「Visual Studio Code(ビジュアル・スタジオ・コード、略してVS Code)」を使用します。
なぜVisual Studio Codeなのか?
VS Codeをおすすめする理由はとてもシンプルです。
- 無料で利用できる
- 動作が非常に高速
- 「拡張機能」で自由にカスタマイズできる
- 世界中の開発者が使っており、情報が豊富
これらの理由から、多くのプロの現場で採用されており、これから皆さんがエンジニアとしてキャリアを歩む上で、間違いなく最高のパートナーとなってくれます。
Visual Studio Codeのインストール
まずはVS Codeをあなたのパソコンにインストールしましょう。
- Webブラウザで、Visual Studio Codeの公式サイトにアクセスします。
- トップページに、あなたのOS(WindowsやMac)に合ったダウンロードボタンが表示されているはずです。クリックしてインストーラーをダウンロードしてください。
- ダウンロードしたファイルを開き、他のアプリケーションと同じようにインストール作業を完了させます。
インストールが完了したら、一度VS Codeを開いてみましょう。このような画面が表示されるはずです。
拡張機能でVS Codeをパワーアップしよう
VS Codeの真の力は、「拡張機能(Extensions)」を追加することで発揮されます。
拡張機能とは、VS Codeに新しい機能を追加するための小さなプログラムです。例えるなら、シェフの包丁に、特定の野菜を千切りにするためのアタッチメントや、果物の皮をきれいに剥くためのアタッチメントを取り付けるようなものです。基本の道具に専門的な能力を追加することで、作業効率が劇的に向上します。
VS Codeの左側にある、四角が4つ並んだようなアイコンをクリックすると、拡張機能を検索・インストールする画面が開きます。
ここでは、Laravel開発を快適に進めるために、最低限入れておきたい、おすすめの拡張機能をいくつか紹介します。検索ボックスに名前を入力して、それぞれ「Install」ボタンを押してください。
1. Laravel Blade Snippets
Laravelのビュー(画面の見た目)を作成する際に使う「Blade」というテンプレート言語の色付けや、コードの自動補完をしてくれる拡張機能です。@if
や @foreach
といったBlade特有の構文を、簡単かつ正確に入力できるようになります。
2. PHP Intelephense
PHPコードを書く上で、非常に強力なサポートをしてくれる拡張機能です。コードの文法ミスをリアルタイムで教えてくれたり、関数の使い方をヒントとして表示してくれたりします。これがあるだけで、コーディングのスピードと正確性が格段に向上します。
3. Prettier - Code formatter
書いたコードの見た目(インデントの深さ、スペースの数など)を、保存するたびに自動で綺麗に整えてくれる拡張機能です。コードの見た目を常に一定のルールに保つことは、複数人で開発を行う上で非常に重要です。
お疲れ様でした!
これで、開発環境(キッチン)、コードエディタ(調理道具)、そして便利な拡張機能(アタッチメント)と、Webアプリケーションを開発するための全ての準備が整いました。あなたは今、プロのエンジアが使うものと全く同じ、最高の開発環境を手に入れたのです。
長い準備の章はこれで終わりです。
次の章から、いよいよLaravelのコードに触れていきます。私たちが作ったこのピカピカのキッチンで、どんな料理を作っていけるのか、ぜひ楽しみにしていてください!
前の章では、実際に手を動かして「ルート → コントローラー → ビュー」というLaravelの基本的な処理の流れを体験しました。
もしかしたら、「どうしてこんな風にファイルを分けるんだろう?」「ブラウザでURLを開くと、裏側では一体何が起きているんだろう?」と、疑問に思った方もいるかもしれません。
この章では、一度コーディングの手を休めて、その「なぜ?」に答えるための理論、つまり全てのWebアプリケーションが動作する上での、根本的な「仕組み」について解説します。この仕組みを理解することで、今後の学習がより深く、そしてスムーズになりますよ。
ブラウザとサーバーの対話:リクエストとレスポンス
皆さんがWebサイトを見るとき、ブラウザと、Webサイトのデータが置かれているサーバーとの間では、常に「会話」が行われています。この会話は、非常に礼儀正しい2つのステップで構成されています。
- リクエスト (Request):ブラウザからサーバーへの「お願い」
- レスポンス (Response):サーバーからブラウザへの「お返事」
これは、レストランでの注文にとてもよく似ています。
- あなた(利用者):お客さん
- ブラウザ:ウェイター
- サーバー(Laravelアプリケーション):厨房のシェフ
リクエスト:ウェイターへの注文
あなたが「セミナー一覧ページが見たい」と思って、ブラウザのアドレスバーにURLを入力してEnterキーを押すと、ウェイター(ブラウザ)が厨房(サーバー)へ注文を伝えに行きます。これがリクエストです。
このとき、ウェイターは注文票に「どのテーブルの客が(IPアドレス
)、何を食べたいか(URL
)、どんな方法で(メソッド
)」といった情報を書いて厨房に渡します。Webのメソッドで最も一般的なのは、ページを見るためのGET
と、フォームを送信するためのPOST
です。
レスポンス:厨房からの料理
注文票を受け取った厨房(サーバー)は、シェフ(Laravel)がレシピに従って料理(Webページ)を作ります。料理が完成すると、ウェイター(ブラウザ)がそれを受け取って、あなたのテーブルまで運んできてくれます。これがレスポンスです。
レスポンスには、注文通りの料理(HTMLファイル
)だけでなく、「ご注文の品、ご用意できました(ステータスコード 200 OK
)」といった伝票も付いてきます。もし厨房にその料理がなければ、「申し訳ありません、品切れです(ステータスコード 404 Not Found
)」というお返事が返ってきます。
この**「リクエスト」と「レスポンス」**のサイクルが、Webの全ての基本です。
MVCモデル:コードを綺麗に整理する魔法
さて、リクエストを受け取った厨房(サーバー)の中は、どうなっているのでしょうか?一人のシェフが全てをこなしているわけではありません。美味しい料理を効率よく提供するために、プロの厨房では役割分担がされています。
Laravelのような現代的なフレームワークは、この役割分担の考え方として「MVCモデル」という設計パターンを採用しています。
- Model (モデル):食材の仕入れと管理を担当する「食材の専門家」
- View (ビュー):料理の盛り付けを担当する「フードスタイリスト」
- Controller (コントローラー):全体の司令塔となる「総料理長」
それぞれの役割
- ウェイターから注文(リクエスト)が入ると、まず**総料理長(C)**が受け取ります。
- 総料理長(C)は、レシピ(ロジック)を見て、必要な食材を**食材の専門家(M)**に「取ってきてくれ」と指示します。食材の専門家(M)は、冷蔵庫(データベース)とのやり取りを専門に行い、新鮮な食材(データ)を総料理長に渡します。
- 総料理長(C)は、受け取った食材をレシピ通りに調理します。
- 調理が終わると、総料理長(C)は出来上がった料理を**フードスタイリスト(V)**に渡し、「このお皿に美しく盛り付けてくれ」と指示します。フードスタイリスト(V)は、料理の味や作り方は知りませんが、どうすれば美味しそうに見えるか(プレゼンテーション)のプロです。
- 美しく盛り付けられた料理が、最終的にお客さん(ブラウザ)に提供されます。
なぜ分けるのか?
なぜ、こんな面倒な役割分担をするのでしょうか?それは、「関心の分離」と呼ばれる、メンテナンスしやすいソフトウェアを作るための非常に重要な考え方だからです。
- 盛り付け方を変えたい(Viewの修正)とき、総料理長(C)や食材の専門家(M)の仕事に影響はありません。
- 調理法を変えたい(Controllerの修正)とき、食材の仕入れ方(M)や盛り付け方(V)を変える必要はありません。
- 食材の仕入れ先を変えたい(Modelの修正)ときも同様です。
このように、それぞれの専門家が自分の仕事に集中できるため、変更に強く、コードの見通しが良いアプリケーションを作ることができるのです。
私たちが前の章で体験した「ルート → コントローラー → ビュー」という流れは、まさにこのMVCモデルそのものです。まだ食材の専門家(Model)は登場していませんが、今後の章でデータベースを扱う際に、彼にも登場してもらうことになります。
この章で学んだ「リクエスト・レスポンス」と「MVCモデル」は、Web開発の理論的な背骨となる部分です。この全体像を頭の片隅に置いておくだけで、これから書くコード一行一行の意味が、より深く理解できるようになるはずです。
さて、理論の次は再び実践です。次の章では、総料理長(コントローラー)が、フードスタイリスト(ビュー)に、調理した食材(データ)を渡す方法を学んでいきましょう。
第2部:Laravelの世界へようこそ - 基本の歩き方をマスターする
おめでとうございます!あなたは今、プロのWebアプリケーション開発者になるための、大きな一歩を踏み出しました。この第2部では、本格的な開発に入る前に、必要不可欠な知識と環境を整えます。
第4章:はじめてのLaravelプロジェクト
前の章までで、私たちはLaravelアプリケーションを動かすための環境を整え、「ルート → コントローラー → ビュー」という、リクエストが処理される基本的な流れを学びました。
この章では、その流れに「データ」という命を吹き込みます。ただ静的なページを表示するだけでなく、動的に変わる情報を画面に表示させることで、私たちのプロジェクトを本物のWebアプリケーションへと進化させていきましょう。
4-1 コントローラーからビューへデータを渡す
現在の私たちのアプリケーションは、SeminarController
が seminars.index
というビューを返すだけで、いつ誰が見ても全く同じ内容が表示されます。しかし、実際のセミナーサイトでは、開催されるセミナーのリストは日々変わるはずです。
このような動的な情報を扱うには、コントローラー(ロジック担当)からビュー(見た目担当)へ、表示したいデータを渡してあげる必要があります。
これを、再びレストランの厨房の例えで考えてみましょう。
総料理長(コントローラー)は、フードスタイリスト(ビュー)に、ただ「今日のランチメニューの看板を作ってくれ」と頼むだけではありません。「今日のランチは『特製ハンバーグ』だ。この情報を使って看板を作ってくれ」というように、具体的なデータを渡します。
Laravelでは、このデータの受け渡しを、view()
関数の2番目の引数を使って、非常に簡単に行うことができます。
ステップ1:コントローラーでデータを用意し、ビューに渡す
まずは、一つのセミナータイトルをビューに渡してみましょう。
app/Http/Controllers/SeminarController.php を開き、index メソッドを次のように修正します。
// ...
class SeminarController extends Controller
{
public function index()
{
$seminarTitle = 'Laravel From Scratch';
return view('seminars.index', ['title' => $seminarTitle]);
}
}
view()
関数の第2引数に、['キー' => 値]
の形で配列を渡している点に注目してください。
'title'
:これが、ビューの中でデータを取り出すときに使う「名前(キー)」になります。$seminarTitle
:これが、実際に渡されるデータ(値)です。
ステップ2:ビューでデータを受け取って表示する
次に、ビュー側で、コントローラーから渡されたデータを受け取って表示します。
resources/views/seminars/index.blade.php を開き、<h1> タグの中を修正しましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>セミナー一覧</title>
</head>
<body>
<h1>{{ $title }}</h1>
<p>こちらは現在開催予定のセミナー一覧ページです。</p>
</body>
</html>
{{ $title }} という見慣れない記法が出てきましたね。
これが、Laravelのテンプレートエンジン「Blade」の最も基本的な機能で、変数の内容を画面に表示するための命令です。
{{ }}
で変数を囲むと、Laravelはコントローラーから渡されたデータの中から 'title'
というキーを探し出し、その値 ('Laravel From Scratch'
) をこの場所に表示してくれます。また、この記法は、セキュリティ対策(クロスサイトスクリプティング対策)も自動的に行ってくれる、非常に安全な書き方です。
ファイルを保存して、ブラウザで http://localhost を更新してください。
見出しが「Laravel From Scratch」に変わっていれば成功です!
ステップ3:複数のデータを配列で渡して表示する
次に、もっと実践的な例として、複数のセミナータイトルを「配列」でビューに渡し、一覧表示してみましょう。
まず、SeminarController
を修正します。
// ...
class SeminarController extends Controller
{
public function index()
{
$seminars = [
'Laravel From Scratch',
'Advanced Eloquent',
'TDD with Pest'
];
return view('seminars.index', ['seminarList' => $seminars]);
}
}
次に、seminars/index.blade.php
を修正し、Bladeの @foreach
を使って、受け取った配列のデータを一つずつ表示します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>セミナー一覧</title>
</head>
<body>
<h1>開催予定セミナー</h1>
<ul>
@foreach ($seminarList as $seminar)
<li>{{ $seminar }}</li>
@endforeach
</ul>
</body>
</html>
@foreach
から @endforeach
の間が、配列の要素の数だけ繰り返されます。コントローラーから 'seminarList'
というキーで渡された配列が、ビューの中では $seminarList
という変数として使えます。
ファイルを保存して、ブラウザを更新してください。
セミナーのリストが箇条書きで表示されたでしょうか?
このセクションでは、コントローラーからビューへデータを渡し、それを画面に動的に表示するという、Webアプリケーション開発の核となる技術を学びました。
しかし、今はまだセミナーのデータがコントローラーの中に直接書かれています(ハードコーディングと言います)。本来、このようなデータはデータベースに保存し、そこから取り出すべきです。
次の章では、いよいよMVCの「M」にあたるモデルを導入し、データベースを扱う方法について学んでいきます。
かしこまりました。
それでは、「4-2 Laravelプロジェクトの地図:主要なディレクトリの役割」を執筆します。
4-2 Laravelプロジェクトの地図:主要なディレクトリの役割
VS CodeでLaravelプロジェクトを開くと、たくさんのファイルやフォルダが並んでいて、最初はどこに何があるのか分からず、少し戸惑ってしまうかもしれません。
しかし、心配は無用です。これら全てを一度に覚える必要はありません。ちょうど、初めて訪れる都市で、いきなり全ての路地を覚えられないのと同じです。まずは、主要な地区や大きな通りがどこにあるのか、地図を広げて確認することから始めましょう。
このセクションでは、あなたのLaravelという都市の「地図」を読み解き、これから頻繁に訪れることになる、特に重要なディレクトリ(フォルダ)の役割について解説していきます。
app
フォルダ:都市の心臓部(ビジネス街と市役所)
app
フォルダは、あなたのアプリケーションの「頭脳」であり「心臓部」です。アプリケーションのほとんどのコアなロジックは、この中に書かれます。ユーザー登録、データ処理、計算など、アプリケーションの具体的な「ふるまい」を定義するファイルがここに集まります。
- app/Http/Controllers私たちがすでに利用したController(コントローラー)が格納される場所です。外部からのリクエストを受け取り、適切な指示を出す「市役所の各担当部署」や「オフィスビル」のようなものです。
- app/Models今後の章で詳しく学びますが、データベースとの対話を専門に行うModel(モデル)が格納される場所です。市の記録保管庫(データベース)から、必要な書類(データ)を取り出したり、新しい書類を保管したりする方法を知っている「記録係」や「司書」がいる場所だと考えてください。
routes
フォルダ:都市の交通網(道路地図と案内標識)
routes
フォルダは、都市の交通システム全体を管理する場所です。ここにあるファイルが、ユーザーからのアクセス(リクエスト)を、どのコントローラーのどの処理に届けるかを決定する「公式な道路地図」の役割を果たします。
- routes/web.php私たちがすでに編集したファイルです。Webブラウザを通じて行われる、一般的なユーザーからのアクセスに関するルートを定義します。
- routes/api.phpこちらは、モバイルアプリや他のコンピュータプログラムからのアクセス(APIリクエスト)のための、もう一つの特別な道路地図です。今はまだ気にする必要はありません。
resources
フォルダ:都市の景観を作る(素材とデザイン工房)
resources
フォルダは、ユーザーの目に触れる「見た目」に関する、未加工の素材が全て保管される場所です。アーティストやデザイナーが働く「デザイン工房」が集まる地区だとイメージしてください。
- resources/viewsこちらもすでにお馴染みですね。ユーザーに表示されるWebページの設計図となる、Bladeテンプレートファイル(.blade.php)がここに置かれます。
- resources/css, resources/jsWebページを彩るためのCSS(スタイルシート)や、動きを加えるためのJavaScriptファイルの置き場所です。現時点では、これらのフォルダの中身はほとんど空です。
database
フォルダ:都市の土台と記録(設計図と初期データ)
database
フォルダは、アプリケーションが利用するデータの「構造」を定義し、管理するための場所です。都市の土台となるインフラの設計図や、市の記録保管庫の管理事務所が集まっています。
- database/migrationsデータベースのテーブル構造を定義するための「設計図ファイル」がここに格納されます。どのようなテーブルがあり、それぞれどんな列を持つのか、その歴史が全てコードとして記録されます。
- database/seedersアプリケーションの初期データを投入するためのファイルが置かれます。例えば、アプリケーションを最初に動かすときのために、テスト用のユーザーデータや商品データをあらかじめデータベースに用意しておく、といった使い方ができます。
.env
ファイル:都市の秘密の管理室
これはフォルダではありませんが、プロジェクトのルートディレクトリにある、非常に重要なファイルです。
.env
ファイルは、あなたのアプリケーションの「環境設定」を記述する場所です。データベースの接続情報(ホスト名、データベース名、パスワードなど)や、外部サービスのAPIキーといった、環境によって変わる可能性のある、そして他人に知られてはいけない重要な情報をここに書きます。
例えるなら、都市のインフラを管理する、鍵のかかった秘密の管理室です。このファイルは非常に重要なので、Gitなどのバージョン管理システムには含めないのが一般的です。
この地図を一度に全て暗記する必要はありません。これから私たちが「セミナー受付システム」を構築していく過程で、これらのフォルダやファイルを何度も訪れることになります。その旅を通して、それぞれの役割は自然と身についていくはずです。
さて、都市の全体像が掴めたところで、次の章からは、いよいよ都市のインフラ、特にデータの保管庫であるデータベースの建設に取り掛かっていきます。
第5章:ルーティングとコントローラー - リクエストを捌く司令塔
これまでの章で、私たちは「ブラウザからのリクエストが routes/web.php
ファイルに届き、それがコントローラーの特定のメソッドを呼び出す」という一連の流れを体験してきました。
この章では、そのWebアプリケーションの根幹をなす「ルーティング」と「コントローラー」の役割を改めて深く理解し、より動的で、よりメンテナンスしやすいアプリケーションを構築するための、さらに進んだテクニックを学んでいきます。
5-1 ルーティングの役割の再確認
まず、ルーティングの最も重要な役割を思い出しましょう。それは、**「交通整理」**です。
routes/web.php
ファイルは、アプリケーションの「総合受付」や「電話交換手」のようなものです。様々な宛先へのリクエスト(電話)がひっきりなしに入ってきますが、このファイルの役目は、その一つ一つを、適切な担当部署(コントローラーのメソッド)に、ただ繋ぐことだけです。
// トップページへのアクセスは、SeminarControllerのindexメソッドへ
Route::get('/', [SeminarController::class, 'index']);
// ユーザー登録ページへのアクセスは、UserControllerのcreateメソッドへ
// Route::get('/register', [UserController::class, 'create']);
このように、routes/web.php
を見れば、このアプリケーションにどのようなURL(入り口)が存在するのかが一目でわかる、いわば「目次」のような状態を保つことが理想です。具体的な処理は全てコントローラーに任せる。この「関心の分離」が、見通しの良いコードを保つための秘訣です。
5-2 ルートパラメータで動的なURLを扱う
さて、ここからがこの章の新しいテーマです。
現在の私たちのアプリケーションでは、「セミナー一覧」ページしか表示できません。もし、「特定のセミナーの詳細ページ」を表示したい場合はどうすれば良いでしょうか?
セミナーが100個あるからといって、routes/web.php
に100個のルートを定義するのは現実的ではありません。
// こうは書かない!
// Route::get('/seminars/1', ...);
// Route::get('/seminars/2', ...);
// Route::get('/seminars/3', ...);
こんなときに使うのが「ルートパラメータ」です。URLの一部を「変数」のように扱うことができる、非常に強力な機能です。
routes/web.php
に、次のようにルートを定義してみましょう。
Route::get('/seminars/{id}', [SeminarController::class, 'show']);
URLの {id}
と波括弧で囲んだ部分が、ルートパラメータです。これは、「/seminars/
に続く部分を、id
という名前の変数として受け取りますよ」という意味になります。
次に、このid
をコントローラー側で受け取ります。SeminarController.php
に、show
という新しいメソッドを追加してください。
// SeminarController.php の中
public function show($id)
{
return 'This is the details page for seminar with ID: ' . $id;
}
ルートパラメータ {id}
の部分が、show
メソッドの引数 $id
に自動的に渡されるのです。
ファイルを保存して、ブラウザで http://localhost/seminars/1
にアクセスしてみてください。「ID: 1」と表示されるはずです。次に http://localhost/seminars/123
にアクセスすれば、「ID: 123」と表示が変わります。
一つのルート定義だけで、無数の詳細ページに対応できる。これがルートパラメータの力です。
5-3 名前付きルートでメンテナンス性を高める
もう一つ、プロの技として「名前付きルート」を覚えておきましょう。
これは、ルートに固有の名前をつけて管理する方法です。
例えば、セミナー詳細ページへのURLを、ビューファイルの中で <a href="/seminars/1">
のように直接書いていたとします。もし将来、URLの構造を /seminars/
から /events/
に変更したくなったら、このリンクが書かれている全てのファイルを探し出して修正しなければならず、大変です。
そこで、ルートに名前をつけます。
// routes/web.php の中
Route::get('/seminars/{id}', [SeminarController::class, 'show'])->name('seminars.show');
このように ->name('seminars.show')
を末尾につけるだけで、このルートに seminars.show
という名前がつきました。
そして、ビューファイルの中では、route()
ヘルパー関数を使って、この名前でURLを呼び出します。
{{-- Bladeファイルの中 --}}
<a href="{{ route('seminars.show', ['id' => 1]) }}">
View Seminar Details
</a>
こうしておけば、将来 web.php
のURL定義を /events/{id}
に変更したとしても、ビューファイルの方は一切変更する必要がありません。アプリケーションがURLの具体的な形に依存しなくなり、非常に変更に強くなります。
この章では、ルーティングとコントローラーの基本を復習し、さらにルートパラメータや名前付きルートといった、より実践的なテクニックを学びました。
URLの設計は、アプリケーションの使いやすさを決める重要な要素です。この章で学んだ知識を使えば、柔軟で分かりやすいURL構造を自由に設計できるようになったはずです。
さて、個別のセミナーページを表示する準備はできましたが、まだ表示しているのはIDだけです。次の章では、いよいよデータベースを導入し、このIDを使って、セミナーのタイトルや説明文といった本物のデータを取得する方法を学んでいきます。
第6章:Bladeテンプレート - 美しい画面を作るアーティスト
第6章:Bladeテンプレート - 見た目を美しく、賢く作る
これまでの章で、私たちはコントローラーからビューへデータを渡し、その内容を画面に表示することに成功しました。その際、{{ $variable }}
や @foreach
といった、見慣れない記法が登場したのを覚えているでしょうか。
あれらは全て、Laravelに搭載されている「Blade(ブレード)」という、テンプレートエンジンの機能です。
この章では、Bladeの基本的な使い方を改めて整理し、なぜ私たちが素のPHPではなくBladeを使うべきなのか、その理由とメリットについて深く掘り下げていきます。
6-1 Bladeの基本構文と画面へのデータ表示
なぜBladeを使うのか?
まず、「なぜわざわざBladeという特別な書き方を学ぶ必要があるの?」という疑問からお答えしましょう。
もちろん、通常のPHPファイル (.php
) の中に、HTMLとPHPのコードを混ぜて書くことも可能です。
<h1><?php echo $title; ?></h1>
<ul>
<?php foreach ($seminarList as $seminar): ?>
<li><?php echo $seminar; ?></li>
<?php endforeach; ?>
</ul>
この書き方でも、同じ結果を得ることはできます。しかし、コードが長くなるにつれて、<?php
や echo
, ;
が増えていき、見た目がごちゃごちゃして読みにくくなると思いませんか?
Bladeは、このようなHTML内のPHP記述を、より直感的で、美しく、そして安全に書くための「PHPのショートカット記法」のようなものです。私たちがBladeのシンプルな記法で書いたコードは、裏側でLaravelが最適化された素のPHPコードに変換してくれているのです。
データ表示: {{ }}
コントローラーから渡された変数の内容を表示するには、二重の中括弧 {{ }}
で変数を囲みます。
<h1>{{ $title }}</h1>
これは、<?php echo $title; ?>
と書くのと全く同じ意味ですが、はるかに短く、スッキリしていますね。
そして、この記法にはもう一つ、非常に重要な役割があります。それは、**自動的なセキュリティ対策(エスケープ処理)**です。
もし、変数の中に悪意のあるJavaScriptコード(<script>alert('test')</script>のような)が含まれていたとしても、{{ }} はそれをただの文字列として無害化して表示してくれます。これにより、クロスサイトスクリプティング(XSS)と呼ばれる代表的なサイバー攻撃から、アプリケーションを自動的に守ってくれるのです。
もし、意図的にHTMLタグをそのまま表示したい場合は、{!! !!}
という記法を使いますが、セキュリティ上のリスクがあるため、信頼できるデータ以外には絶対に使わないようにしましょう。
制御構文: @
ディレクティブ
if
文による条件分岐や、foreach
文による繰り返しといった、PHPの制御構文も、Bladeでは @
から始まる「ディレクティブ」という形で、よりクリーンに書くことができます。
条件分岐 @if
PHPの if
文は、Bladeでは @if
, @elseif
, @else
, @endif
を使って表現します。
@if ($seminar->is_online)
<p>このセミナーはオンライン開催です。</p>
@else
<p>このセミナーは会場での開催です。</p>
@endif
PHPのタグで囲むよりも、どこからどこまでが条件分岐の範囲なのかが一目で分かりやすいですね。
繰り返し @foreach
PHPの foreach
ループは、@foreach
と @endforeach
で表現します。これもすでにお馴染みですね。
<ul>
@foreach ($seminarList as $seminar)
<li>{{ $seminar->title }}</li>
@endforeach
</ul>
Bladeのループには、$loop
という便利な変数が自動で用意されており、例えばループの最初かどうか ($loop->first
)、最後かどうか ($loop->last
) などを判定することもできます。
コメント
Bladeファイルの中に、開発者用のメモとしてコメントを残したいけれど、最終的なHTMLソースコードには表示させたくない、という場合があります。その場合は、{{-- --}}
でコメントを囲みます。
{{-- このコメントはブラウザのソース表示には現れません --}}
このセクションでは、Bladeの最も基本的な構文を学びました。{{ }}
による安全なデータ表示と、@
ディレクティブによるクリーンな制御構文。これらを使いこなすことが、読みやすく、メンテナンスしやすいビューを作成するための第一歩です。
さて、複数のビューファイルを作っていくと、ヘッダーやフッター、サイドバーといった、全てのページで共通する部分が出てきます。これらの共通パーツを、毎回全てのファイルにコピー&ペーストするのは非効率ですよね。
次のセクションでは、このような問題を解決する、Bladeの強力な「レイアウト機能」について学んでいきます。
6-2 レイアウト機能で共通パーツを使い回す
私たちのアプリケーションが成長し、ページ数が増えていくと、ある問題に直面します。「セミナー一覧ページ」「セミナー詳細ページ」「申し込みフォームページ」…これらのページは、それぞれ内容は違いますが、ページの上部にあるヘッダーや、下部にあるフッターといった部分は、全て共通のデザインを使いたいですよね。
これまでの知識だけだと、この共通部分のHTMLコードを、新しいビューファイルを作るたびに、毎回コピー&ペーストしなければなりません。もし、ヘッダーのナビゲーションに一つリンクを追加したくなったら、全てのファイルを一つずつ修正する必要があり、非常に手間がかかり、ミスの原因にもなります。
Bladeの強力な「レイアウト機能」は、この問題をエレガントに解決してくれます。
レイアウトの考え方:「額縁」と「絵」
Bladeのレイアウト機能を理解するには、「額縁」と「絵」の関係をイメージするのが一番です。
- レイアウトファイル(額縁)全てのページで共通となる、ヘッダー、フッター、サイドバーなどを含んだ、ページの骨格となるファイルです。これは、中身の絵を入れ替えるための、立派な「額縁」にあたります。
- 個別のビューファイル(絵)各ページ固有の内容だけが書かれたファイルです。セミナーの一覧や、特定のセミナーの詳細情報など、額縁の中に入れる「絵」にあたります。
この仕組みを使えば、私たちは額縁を一度だけ作り、あとは中に入れる絵だけを差し替えることで、統一感のあるウェブサイトを効率的に構築できるのです。
この仕組みは、主に3つのBladeディレクティブで実現されます。
@extends('レイアウト名')
: 「この絵は、あの額縁を使います」と宣言する。@yield('セクション名')
: 額縁側で、「ここに絵をはめ込むための場所(穴)を用意する」と定義する。@section('セクション名') ... @endsection
: 絵の側で、「この部分が、額縁のあの場所に入る絵です」と定義する。
ステップ1:マスターレイアウト(額縁)を作成する
まず、全てのページの土台となる「額縁」ファイルを作成しましょう。
resources/views
フォルダの中に、新しくlayouts
というフォルダを作成します。レイアウト関連のファイルは、ここにまとめておくと分かりやすいです。layouts
フォルダの中に、app.blade.php
という名前で新しいファイルを作成します。これが、アプリケーション全体のマスターレイアウトになります。app.blade.php
に、次のようにページの骨格となるHTMLを記述します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Seminar Application</title>
</head>
<body>
<header>
<h1>My Seminar App</h1>
</header>
<main>
@yield('content')
</main>
<footer>
<p>© 2025 Seminar App.</p>
</footer>
</body>
</html>
@yield('content')
という部分に注目してください。これが、額縁に空けられた「穴」です。私たちはこの穴に content
という名前をつけました。各ページの固有のコンテンツは、この場所に表示されることになります。
ステップ2:個別のビュー(絵)でレイアウトを継承する
次に、既存のセミナー一覧ページ (resources/views/seminars/index.blade.php
) を修正して、今作った額縁(レイアウト)を使うように変更します。
ファイルの中身は、驚くほどシンプルになります。共通部分である <html>
や <body>
タグなどは全て削除し、そのページ固有の部分だけを残します。
@extends('layouts.app')
@section('content')
<h2>開催予定セミナー</h2>
<ul>
@foreach ($seminarList as $seminar)
<li>{{ $seminar }}</li>
@endforeach
</ul>
@endsection
- @extends('layouts.app')ファイルの先頭で、「このビューは、layoutsフォルダのappビューを額縁として使います」と宣言しています。
- @section('content') ... @endsectionこの @section で囲まれた部分が、「額縁の content という名前の穴(@yield)にはめ込む、絵の中身です」と定義しています。
ステップ3:ブラウザで確認
両方のファイルを保存して、ブラウザで http://localhost
を更新してください。
どうでしょうか?セミナーの一覧リストが、app.blade.php
で定義したヘッダーとフッターに挟まれて、一つの完成したページとして表示されているはずです。Laravelが、裏側で「額縁」と「絵」を賢く合体させてくれたのです。
Bladeのレイアウト機能を使えば、サイト全体のデザイン変更が非常に簡単になります。例えば、フッターの年号を変えたい場合、修正するファイルは layouts/app.blade.php
のたった一つだけで、サイトの全てのページにその変更が反映されます。
これで、私たちはアプリケーションの「見た目」を本格的に構築するための、強力な武器を手に入れました。
次の章では、いよいよMVCの最後のピースである「M(モデル)」の登場です。データベースの設計図となる「マイグレーション」と、データベースとの対話役である「Eloquentモデル」について学んでいきましょう。
第7章:データベースとマイグレーション - データの「家」を建てる
第7章:データベースとマイグレーション - データの家を建てる
これまでの章で、私たちはアプリケーションの「見た目」と「ロジック」を扱う方法を学んできました。しかし、現在のセミナー情報はコントローラーのファイル内に直接書き込まれており(ハードコーディング)、これではアプリケーションを再起動すると消えてしまいますし、新しいセミナーを追加するにはコードを直接編集しなければなりません。
本物のアプリケーションは、情報を永続的に保存しておくための場所、つまり「データベース」が必要です。
この章では、MVCの最後のピースである「M(モデル)」を扱うための準備として、アプリケーションの「記憶」を担当するデータベースとの接続設定と、その構造を設計するための強力な機能「マイグレーション」について学んでいきます。
7-1 .envファイルとデータベース接続
アプリケーションがデータベースと対話するためには、まず「データベースはどこにあるのか?」「接続するための合言葉は何か?」といった情報を知る必要があります。
この、他人に知られてはいけない重要な接続情報を保管しておく場所が、プロジェクトのルートディレクトリにある .env
ファイルです。
.envファイルの役割とは?
.env
ファイルは、その名の通り「Environment(環境)」に関する変数を定義するためのファイルです。
ここで言う「環境」とは、アプリケーションが動いている場所のことを指します。例えば、
- あなたのパソコンの中(ローカル開発環境)
- インターネットに公開された本番のサーバー(本番環境)
などです。通常、ローカル開発環境で使うデータベースのパスワードと、本番環境で使うパスワードは、セキュリティのために異なるものを設定します。.env
ファイルは、このような環境ごとに異なる設定値を、アプリケーションのコアなコードを変更することなく、簡単に切り替えるための仕組みです。
例えるなら、アプリケーションという家の「秘密の配電盤」のようなものです。家の基本的な設計(プログラムコード)は変えずに、配電盤のスイッチ(.env
ファイルの設定値)を切り替えるだけで、電気の供給元(接続先のデータベースなど)を変更できるのです。
このファイルにはパスワードなどの機密情報が含まれるため、Gitなどのバージョン管理システムに絶対に含めてはいけません。(Laravelの初期設定で、.env
ファイルは自動的にGitの管理対象から除外されるようになっています)
Laravel Sailとデータベース接続
「データベースに接続するための設定が必要」と聞くと、少し身構えてしまうかもしれません。しかし、安心してください。私たちが第2章で利用したLaravel Sailが、すでにほとんど全ての作業を完了してくれています。
seminar-app
プロジェクトを作成したあの瞬間に、SailはLaravelアプリケーション用のDockerコンテナと一緒に、データベース(MySQL)専用のコンテナも用意してくれました。そして、アプリケーションがそのデータベースコンテナに接続するために必要な情報を、自動的に.env
ファイルに書き込んでくれているのです。
VS Codeで、プロジェクトのルートにある.env
ファイルを開き、DB_
で始まる設定項目を探してみてください。
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=seminar_app
DB_USERNAME=sail
DB_PASSWORD=password
これが、Sailが用意してくれたデータベースへの「接続情報」です。
DB_CONNECTION
: どの種類のデータベースを使うか。mysql
が指定されています。DB_HOST
: データベースの住所(ホスト名)。mysql
と書かれていますが、これはSailが用意したMySQLコンテナのサービス名を指しています。私たちのアプリコンテナは、この名前でデータベースコンテナの場所を見つけることができます。DB_PORT
: データベースのポート番号(部屋番号のようなもの)。3306
はMySQLの標準的なポートです。DB_DATABASE
: データベース名。プロジェクト作成時に、自動的にフォルダ名と同じseminar_app
という名前のデータベースが作られています。DB_USERNAME
,DB_PASSWORD
: データベースにログインするためのユーザー名とパスワードです。Sailは、ローカル開発用にsail
とpassword
という、分かりやすい初期設定を用意してくれています。
接続の確認方法
では、この設定で本当にデータベースに接続できているのでしょうか?
実は、私たちはすでにその確認を済ませています。第2章で、開発環境を構築した際に実行した、次のコマンドを覚えていますか?
./vendor/bin/sail artisan migrate
このmigrate
コマンドは、データベースの構造を作成するための命令です。このコマンドがエラーなく成功した、という事実こそが、私たちのLaravelアプリケーションが.env
ファイルの設定値を読み取り、データベースコンテナへ正しく接続できたことの、何よりの証明なのです。
このセクションでは、アプリケーションの機密情報を管理する.env
ファイルの役割と、Sailがいかにデータベース接続を簡単にしてくれているかを学びました。
これで、アプリケーションと、その記憶装置であるデータベースとを繋ぐ道が確保できました。しかし、今のデータベースは、まだ中身が空っぽのただの倉庫です。
次のセクションでは、この倉庫の中に、セミナー情報を整理して保管するための棚や仕切り(テーブルやカラム)を設計するための、Laravelの強力な機能「マイグレーション」の使い方を学んでいきます。
7-2 マイグレーション:コードでデータベースの設計図を管理する
データベースへの接続が確認できましたが、今のデータベースは、まだ中身が空っぽのただの倉庫です。データを格納するためには、まず倉庫の中に「どのような情報を」「どのような形式で」保管するのか、棚や仕切りを作ってあげる必要があります。このデータベースにおける棚や仕切りが「テーブル」や「カラム」です。
では、どうやってテーブルを作成するのでしょうか?
昔ながらの方法では、データベース管理ツールを使って、マウスでポチポチとクリックしながらテーブルやカラムを手作業で作っていました。しかし、この方法には大きな問題点があります。
- チーム開発が難しい:もし、あなたがテーブルに新しいカラムを追加したら、その変更をチームメンバー全員に口頭やチャットで伝え、全員に同じ手作業をしてもらわなければなりません。これは非常に面倒で、ミスが起こりやすいです。
- 歴史が残らない:データベースがどのような変更を経て現在の形になったのか、その歴史を後から追うことができません。
- やり直しが難しい:一度作った構造を、簡単にもとに戻すことができません。
Laravelの「マイグレーション (Migration)」機能は、これらの問題を全て解決してくれる、画期的な仕組みです。
マイグレーションとは?データベースの「設計図」
マイグレーションとは、データベースの構造(テーブルの作成や変更など)を、PHPのコードとして記録・管理する仕組みのことです。
これを、レゴブロックの組み立て説明書に例えてみましょう。
マイグレーションファイルは、その説明書の1ページにあたります。「ステップ1:青いブロックを2つ使って、土台を作ります」といった具体的な指示が、コードとして書かれています。
この説明書のページ(マイグレーションファイル)を順番に実行していけば、誰が作っても、いつでも、寸分違わず同じ形のレゴ作品(データベース構造)を完成させることができます。もし、後から「窓を一つ追加したい」と思ったら、「ステップ25:ここに窓を取り付けます」という新しいページを説明書に追加すれば良いのです。
この「コードでデータベースを管理する」という考え方により、データベースの変更履歴をGitで管理でき、チームでの共同作業が劇的にスムーズになります。
ステップ1:マイグレーションファイルを作成する
それでは、セミナー情報を格納するための seminars
テーブルの設計図(マイグレーションファイル)を作成しましょう。artisan
コマンドを使います。
./vendor/bin/sail artisan make:migration create_seminars_table
make:migration
:新しいマイグレーションファイルを作成する、という命令です。create_seminars_table
:マイグレーションファイルの名前です。Laravelは賢いので、create_テーブル名_table
という命名規則に従うと、自動的にそのテーブルを作成するための定型コードを生成してくれます。
コマンドを実行すると、database/migrations
フォルダの中に、2025_08_10_000000_create_seminars_table.php
のような、タイムスタンプ付きのファイルが作成されます。このタイムスタンプの順番で、マイグレーションは実行されます。
ステップ2:テーブルの構造を定義する
作成されたマイグレーションファイルをVS Codeで開いてください。up()
と down()
という2つのメソッドがあるのが分かります。
up()
メソッド:マイグレーションを実行 (migrate
) したときに呼ばれます。テーブルの作成など、変更を「適用」する処理を書きます。down()
メソッド:マイグレーションを取り消し (migrate:rollback
) したときに呼ばれます。up()
で行った変更を元に戻す処理を書きます。
今回は、up()
メソッドの中に、seminars
テーブルに必要なカラム(仕切り)を定義していきます。
// ...
public function up()
{
Schema::create('seminars', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->integer('capacity');
$table->timestamps();
});
}
// ...
Schema::create('seminars', ...)
:「seminars
という名前のテーブルを新しく作ります」という宣言です。$table->id();
:全てのデータを見分けるための、重複しない連番のid
カラム(主キー)を作成します。$table->string('title');
:セミナーのタイトルのような、比較的短い文字列を格納するtitle
カラムを作成します。$table->text('description');
:セミナーの詳細説明のような、長い文章を格納するdescription
カラムを作成します。$table->integer('capacity');
:定員のような、整数を格納するcapacity
カラムを作成します。$table->timestamps();
:これは便利なヘルパーで、データの作成日時を記録するcreated_at
と、更新日時を記録するupdated_at
という2つのカラムを自動で作成してくれます。
ステップ3:マイグレーションを実行する
設計図が完成しました。この設計図を元に、データベースに実際のテーブルを作成しましょう。実行するコマンドは、もうお馴染みですね。
./vendor/bin/sail artisan migrate
このコマンドを実行すると、Laravelはまだ実行されていない新しいマイグレーションファイルを探し出し、その up()
メソッドを実行します。これにより、私たちのデータベースの中に、定義した通りのカラムを持った seminars
テーブルが物理的に作成されました。
これで、データを保管するための「家の骨格」が、ついに完成しました。マイグレーションを使えば、データベースの構造をコードで明確に管理できるため、いつでも安心して開発を進めることができます。
しかし、まだこの家(テーブル)にデータを入れたり、取り出したりする方法がありません。そのためには、データベースとの対話を専門に行う、MVCの「M」にあたるModel
(モデル)が必要です。
次の章では、この新しく作ったテーブルを操作するためのSeminar
モデルを作成し、いよいよデータの読み書きを行っていきます。
第8章:Eloquent ORM - データベースと流暢に会話する
第8章:Eloquent ORM - データベースと会話しよう
これまでの章で、私たちはアプリケーションの「記憶倉庫」であるデータベースを準備し、その中に seminars
というテーブル(棚)を「マイグレーション」によって建設しました。
しかし、今のところ、その棚にデータ(情報)を入れたり、中に入っているデータを取り出したりする手段がありません。PHPのコードからデータベースを直接操作するには、通常「SQL」という専門の言語を書く必要がありますが、これは学習コストが高く、コードが複雑になりがちです。
そこで登場するのが、Laravelの最も強力で、最も愛されている機能の一つ、「Eloquent ORM(エロクエント・オーアールエム)」です。Eloquentは、難しいSQL言語を意識することなく、まるでPHPのオブジェクトを扱うような直感的な感覚で、データベースと対話させてくれる魔法のツールです。
この章では、Eloquentの主役である「モデル」を作成し、ついにアプリケーションとデータベースを繋ぎます。
8-1 モデルとは?データベースのテーブルの分身
Eloquent ORMの中心的な役割を担うのが、「モデル (Model)」です。
モデルとは、データベース上の一つのテーブルを表す、PHPのクラスのことです。
これは、図書館の特定の棚に、専属の「司書」を一人割り当てるようなものです。
- データベース:巨大な図書館
seminars
テーブル:セミナー関連の書籍だけを集めた「セミナー専門書架」Seminar
モデル:「セミナー専門書架」のことなら何でも知っている、専属の「司書さん」
新しいセミナーの情報を追加したいとき(本を棚にしまう)、私たちは本棚に直接触る必要はありません。司書さん(モデル)に「この本をしまっておいて」と渡すだけです。特定のセミナー情報を探したいときも、司書さんに「こういう本を探している」と伝えれば、すぐに見つけてきてくれます。
この司書さん(モデル)を介することで、私たちは書架の物理的な構造(SQL)を意識することなく、データの出し入れができるのです。
Laravelの命名規則という魔法
Eloquentが魔法と呼ばれる理由の一つに、その賢い「命名規則」があります。
- モデルの名前を、テーブル名の単数形・大文字始まりのキャメルケース(例:
Seminar
)にする - テーブルの名前を、モデル名の複数形・小文字のスネークケース(例:
seminars
)にする
このルールに従うだけで、Laravelは自動的に「Seminar
モデルは、seminars
テーブルに対応しているんだな」と理解してくれます。この「設定より規約」という考え方のおかげで、私たちはモデルとテーブルを繋ぐためのコードを一行も書く必要がないのです。
ステップ1:モデルを作成する
それでは、私たちの seminars
テーブルに対応する、Seminar
モデルを作成しましょう。もちろん、artisan
コマンドを使います。
./vendor/bin/sail artisan make:model Seminar
make:model という命令で、Seminar という名前のモデルを新しく作ります。
コマンドが成功すると、app/Models フォルダの中に Seminar.php というファイルが作成されます。
ステップ2:モデルファイルの中身を確認する
作成された app/Models/Seminar.php
をVS Codeで開いてみてください。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Seminar extends Model
{
use HasFactory;
}
驚くほど、中身がシンプルだと思いませんか?私たちがマイグレーションで定義した title
や description
といったカラムの情報は、どこにも書かれていません。
これもEloquentの魔法です。Seminar
クラスは、Laravelの基本的な Model
クラスを継承 (extends
) しています。この親クラスが非常に優秀で、対応する seminars
テーブルの構造を自動的に解析し、どんなカラムがあるのかを理解してくれるのです。
ステップ3:Tinkerでモデルの力を体験する
この新しく生まれた司書さん(モデル)の力を、早速試してみましょう。UIをまだ作っていないので、今回はLaravelに付属する「Tinker」という対話型のコンソールを使います。Tinkerを使うと、コマンドライン上で直接Laravelの機能を試すことができます。
ターミナルで、次のコマンドを実行してTinkerを起動してください。
./vendor/bin/sail artisan tinker
>>>
というプロンプトが表示されたら、Tinkerの世界に入った合図です。ここにPHPコードを直接打ち込んで、モデルを操作してみましょう。
データの作成
seminars
テーブルに、最初のデータを登録します。
$seminar = new App\Models\Seminar();
$seminar->title = 'My First Seminar';
$seminar->description = 'This is a test seminar.';
$seminar->capacity = 50;
$seminar->save();
new App\Models\Seminar()
で、新しいセミナーのオブジェクト(空のレコード)を作成します。->title
のように、プロパティに値を設定していきます。- 最後に
->save()
メソッドを呼び出すと、このデータがseminars
テーブルに新しい行として保存されます。
データの取得
次に、今保存したデータを取得してみましょう。
App\Models\Seminar::all();
all()
メソッドは、seminars
テーブルにある全てのレコードを取得してくれます。
App\Models\Seminar::find(1);
find(1)
メソッドは、id
が1のレコードを一件だけ取得してくれます。
このセクションでは、Eloquentモデルという、データベースと対話するための強力なパートナーを作成しました。SQLを一行も書くことなく、PHPのオブジェクトを操作するだけで、データベースの読み書きができてしまう。これが、Eloquent ORMの基本的な力です。
Tinkerを使ってデータベースにデータを入れることには成功しました。次のステップは、このモデルをコントローラーの中で使い、データベースから取得した本物のデータを、ビューに渡して表示することです。いよいよ、アプリケーションのデータが、完全に動的になります。
Eloquentを使うと、データベースの基本的な操作であるCRUD(クラッド)—Create (作成)、Read (読み取り)、Update (更新)、Delete (削除)—を、SQLを一切書かずに、簡単なPHPのメソッドで実行できます。
このセクションでは、前の章で作成した Seminar
モデルをコントローラー内で実際に使い、これら4つの操作をマスターする方法を学びます。
CRUDとは? 🗃️
CRUDは、ほとんどのアプリケーションにおけるデータ操作の基本となる、4つの単語の頭文字を取ったものです。
- Create: 新しいデータを作成する
- Read: 既存のデータを読み取る
- Update: 既存のデータを更新する
- Delete: 既存のデータを削除する
この4つの操作を自在に操ることが、データ駆動型アプリケーション開発の鍵となります。
R: データの読み取り (Read)
まずは、アプリケーションの最も一般的な機能であるデータの読み取りです。前の章で作成したセミナー一覧ページに、データベースから取得した本物のデータを表示させましょう。
ステップ1: Controllerの修正
SeminarController
の index
メソッドを修正し、ハードコードされた配列の代わりに、Seminar
モデルを使ってデータベースから全てのセミナー情報を取得します。
app/Http/Controllers/SeminarController.php
を開きます。- ファイルの先頭で
Seminar
モデルをインポートします。 index
メソッドを以下のように書き換えます。
<?php
namespace App\Http\Controllers;
use App\Models\Seminar;
use Illuminate\Http\Request;
class SeminarController extends Controller
{
public function index()
{
$seminars = Seminar::all();
return view('seminars.index', ['seminarList' => $seminars]);
}
// ... showメソッドなどは省略 ...
}
Seminar::all()
がEloquentのメソッドです。これはseminars
テーブルの全ての行を取得し、Seminar
オブジェクトの集まり(コレクション)として返してくれます。
ステップ2: Viewの修正
次に、ビューがオブジェクトのプロパティを表示できるように seminars/index.blade.php
を修正します。
<ul>
@foreach ($seminarList as $seminar)
<li>{{ $seminar->title }}</li>
@endforeach
</ul>
$seminarList
の中身が、単なる文字列の配列から Seminar
オブジェクトのコレクションに変わりました。そのため、->
(アロー演算子)を使って、各セミナーオブジェクトの title
プロパティにアクセスします。
ステップ3: 動作確認
ブラウザで http://localhost
を更新してください。前の章でTinkerを使って登録した「My First Seminar」がリストに表示されれば成功です!
C: データの新規作成 (Create)
データを新しくデータベースに保存するには、主に2つの方法があります。
方法1: new
と save
前の章でTinkerを使って試した方法です。まず新しいモデルオブジェクトを作成し、各プロパティに値を設定してから save
メソッドを呼び出します。
$seminar = new Seminar();
$seminar->title = 'Introduction to PHP';
$seminar->description = 'A great course for beginners.';
$seminar->capacity = 20;
$seminar->save();
方法2: create
メソッド (Mass Assignment)
より簡潔に、一行でレコードを作成する方法です。
Seminar::create([
'title' => 'Introduction to Vue.js',
'description' => 'Learn the basics of Vue.',
'capacity' => 25
]);
⚠️ 重要:マスアサインメント保護
この create メソッドをそのまま実行すると、デフォルトではエラーになります。これは、悪意のあるユーザーが意図しないデータを送りつけてくるのを防ぐための、Laravelのマスアサインメント保護というセキュリティ機能です。
この機能を有効にするには、「この方法で一括登録しても安全なカラム」をモデルに明示的に指定する必要があります。app/Models/Seminar.php
を開き、$fillable
プロパティを追加してください。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Seminar extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description',
'capacity',
];
}
これで、title
, description
, capacity
の3つのカラムは create
メソッドで安全に一括登録できるようになります。
U: データの更新 (Update)
既存のデータを更新する手順は、「探す → 変更する → 保存する」の3ステップです。
// 1. IDが1のセミナーを探す
$seminar = Seminar::find(1);
// 2. プロパティの値を変更する
$seminar->title = 'My First Laravel Seminar (Updated)';
// 3. 変更をデータベースに保存する
$seminar->save();
save
メソッドは非常に賢く、オブジェクトがデータベースに存在しない場合は INSERT
(新規作成)、すでに存在する場合は UPDATE
(更新)を自動的に実行してくれます。
D: データの削除 (Delete)
データの削除は非常にシンプルです。「探す → 削除する」の2ステップです。
// 1. IDが2のセミナーを探す
$seminar = Seminar::find(2);
// 2. レコードを削除する
$seminar->delete();
IDを指定して直接削除する destroy メソッドも便利です。
Seminar::destroy(2);
これで、Eloquentを使った基本的なCRUD操作を全て学びました。これらのメソッドを組み合わせることで、アプリケーションのデータ管理機能のほとんどを実装できます。次の章では、これらの知識を使い、実際に管理者向けのセミナー登録・編集画面を作成していきます。
Tinkerは、Laravel公式の対話型コマンドラインインターフェース(CLI)で、REPL(Read-Eval-Print Loop)とも呼ばれます。ターミナルから直接PHPコードを実行し、モデルやサービスなど、アプリケーション全体の機能と対話することができます。👨💻
Tinkerは、アプリケーションの実験台やシェフの味見スプーンのようなものです。UIをわざわざ作成する前に、コードの断片を試したり、データベースのクエリを実験したりして、全てが期待通りに動くか素早く確認できます。
Tinkerの起動と終了
Laravel Sail環境でTinkerを起動するには、プロジェクトのルートディレクトリで次のコマンドを実行します。
./vendor/bin/sail artisan tinker
コマンドを実行すると、ターミナルのプロンプトが >>>
に変わります。これが、あなたのLaravelアプリケーションが完全に読み込まれた、Tinkerセッションの内部にいる合図です。
Tinkerを終了するには、exit
と入力してEnterキーを押すか、キーボードショートカットの Ctrl+C
を使用します。
なぜTinkerが便利なのか?
Tinkerの最大の利点は、迅速な実験ができることです。🧪
UIやルートを作成しなくても、以下のようなタスクを瞬時に実行できます。
- Eloquentクエリのテスト:
Seminar::where('capacity', '>', 20)->get()
のようなクエリが、期待通りのデータを返すかすぐに試せます。 - データの操作: テスト用のレコードを手動で作成したり、不要なデータを削除したりできます。
- 一度きりのタスク実行: 特定のジョブやイベントをテスト目的で一度だけ実行したい場合に便利です。
- オブジェクトの調査: モデルオブジェクトを取得し、どのようなデータが含まれているか、どのようなメソッドが使えるかを確認できます。
Tinker実践:Eloquentを試してみよう
実際にTinkerを使って、Eloquentの様々なメソッドを試してみましょう。
1. データの作成 (Creating Data)
create
メソッドを使って新しいセミナーを登録します。最初に use
文でモデルをインポートしておくと、毎回フルネームでクラスを指定する必要がなくなり便利です。
>>> use App\Models\Seminar;
>>> Seminar::create(['title' => 'Tinker Test Course', 'description' => 'A course made via Tinker', 'capacity' => 10]);
実行すると、新しく作成された Seminar
オブジェクトが返されます。
2. 条件を使ったデータの検索 (Querying Data with Conditions)
where
メソッドを使って、特定の条件に一致するレコードを検索します。
例1:定員が20名以上のセミナーを全て取得する
>>> Seminar::where('capacity', '>=', 20)->get();
get()
メソッドは、条件に一致した全てのレコードをコレクションとして返します。
例2:特定のタイトルのセミナーを1件だけ取得する
>>> Seminar::where('title', 'My First Seminar')->first();
first()
メソッドは、条件に一致した最初の1件を単一のオブジェクトとして返します。
3. データの更新 (Updating Data)
まず find
でレコードを取得し、プロパティを変更して save
します。
>>> $seminar = Seminar::find(1);
>>> $seminar->capacity = 100;
>>> $seminar->save();
save()
を実行すると、true
が返され、データベースの値が更新されます。
4. 結果の確認 (Verifying the Result)
更新が正しく行われたか、もう一度 find
で確認してみましょう。
>>> Seminar::find(1);
ターミナルに表示される Seminar
オブジェクトの capacity
が 100
に変わっているはずです。
Tinkerは、Laravel開発者にとって不可欠なツールです。Eloquentの動作に迷ったとき、新しいロジックを試したいとき、まずはTinkerで気軽に「味見」をすることで、開発効率は飛躍的に向上します。
第3部:実践!セミナー受付システム開発
いよいよ本番です。第2部で学んだ知識を総動員して、一つのアプリケーションをゼロから作り上げます。
第9章:プロジェクトの設計図を描こう
これまでの章で学んだ知識を総動員し、実践的な「セミナー受付システム」を構築します。このシステムは、管理者がセミナーを管理し、参加者がセミナーに申し込むための、2つの側面を持ちます。
本格的な開発に入る前に、まずは私たちが作るシステムの全体像、つまり機能の一覧を明確にしましょう。
参加者向け機能 👨🎓
一般のウェブサイト訪問者が利用できる機能です。
- セミナー一覧表示: 現在開催予定のセミナーが一覧で表示されます。
- セミナー詳細表示: 一覧から特定のセミナーを選ぶと、その詳細情報(説明、日時、定員など)を確認できます。
- セミナー申し込み: 詳細ページから、名前やメールアドレスなどを入力してセミナーに申し込むことができます。
- 申し込み完了通知: 申し込みが完了すると、確認メールが自動で送信されます。
管理者向け機能 👨💼
特定のユーザー(管理者)のみが、ログインして利用できる機能です。
- ログイン認証: 安全なログインページから、IDとパスワードを使って管理画面にログインします。
- セミナー管理ダッシュボード: 登録されているセミナーの一覧を管理画面で確認できます。
- セミナーの新規登録 (Create): 新しいセミナーのタイトル、説明、日時などをフォームに入力して登録します。これはデータベース操作の基本であるCRUDの C (作成) にあたります。
- セミナーの編集 (Update): 既存のセミナー情報をフォームで編集し、更新します。CRUDの U (更新) です。
- セミナーの削除 (Delete): 登録済みのセミナーを削除します。CRUDの D (削除) です。
- 申込者一覧の確認: 各セミナーに誰が申し込んでいるのか、一覧で確認できます。
システムのゴール 🎯
このシステムは、シンプルながらも実際のWebアプリケーション開発に不可欠な、CRUD操作、ユーザー認証、データベースのリレーション(セミナーと申込者の関連付け)、そしてメール送信といった、Laravelの重要な機能を網羅しています。
このプロジェクトを完成させることで、皆さんは実践的な開発の全体的な流れを体験し、自信を持って次のステップに進むことができるようになります。
前のセクションで定義した機能一覧を実現するために、どのようなデータを保存する必要があるかを考え、それをデータベースのテーブルとカラムの設計に落とし込みます。
これは、家を建てる前に、どの部屋に何を置くかを決める間取り図を作成するような、非常に重要な工程です。
必要なテーブルを洗い出す
まず、機能一覧から、アプリケーションが必要とする主要な「モノ」を洗い出します。
- セミナー (Seminar): アプリケーションの核となる情報です。タイトルや説明などを保存する必要があります。 ->
seminars
テーブル - 利用者 (User): セミナーに申し込む「参加者」や、システムを管理する「管理者」の情報です。 ->
users
テーブル - 申し込み (Application): 「どの利用者」が「どのセミナーに」申し込んだか、という関係性を記録する必要があります。 ->
applications
テーブル
この3つのテーブルを軸に、それぞれのテーブルが持つべき具体的なカラム(情報)を設計していきましょう。
1. seminars
テーブルの設計 🗓️
セミナー自体の情報を格納するためのテーブルです。
カラム名 | データ型 | 説明 |
id | 整数 (ID) | データを一意に識別するための番号 (主キー 🔑) |
title | 文字列 (string) | セミナーのタイトル |
description | テキスト (text) | セミナーの詳細な説明文 (長文) |
start_time | 日時 (datetime) | セミナーの開始日時 |
end_time | 日時 (datetime) | セミナーの終了日時 |
capacity | 整数 (integer) | セミナーの定員 |
created_at | タイムスタンプ | レコード作成日時 (Laravelが自動管理) |
updated_at | タイムスタンプ | レコード更新日時 (Laravelが自動管理) |
2. users
テーブルの設計 👤
システムの利用者(参加者および管理者)の情報を格納するためのテーブルです。Laravelの標準的なユーザー機能も活用するため、それに準じた設計にします。
カラム名 | データ型 | 説明 |
id | 整数 (ID) | ユーザーを一位に識別する番号 (主キー 🔑) |
name | 文字列 (string) | ユーザー名 |
email | 文字列 (string) | メールアドレス (ログインIDとしても利用、重複不可) |
password | 文字列 (string) | ログイン用パスワード (ハッシュ化して保存) |
is_admin | 真偽値 (boolean) | 管理者かどうかを判別するフラグ (true なら管理者) |
created_at | タイムスタンプ | レコード作成日時 |
updated_at | タイムスタンプ | レコード更新日時 |
3. applications
テーブルの設計 🔗
「誰が」「どのセミナーに」申し込んだのか、という関係を記録するための中間テーブルです。
カラム名 | データ型 | 説明 |
id | 整数 (ID) | 申し込み情報を一位に識別する番号 (主キー 🔑) |
user_id | 整数 | 申し込んだユーザーのID (外部キー) |
seminar_id | 整数 | 申し込まれたセミナーのID (外部キー) |
created_at | タイムスタンプ | 申し込み日時 |
updated_at | タイムスタンプ | 申し込み情報更新日時 |
外部キー (Foreign Key) とは、他のテーブルの id
と関連付けるためのカラムです。applications
テーブルの user_id
は users
テーブルの id
に、seminar_id
は seminars
テーブルの id
に、それぞれ対応します。これにより、データ同士の関連性を担保します。
この設計図が完成した今、次のステップはこれを実際のデータベースに反映させることです。次のセクションでは、このテーブル設計を元に、Laravelのマイグレーションファイルを実際に作成していきます。
第10章:ログイン機能を一瞬で実装する
Laravel Breezeは、Laravel公式が提供する、シンプルで美しい認証機能をアプリケーションに高速で追加するためのスターターキットです。🚀
ログイン、新規登録、パスワードリセットといった、多くのWebアプリケーションで必要となる認証周りの機能を、ゼロから自分で構築するのは非常に複雑で時間がかかります。Breezeは、これらの機能一式を、いくつかの簡単なコマンドを実行するだけで、自動的にあなたのアプリケーションに組み込んでくれます。
Breezeが提供してくれるもの
Breezeをインストールすると、以下の機能がすぐに使えるようになります。
- ログイン機能 🔑: メールアドレスとパスワードでユーザーを認証するためのフォームとロジック。
- 新規登録機能: 新しいユーザーがアカウントを作成するための登録フォーム。
- パスワードリセット機能: パスワードを忘れたユーザーが、メール経由でパスワードを再設定するための一連のフロー。
- メール認証: ユーザーが登録したメールアドレスが本人のものであることを確認する機能(オプション)。
- ログアウト機能: ユーザーが安全にセッションを終了するための機能。
- プロファイルページ: ログイン中のユーザーが、自身の名前やパスワードを更新できる簡単なページ。
なぜBreezeを使うのか?
Breezeを使う最大の理由は、開発の速度と安全性です。
これは、家に高品質な既製品のセキュリティシステムを導入するのに似ています。自分で鍵や監視カメラの仕組みをゼロから設計することも可能ですが、専門家が作ったシステムを導入する方が、はるかに早く、そして安全ですよね。
BreezeはLaravelのコアチームによって開発されており、パスワードのハッシュ化などのセキュリティ対策もベストプラクティスに沿って実装されています。また、Breezeが生成するコントローラーやビューのファイルは全てあなたのプロジェクト内に配置されるため、後から自由にカスタマイズすることも非常に簡単です。
Breezeのインストール手順
それでは、実際にBreezeを導入してみましょう。ターミナルで、プロジェクトのルートディレクトリにいることを確認し、以下のコマンドを順番に実行してください。
ステップ1: Composerでパッケージをインストール
まず、PHPのパッケージ管理ツールであるComposerを使って、Breezeのパッケージをプロジェクトに追加します。
./vendor/bin/sail composer require laravel/breeze --dev
ステップ2: Breezeをアプリケーションにインストール
次に、artisan
コマンドで、認証機能の土台となるファイル群を生成します。
./vendor/bin/sail artisan breeze:install
このコマンドを実行すると、「どのスタックを使用しますか?」と質問されます。私たちはこれまでBladeを使ってきたので、Blade
を選択してください(通常は 0
を入力してEnter)。その後、いくつかの質問をされますが、基本的にはEnterキーを押してデフォルトの選択肢のまま進めて問題ありません。
ステップ3: 必要なパッケージをインストールし、ビルドする
Breezeが生成する画面は、Tailwind CSSというCSSフレームワークでデザインされています。その関連パッケージをインストールし、CSSファイルをビルド(生成)するためのコマンドです。
./vendor/bin/sail npm install
./vendor/bin/sail npm run build
ステップ4: データベースをマイグレートする
Breezeは、パスワードリセット情報を保存するためのテーブルなどを追加します。そのためのマイグレーションファイルを実行し、データベースの構造を更新します。
./vendor/bin/sail artisan migrate
動作確認
全てのステップが完了したら、ブラウザで http://localhost
にアクセスしてみてください。
画面の右上に「Log in」と「Register」のリンクが表示されているはずです。
「Register」をクリックして新しいアカウントを作成し、その後ログインしてみてください。/dashboard
というURLのダッシュボード画面にリダイレクトされれば、インストールは完璧に成功しています。
ほんの数個のコマンドで、本格的な認証システムが実装できました。これがLaravelエコシステムの持つ生産性の高さです。🛡️
これで管理者用のログイン機能が手に入りました。次のステップは、この認証システムを利用して「ログインしている管理者だけが見られるページ」を作成し、セミナー管理機能の構築へと進んでいきます。
Laravelはミドルウェア (Middleware) という仕組みを使って、特定のルートを保護します。ミドルウェアは、アプリケーションへのリクエストが目的の処理(コントローラー)に到達する前に通過する「検問所」や「用心棒」のようなものです。🛡️
VIPラウンジ(保護されたページ)に入る前に、用心棒(ミドルウェア)があなたのチケット(ログイン状態)をチェックします。有効なチケットを持っていれば中に入れますが、持っていなければ入り口(ログインページ)に戻される、というイメージです。
前の章でインストールしたLaravel Breezeは、ユーザーがログインしているかをチェックする auth
という名前のミドルウェアを、すでに用意してくれています。このセクションでは、この仕組みを利用して管理者専用のエリアを作成します。
ステップ1: ダッシュボードを保護する
Breezeをインストールすると、ログイン後に /dashboard
というページにリダイレクトされます。このルートは、Breezeによってすでに auth
ミドルウェアで保護されています。
routes/web.php
ファイルを見ると、以下のような記述があるはずです。
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
->middleware(['auth', 'verified'])
の部分が、このルートに「検問所」を設置している記述です。auth
ミドルウェアが、ログインしているかどうかをチェックします。
実験してみましょう: アプリケーションからログアウトした状態で、ブラウザのアドレスバーに直接 http://localhost/dashboard
と入力してみてください。ログインページに自動的にリダイレクトされるはずです。これが auth
ミドルウェアの働きです。
ステップ2: 管理者専用のルートグループを作成する
これから私たちは、セミナーの「一覧」「作成」「編集」といった、複数の管理者向けページを作成していきます。これらのページ一つ一つに ->middleware('auth')
を追加するのは非効率です。
そこで、ルートグループという機能を使います。これは、複数のルートをまとめて、グループ全体にミドルウェアを適用するためのものです。
routes/web.php
に、管理者向けのルートグループを追記しましょう。
use App\Http\Controllers\SeminarController;
// ... 他のuse文
Route::middleware('auth')->group(function () {
// このグループ内のルートは全て、ログインしていなければアクセスできない
Route::get('/admin/seminars', [SeminarController::class, 'index'])->name('admin.seminars.index');
// 今後、作成・編集・削除のルートもここに追加していく
});
require __DIR__.'/auth.php';
Route::middleware('auth')->group(...)
で囲んだ内側のルートには、全て自動で auth
ミドルウェアが適用されます。また、管理者向けの機能であることが分かりやすいように、URLに /admin/
という接頭辞をつけ、ルート名にも admin.
という接頭辞をつけておくのが良い習慣です。
ステップ3: さらなる保護:管理者かどうかをチェックする
今のままでは、一般ユーザーとしてログインした人も /admin/seminars
にアクセスできてしまいます。これを防ぐために、「ログインしている」かつ「管理者である」という二重のチェックが必要です。
より本格的な方法はカスタムミドルウェアを作成することですが、今回はコントローラー内で簡単にチェックする方法を学びましょう。
SeminarController
の index
メソッドの先頭に、ユーザーが管理者かどうかを判定するロジックを追加します。
// app/Http/Controllers/SeminarController.php
public function index()
{
// ログイン中のユーザーが管理者でなければ
if (!auth()->user()->is_admin) {
// トップページにリダイレクトさせる
return redirect('/');
}
// 管理者であれば、以下の処理を続行
$seminars = \App\Models\Seminar::all();
return view('seminars.index', ['seminarList' => $seminars]);
}
auth()->user()
は、現在ログインしているユーザーのオブジェクトを取得する便利なヘルパー関数です。私たちは以前 users
テーブルの設計で is_admin
というカラムを用意しました。この値が true
でなければ、トップページに強制的に戻す、という処理です。
これで、管理者だけがアクセスできる特別なエリアの基礎が完成しました。🔒
- ミドルウェアが「用心棒」として機能する。
auth
ミドルウェアがログイン状態をチェックする。- ルートグループで効率的にルートを保護できる。
- コントローラー内のロジックで、より詳細な権限チェックができる。
次のステップでは、この保護されたエリアの中に、実際にセミナーを管理するための画面(ダッシュボードや新規登録フォーム)を作成していきます。
第11章:管理者向けセミナー管理機能(CRUD)
管理者向けのセミナー管理機能、その最初のステップとして、データベースに登録されている全てのセミナーを一覧で表示する管理ダッシュボード画面を作成します。これは、CRUD操作の R (Read) にあたります。🖥️
ステップ1: 管理者用のレイアウトを作成する
一般ユーザー向けの画面と管理者向けの画面では、ナビゲーションやデザインが異なることが多いため、管理者専用のレイアウトファイルを用意するのが良い習慣です。
resources/views/layouts/app.blade.php
をコピーし、同じlayouts
フォルダ内にadmin.blade.php
という名前で複製します。- 新しい
admin.blade.php
を開き、区別がつくように少しだけ変更します。例えば、ヘッダー部分を以下のように書き換えます。
<header>
<h1>セミナー管理画面</h1>
<nav>
<a href="{{ route('admin.seminars.index') }}">セミナー一覧</a>
</nav>
</header>
ステップ2: 管理者用の一覧ビューを作成する
次に、セミナーの一覧をテーブル形式で表示するための、管理者専用のビューファイルを作成します。
resources/views
の中に、admin
という新しいフォルダを作成します。- さらに、その
admin
フォルダの中にseminars
フォルダを作成します。 - 最終的に
resources/views/admin/seminars/
というパスに、index.blade.php
という新しいファイルを作成し、以下の内容を記述します。
@extends('layouts.admin')
@section('content')
<h2>セミナー一覧</h2>
{{-- 新規作成ボタンは後でここに追加します --}}
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>タイトル</th>
<th>開催日時</th>
<th>定員</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach ($seminars as $seminar)
<tr>
<td>{{ $seminar->id }}</td>
<td>{{ $seminar->title }}</td>
<td>{{ $seminar->start_time }}</td>
<td>{{ $seminar->capacity }}</td>
<td>
{{-- 編集・削除ボタンは後でここに追加します --}}
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection
このビューは、先ほど作成した admin
レイアウトを継承し、渡されたセミナーのリストをテーブルで表示します。操作欄は、後のセクションで編集・削除ボタンを追加するために空けておきます。
ステップ3: コントローラーを修正して新しいビューを返す
SeminarController
の index
メソッドが、今作成した管理者用のビューを返すように修正します。
app/Http/Controllers/SeminarController.php
を開き、index
メソッドを以下のように変更してください。
public function index()
{
if (!auth()->user()->is_admin) {
return redirect('/');
}
$seminars = \App\Models\Seminar::all();
return view('admin.seminars.index', ['seminars' => $seminars]);
}
view()
関数が指し示す先を、seminars.index
から admin.seminars.index
に変更した点がポイントです。
ステップ4: 動作確認
最後に、ブラウザで動作を確認します。
準備:管理者ユーザーを作成する
テストを行うには、is_admin
フラグが true
になっている管理者ユーザーが必要です。Tinkerを使って作成しましょう。
# ターミナルでTinkerを起動
./vendor/bin/sail artisan tinker
# Tinker内で実行
use App\Models\User;
User::create([
'name' => 'Admin User',
'email' => 'admin@example.com',
'password' => bcrypt('password'),
'is_admin' => true
]);
確認手順
- 一度アプリケーションからログアウトします。
- 先ほど作成した管理者アカウント(
admin@example.com
/password
)でログインします。 - ブラウザで
http://localhost/admin/seminars
にアクセスします。
「セミナー管理画面」というヘッダーと共に、データベースに登録されているセミナーがテーブルで表示されれば成功です。
一覧表示ができたので、次はいよいよCRUDの C (Create)、つまり新しいセミナーを登録するための機能を作成します。一覧ページに「新規作成」ボタンを追加し、セミナー情報を入力するためのフォームを作成していきましょう。
(つづく)
投稿者プロフィール
- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。