Laravel

01このレッスンのゴール

ここでは、HTML&CSSやPHPのレッスンで作成したメモ帳をLaravelを用いて作成し、基本的な使い方について学んでいきます。

メモ帳を作成していく中で「MVCモデル」について詳しく解説していきます。

MVCモデル及びLaravelの記述法、ルールをしっかりと理解していきましょう。

02Laravelとは?

Laravelとは2011年にリリースされたPHPのフレームワークです。 PHPフレームワークとしては後発ながら、使いやすさなどから今や世界で最も人気のフレームワークとなっています。

フレームワークとしてLaravelが優れているポイントや具体的なメリットは以下の通りです。

  • 分業開発がしやすい
  • 構成が分かりやすく学習コストが低い
  • プログラムの拡張性が高い
  • 将来性が高い

なぜ分業作業がしやすいのか?

Laravelとは「MVC」というアーキテクチャを採用しているフレームワークだからです。

MVCはアプリケーション内の各処理機能の頭文字で

M = 「Model(モデル)」

V = 「View(ビュー)」

C = 「Controller(コントローラ)」

をそれぞれ意味しています。下に図解を示しました。

MVCについて説明します。

Model(モデル)は、データの処理を行う

データベースへのアクセス(登録/更新/削除/検索の実行)や、データの加工等々、データにまつわる処理全般を請け負うのがModelです。

View(ビュー)は、ブラウザに表示される画面を作る

Controllerから取得したデータをテンプレートを使ってブラウザに出力するのもViewの役割です。HTMLやJSがメインとなるので、皆さんにとっては馴染み易いかもしれません。

Controller(コントローラー)は、上記の「Model」と「View」の橋渡しとなる

画面からの入力値をModel層の処理機能へデータとして引き渡したり、 データベースから取得したデータを画面へ表示するためにView層へ渡したりと、ViewとModelの間を取り持ちます。

大まかな処理の流れ

  1. ページURLにアクセスされ、ルートファイル(Routes/web.php)が作動し設定されたコントローラメソッドを実行する。
  2. コントローラメソッドが実行され特定のモデルが呼び出されることでDBから値を取得する。
  3. 値が取得できた後は指定のView(ブレードファイルのこと)が表示される。
  4. Viewが表示されたタイミングでCSSやJSが反映される。

用語は後から順を追って説明します。

この流れはLaravelを理解するうえで非常に重要なので何度も記述します。

今は理解できなくても大丈夫です。

03Laravelのインストール(cloud9)

まずはLaravelをインストールしていきましょう。以下の手順に沿ってLaravelをインストールしてください。

今回はcloud9の中に環境を構築をしていくので、cloud9の画面を開いてください。

まずはPHPとComposerがインストールされているか確認します。

ターミナルを開き、ワークスペース直下(~/environment)に移動した状態で下記コマンドを入力・実行してください。

PHPの確認

php -v

Composerの確認

composer about

容量不足防止のため、メモリを解放

sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"

注意

「Command ‘composer’ not found, but can be installed with: sudo apt install composer」と表示された場合は、下記のコマンドを実行
curl -sS https://getcomposer.org/installer | php

sudo mv composer.phar /usr/local/bin/composer

composer about

下記のように表示されていればOKです。

composerとは

composerとは、PHPのライブラリ管理システムです。PHPのライブラリをインストールしたり、バージョンをコントロールしたりするために利用します。

composerを利用すれば、あるライブラリをインストールするときに、そのライブラリに必要なライブラリ(依存ライブラリ)も自動的にインストールされるため、インストールしたいライブラリの依存ライブラリを手動で探して、インストールする必要がありません。

LaravelもPHPのライブラリの1つであるため、composerで扱います。Laravelにも多くの依存ライブラリがありますが、composerを使うと簡単にLaravelプロジェクトを作成できます。

今後も、PHPライブラリを使用するときは、composerを使用します。

次にLaravelをインストールしていきます。

下記コマンドを順番に入力してください。

// Laravelのインストーラをダウンロード
composer global require laravel/installer
// グローバルにインストールしたパッケージに含まれるコマンドにパスを通す
composer global config bin-dir --absolute
// Composerのbinディレクトリを$PATHへ登録
echo 'export PATH="$PATH:$HOME/.config/composer/vendor/bin"' >> ~/.bashrc
source ~/.bashrc
// PHPのcurlをインストール
sudo apt-get install php8.1-curl
// 
sudo apt-get install php-xml
// Laravelをインストール
laravel new laravel_app

インストールする内容に関して質問があるので、下記のように回答してください。

※矢印キーで移動、Enterで選択できます。

最後、「Application key set successfully」と表示された後、使用するデータベースを選択できます。ここでは「MySQL」を選択してください。

ファイルがダウンロードされていれば成功です。

ファイル構成の写真

続いて、いくつか初期設定を行っていきます。

まず、Cloud9を使用するにあたり、「すべてのプロキシ(Webブラウザの代わりにホームページにアクセスする機能)」を許可しなければなりません。

/laravel_app/app/Http/Middleware/TrustProxies.phpを開き、protected $proxies; と書かれた1行があるので、この行を以下のように変更し、Ctrl+Sで上書き保存をしてください 。

protected $proxies = '*';

続いて、LaravelでURLを生成するroute()関数を、初期設定ではhttpから始まるものになっているので、httpsになるように設定します。

/laravel_app/app/Providers/AppServiceProvider.phpに下記のように設定を追記し、Ctrl+Sで上書き保存をしてください 。

public function boot(): void
{
    \URL::forceScheme('https');
}

最後に、タイムゾーンの設定を行います。

config/app.phpを開き、timzoneという箇所を下記のように変更します。

'timezone' => 'UTC',
↓
'timezone' => 'Asia/Tokyo',

Git

バージョン管理も行います。laravel_appのディレクトリの中で下記コマンドを実行してください。

git add .
git commit -m "init Laravel Project"

ブラウザでの動作確認

Laravelのコマンドによってサーバを起動し、ブラウザでLaravelの初期状態のアプリケーションを表示させます。

laravel_appディレクトリ配下で下記コマンドを実行してください。

php artisan serve --host=$IP --port=$PORT

すると下記の状態になると思います。

続いて、アプリケーションをWebブラウザで表示させます。

メニューから Preview -> Preview Running Application を選択してプレビューを表示します。

プレビューの右上の斜め右上を向いているアイコンをクリックすると、ブラウザで表示されます。

下記のようなページになっていれば成功です。

04MySQLサーバの起動(Cloud9)

.envというファイルを開き、下記のように値を更新します。

DB_DATABASE=laravel_app
DB_USERNAME=dbuser
DB_PASSWORD=dbpass

次にlaravel_appというデータベースを作成していきます。新しいターミナルを開いて下記コマンドを実行します。

// MySQLサーバ起動
sudo service mysql start
// ログイン
sudo mysql -u root
// データベース作成
CREATE DATABASE `laravel_app`;
// データベースが作成されているか確認
SHOW DATABASES;

下記のようにデータベースが作成されていれば完了です。

では実際にDBに接続できているか確認します。

確認のために「tinker」というLaravelの機能を用います。

簡単にいうとtinkerは何でも実行機能だと思っていただけたら大丈夫です。深くは触れませんが「tinker」について深く知りたい方は以下リンクを参照してください。

【Laravel】Laravel tinkerを使ったら開発が快適になった話 | Web Apps Labo

下記コマンドを実行してください。

php artisan tinker

これでtinkerが起動しました。

次に以下のコマンドを実行します。

DB::reconnect();

上記の画像のように表示されたらDBに無事接続できている証拠です。

次にデータベースの初期設定を行います。

まずはユーザの追加を行います。.envに登録したユーザをMySQLに追加しましょう。

sudo mysql -u root
// ユーザの追加
CREATE USER 'dbuser'@'%' IDENTIFIED BY 'dbpass';
// 追加したユーザに権限を付与
GRANT ALL ON *.* TO 'dbuser';
// 一旦MySQLからログアウト
exit;
// MySQLサーバを停止
sudo service mysql stop
// MySQLサーバを再起動
sudo service mysql start
// もう一度MySQLサーバに接続
sudo mysql -u root
// 作成したユーザが追加されているか確認
SELECT Host, User FROM mysql.user WHERE User = 'dbuser';

最後のコマンドを打ったあと、このようにターミナルに表示されてればOKです。

ファイル構成

この段階では、軽く眺めるだけにとどめて次に進んでください。

ファイル/フォルダ役割
app/アプリケーションのためのファイルが格納されます
bootstrap/デザインとしてのBootstrapとは別もので、Laravel起動のためのファイルが置かれています
config/Laravelアプリケーションの設定ファイルがあります
database/データベース関連のファイルがあります
public/アプリケーションの公開に関する設定ファイルや、CSS、JavaScriptが格納されます
resources/View(HTML)などのファイルが格納されます
routes/ルーティングなどのファイルが格納されます
storage/アプリケーションのキャッシュやログなどが格納されます
tests/自動テストファイルが格納されます
vendor/composerにより追加されたライブラリが格納されます
.envデータベースのユーザID・パスワードなど設定情報を記述するファイルです
.env.example.envの記述例として用意されています
.gitattributesGitの動作設定が記載されています
.gitignoreGitのコミットから除外するLaravelのフォルダ・ファイルの設定が記載されています
artisanphp artisan … という形で便利なコマンドを提供します
composer.jsoncomposerにより追加されるLaravelプロジェクトのライブラリを管理しています
composer.lookcomposer.jsonで指定されたライブラリの具体的な状態が書かれています
package.jsonNode.jsのライブラリが管理されています
phpunit.xml自動テストのためのファイルです
README.mdLaravelに関する参考文書です
server.php起動するWebサーバの処理が記述されています
webpack.mix.jsCSSやJavaScriptなどのフロントエンドファイルに関する管理が行われます

初期状態での動作確認

なぜこの「Laravel」と書かれたページが表示されるのか、処理の流れを確認しておきましょう。

Laravelは、閲覧者からのリクエストがあるとまずRouterを確認します。Routerの具体的な設定コードは routes/web.php にあります。ここにすべてのルーティングが書かれます。

つまり、 routes/web.php は HTTPリクエストのすべての入り口 になります。このファイルを見るとLaravelアプリケーションがどのような動作を行うかがわかるため、動作確認時に もっとも大事なファイル です。

Laravelプロジェクトを生成した直後のルーティングを見てみましょう。<?php のPHP開始タグや /* ... */ のコメントを無視すると、下記のシンプルなコードが残ります。これが「Laravel」のページへのルーティングを行っています。

routes/web.php (コメントなどは無視)

Route::get('/', function () {
    return view('welcome');
});

上記のコードは、 '/' に GET メソッドでHTTPリクエストが来ると、 view('welcome')が実行されます。

'welcome' とは、 resources/views/welcome.blade.php ファイルです。つまり、 '/' に GET メソッドでHTTPリクエストが来ると、 resources/views/ フォルダにある welcome という名前のついた拡張子 .blade.php のファイルが表示されます。

ここでは、 view() は resources/views/ 以下にあるファイルを表示するための関数で、 routes/web.php では Route::get() 等のメソッドを使ってルーティングを決定する、と理解しましょう。

注意しておくと、本コースではLaravelの具体的な仕組みに関しては解説しません。

たとえば view() 関数がどこで定義されているとか、 Route::get() の呼び出し側の関数がどこに定義されていて、 return view('welcome'); で返された値はどうなるのか、といった「具体的にLaravelフレームワークを読み解く行為」は行いません。

そもそもLaravelという巨大なWebアプリケーションフレームワークのしくみを完全に把握するには、かなり時間がかかります。そのため、しくみから理解すべきではなく、あくまでLaravelを使った開発のルールを学ぶために時間を使いましょう。

まずはそういうものだと納得して、使い方を覚えるようにしてください。しくみを理解せずとも使い方さえわかれば、Webアプリケーションを作ることは充分できます。実際、私たちは1つのコマンドで、すでにWebアプリケーションの雛形を作成し、「Laravel」という表示を行うに至っています。

では、 resources/views/welcome.blade.php を開いてみてください。style要素(CSS)が長いので、以下は、body要素のみ抜粋しています。

resources/views/welcome.blade.php (body要素のみ抜粋)

<body class="antialiased">
        <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
            @if (Route::has('login'))
                <div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
                    @auth
                        <a href="{{ url('/home') }}" class="text-sm text-gray-700 dark:text-gray-500 underline">Home</a>
                    @else
                        <a href="{{ route('login') }}" class="text-sm text-gray-700 dark:text-gray-500 underline">Log in</a>

                        @if (Route::has('register'))
                            <a href="{{ route('register') }}" class="ml-4 text-sm text-gray-700 dark:text-gray-500 underline">Register</a>
                        @endif
                    @endauth
                </div>
            @endif

            <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
                <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
                    <svg viewBox="0 0 651 192" fill="none" xmlns="<http://www.w3.org/2000/svg>" class="h-16 w-auto text-gray-700 sm:h-20">
                        <g clip-path="url(#clip0)" fill="#EF3B2D">
                            <path d="M248.032 44.676h-16.466v100.23h47.394v-14.748h-30.928V44.676zM337.091 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-[br-xs]5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.431 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162-.001 2.863-.479 5.584-1.432 8.161zM463.954 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.432 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162 0 2.863-.479 5.584-1.432 8.161zM650.772 44.676h-15.606v100.23h15.606V44.676zM365.013 144.906h15.607V93.538h26.776V78.182h-42.383v66.724zM542.133 78.182l-19.616 51.096-19.616-51.096h-15.808l25.617 66.724h19.614l25.617-66.724h-15.808zM591.98 76.466c-19.112 0-34.239 15.706-34.239 35.079 0 21.416 14.641 35.079 36.239 35.079 12.088 0 19.806-4.622 29.234-14.688l-10.544-8.158c-.006.008-7.958 10.449-19.832 10.449-13.802 0-19.612-11.127-19.612-16.884h51.777c2.72-22.043-11.772-40.877-33.023-40.877zm-18.713 29.28c.12-1.284 1.917-16.884 18.589-16.884 16.671 0 18.697 15.598 18.813 16.884h-37.402zM184.068 43.892c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002-35.648-20.524a2.971 2.971 0 00-2.964 0l-35.647 20.522-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v38.979l-29.706 17.103V24.493a3 3 0 00-.103-.776c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002L40.098 1.396a2.971 2.971 0 00-2.964 0L1.487 21.919l-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v122.09c0 1.063.568 2.044 1.489 2.575l71.293 41.045c.156.089.324.143.49.202.078.028.15.074.23.095a2.98 2.98 0 001.524 0c.069-.018.132-.059.2-.083.176-.061.354-.119.519-.214l71.293-41.045a2.971 2.971 0 001.489-2.575v-38.979l34.158-19.666a2.971 2.971 0 001.489-2.575V44.666a3.075 3.075 0 00-.106-.774zM74.255 143.167l-29.648-16.779 31.136-17.926.001-.001 34.164-19.669 29.674 17.084-21.772 12.428-43.555 24.863zm68.329-76.259v33.841l-12.475-7.182-17.231-9.92V49.806l12.475 7.182 17.231 9.92zm2.97-39.335l29.693 17.095-29.693 17.095-29.693-17.095 29.693-17.095zM54.06 114.089l-12.475 7.182V46.733l17.231-9.92 12.475-7.182v74.537l-17.231 9.921zM38.614 7.398l29.693 17.095-29.693 17.095L8.921 24.493 38.614 7.398zM5.938 29.632l12.475 7.182 17.231 9.92v79.676l.001.005-.001.006c0 .114.032.221.045.333.017.146.021.294.059.434l.002.007c.032.117.094.222.14.334.051.124.088.255.156.371a.036.036 0 00.004.009c.061.105.149.191.222.288.081.105.149.22.244.314l.008.01c.084.083.19.142.284.215.106.083.202.178.32.247l.013.005.011.008 34.139 19.321v34.175L5.939 144.867V29.632h-.001zm136.646 115.235l-65.352 37.625V148.31l48.399-27.628 16.953-9.677v33.862zm35.646-61.22l-29.706 17.102V66.908l17.231-9.92 12.475-7.182v33.841z"/>
                        </g>
                    </svg>
                </div>

                <div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
                    <div class="grid grid-cols-1 md:grid-cols-2">
                        <div class="p-6">
                            <div class="flex items-center">
                                <svg xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 text-gray-500"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold"><a href="<https://laravel.com/docs>" class="underline text-gray-900 dark:text-white">Documentation</a></div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end.
                                </div>
                            </div>
                        </div>

                        <div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-t-0 md:border-l">
                            <div class="flex items-center">
                                <svg xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 text-gray-500"><path stroke-linecap="round" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z" /></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold"><a href="<https://laracasts.com>" class="underline text-gray-900 dark:text-white">Laracasts</a></div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
                                </div>
                            </div>
                        </div>

                        <div class="p-6 border-t border-gray-200 dark:border-gray-700">
                            <div class="flex items-center">
                                <svg xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 text-gray-500"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" /></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold"><a href="<https://laravel-news.com/>" class="underline text-gray-900 dark:text-white">Laravel News</a></div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials.
                                </div>
                            </div>
                        </div>

                        <div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-l">
                            <div class="flex items-center">
                                <svg xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-8 h-8 text-gray-500"><path stroke-linecap="round" stroke-linejoin="round" d="M6.115 5.19l.319 1.913A6 6 0 008.11 10.36L9.75 12l-.387.775c-.217.433-.132.956.21 1.298l1.348 1.348c.21.21.329.497.329.795v1.089c0 .426.24.815.622 1.006l.153.076c.433.217.956.132 1.298-.21l.723-.723a8.7 8.7 0 002.288-4.042 1.087 1.087 0 00-.358-1.099l-1.33-1.108c-.251-.21-.582-.299-.905-.245l-1.17.195a1.125 1.125 0 01-.98-.314l-.295-.295a1.125 1.125 0 010-1.591l.13-.132a1.125 1.125 0 011.3-.21l.603.302a.809.809 0 001.086-1.086L14.25 7.5l1.256-.837a4.5 4.5 0 001.528-1.732l.146-.292M6.115 5.19A9 9 0 1017.18 4.64M6.115 5.19A8.965 8.965 0 0112 3c1.929 0 3.716.607 5.18 1.64" /></svg>
                                <div class="ml-4 text-lg leading-7 font-semibold text-gray-900 dark:text-white">Vibrant Ecosystem</div>
                            </div>

                            <div class="ml-12">
                                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                                    Laravel's robust library of first-party tools and libraries, such as <a href="<https://forge.laravel.com>" class="underline">Forge</a>, <a href="<https://vapor.laravel.com>" class="underline">Vapor</a>, <a href="<https://nova.laravel.com>" class="underline">Nova</a>, and <a href="<https://envoyer.io>" class="underline">Envoyer</a> help you take your projects to the next level. Pair them with powerful open source libraries like <a href="<https://laravel.com/docs/billing>" class="underline">Cashier</a>, <a href="<https://laravel.com/docs/dusk>" class="underline">Dusk</a>, <a href="<https://laravel.com/docs/broadcasting>" class="underline">Echo</a>, <a href="<https://laravel.com/docs/horizon>" class="underline">Horizon</a>, <a href="<https://laravel.com/docs/sanctum>" class="underline">Sanctum</a>, <a href="<https://laravel.com/docs/telescope>" class="underline">Telescope</a>, and more.
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="flex justify-center mt-4 sm:items-center sm:justify-between">
                    <div class="text-center text-sm text-gray-500 sm:text-left">
                        <div class="flex items-center">
                            <svg xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="-mt-px w-5 h-5 text-gray-400">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 00-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 00-16.536-1.84M7.5 14.25L5.106 5.272M6 20.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm12.75 0a.75.75 0 11-1.5 0 .75.75 0 011.5 0z" />
                            </svg>

                            <a href="<https://laravel.bigcartel.com>" class="ml-1 underline">
                                Shop
                            </a>

                            <svg xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="ml-4 -mt-px w-5 h-5 text-gray-400">
                                <path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" />
                            </svg>

                            <a href="<https://github.com/sponsors/taylorotwell>" class="ml-1 underline">
                                Sponsor
                            </a>
                        </div>
                    </div>

                    <div class="ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0">
                        Laravel v{{ Illuminate\\Foundation\\Application::VERSION }} (PHP v{{ PHP_VERSION }})
                    </div>
                </div>
            </div>
        </div>
    </body>

ファイル名が welcome.blade.php となっており、 bladeやphpが付いていますが、中身はほぼHTMLファイルです。

どこかの文章を変更してみましょう。

画面を読み込むと変更したように画面が変更されるはずです。

05Routeについて学ぶ

ここからは実際にLaravelを触り、理解を深めます。

Routeとは?

routeとは、URLとコントローラーのアクションの対応ルールのことです。対応ルールを作成することをルーティングと呼んだりします。

このURLでアクセスされた時にはこのコントローラーのアクションを呼び出してください、ということをアプリケーションにお願いするために、Laravelのバージョン5.3からはroutes/web.phpにルートを定義していきます。

このファイルをみればどのURLでどの処理が行われるのかが一目瞭然になります。ここに何も書かなければせっかく書いた処理も呼ばれることはないため、忘れずにルーティングしていきましょう。

RouteはRoutes/web.phpにあります。開いてみましょう。

Route::get('/', function() {
    return view('welcome');
});

初期値では上記の様になっているはずです。

これはhttp://localhost/にアクセス(GET処理で)するとwelcom.blade.phpを表示するという意味です。.blade.phpは省略して書くことができます。

環境構築したときウェルカムページが表示されていましたがまさにこのRouteが実行されて表示されたものです。

ちなみにwelcom.blade.phpはresources/views/welcom.blade.phpにあります。

では、resources/views/の中にhome.blade.phpというファイルを作成してみましょう。

.blade.phpという拡張子はLaravel特有の拡張子でViewの部分を作成するファイルです。

以下のひな型をコピペしてください。

home.blade.php

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>メモ帳</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
<div class="container">
    <div class="memo_area">
        <div class="memo_form">
            <h2>メモを追加</h2>
            <form action="">
                <input class="memo_text" type="text" name="" id="">
                <input type="submit" value="追加">
            </form>
        </div>
        <div class="memo_show">
            <div class="memo_item">
                <div class="memo_title">
                    <time>2022.10.10</time>
                    <p>サッカー</p>
                </div>
                <div class="btn_area">
                    <div class="edit_form">
                        <form action="">
                            <input type="submit" value="編集">
                        </form>
                    </div>
                    <div class="del_area">
                        <form action="">
                            <input type="submit" value="削除">
                        </form>
                    </div>
                </div>
            </div>
            <div class="memo_item">
                <div class="memo_title">
                    <time>2022.10.10</time>
                    <p>大阪旅行</p>
                </div>
                <div class="btn_area">
                    <div class="edit_form">
                        <form action="">
                            <input type="submit" value="編集">
                        </form>
                    </div>
                    <div class="del_area">
                        <form action="">
                            <input type="submit" value="削除">
                        </form>
                    </div>
                </div>
            </div>
            <div class="memo_item">
                <div class="memo_title">
                    <time>2022.10.10</time>
                    <p>メモ内容</p>
                </div>
                <div class="btn_area">
                    <div class="edit_form">
                        <form action="">
                            <input type="submit" value="編集">
                        </form>
                    </div>
                    <div class="del_area">
                        <form action="">
                            <input type="submit" value="削除">
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

次にpublicフォルダの中にCSSフォルダを新しく作成し、その中にstyle.cssを新しく作ってください。

作成したstyle.cssに以下のコードをコピペしてください。

style.css

body{
    background-color: #edf2f4;
}

.container{
    max-width: 980px;
    margin-right: auto;
    margin-left: auto;
}

.memo_area{
    display: flex;
    justify-content: space-around;
}

.memo_form{
    text-align: center;
    width: 40%;
}

.memo_form input[type="submit"]{
    border-radius: 5px;
    border: none;
    padding: 5px 20px;
    background-color: #38B000;
    color: #fefefe;
    font-weight: bold;
}

.memo_form h2{
    text-align: center;
}

.memo_text{
    display: block;
    margin: 0 auto 15px;
    border: none;
    height: 20px;
}

.memo_show{
    width: 60%;
}

.memo_item{
    background-color: #fefefe;
    display: flex;
    width: 100%;
    margin-top: 10px;
    padding: 5px 10px;
    border-radius: 5px;
}

.memo_title{
    width: 90%;
}

.memo_title p{
    margin: 0;
}

.memo_title time{
    font-size: 10px;
}

.btn_area{
    display: flex;
    margin: auto;
}

.edit_form{
    margin-right: 10px;
}

.edit_form input,
.del_area input {
    border-radius: 5px;
    padding: 5px 12px;
    border: none;
}
.memo_form input[type="submit"]:hover,
.edit_form input:hover,
.del_area input:hover{
    opacity: .8;
}

.edit_form input{
    background-color: #38B000;
    color: #fefefe;
    font-weight: bold;
}

.del_area input{
    background-color: #d64045;
    color: #fefefe;
    font-weight: bold;
}

ページを再読み込みしてもページは何も変わりません。

これは、以下の部分を変更していないからです。

web.php

Route::get('/', function() {
    return view('welcom');
});

いくらhome.blade.phpを変更しようが今のままではwelcome.blade.phpが表示されるので、次にhome.blade.phpが表示されるようにRouteを修正しましょう。

web.php

Route::get('/', function() {
    return view('home'); // ここを変更
});

上記のように修正できたらページを読み込んでみましょう。

画像のようになっていると思います。

それでは一部コードの解説をします。

<link rel="stylesheet" href="{{ asset('css/style.css') }}">

laravelのブレードファイルでは{{ }}で囲うことによって<?php echo ?>と同じ意味になります。(後で詳しく解説します)

今回は<?php echo asset(’css/style.css’); ?>というPHP文になります。

これはLaravelの機能になります。ブレードファイルに変数などを埋め込むときはこれから{{ }}を使うようにしましょう。

そして、asset('css/style.css')ですが、asset('ファイルパス')はpublicディレクトリのパスを返す関数となっています。

なので今回はpublicフォルダの中のcssフォルダの中のstyle.cssを指定しています。

先ほどpublicフォルダの中にcssフォルダを作成し、さらにcssフォルダ内にstyle.cssを新規作成しました。

そのstyle.cssファイルがhome.blade.phpに反映されています。

06マイグレーションについて学ぶ

ここではマイグレーションについて学んでいきます。

マイグレーションとは?

migrationはDBの改編記録(どういうテーブルをつくったのか、どういうカラムを追加したのか?など)をしっかり残し、いつでもその改変を戻せるようにできる機能です。

また、Laravelの場合、わざわざSQLを叩かずともlaravelで用意されている形式でその設定を書くことで、わかりやすくテーブルの作成等ができるようになっています。

マイグレーションファイルを作成してみましょう

新しくターミナルを開き、laravel_appの階層に移動してください。

※今後「php artisan」から始まるコマンドはすべてlaravel_appディレクトリの中で使用することを念頭に置いててください。

以下のコマンドでマイグレーションファイルを作成することができます。

//テーブルを作成するときのコマンド
php artisan make:migration create_テーブル名_table

//テーブルを削除するときのコマンド
php artisan migrate:rollback

//テーブルを作成してみる これを実行する
php artisan make:migration create_memos_table

実行できたら以下の画像のようにファイルが生成されたはずです。

database/migrationsの中に格納されています。

ファイルの中身を確認してみましょう。

※memo_table.php以外はデフォルトで格納されています。

<?php

use Illuminate\\Database\\Migrations\\Migration;
use Illuminate\\Database\\Schema\\Blueprint;
use Illuminate\\Support\\Facades\\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('memos', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('memo');
    }
};

ファイルに中にupメソッドとdownメソッドが存在します。

upメソッドについて

データベースに新しいテーブルやカラムなどを生成するための処理を記述する部分です。

デフォルトでidカラムとタイムスタンプの2つが既に記述されているので、その書き方にしたがって、追加したいカラムを記述していきます。

$table->id();
$table->timestamps();

1行目でidという名のカラムを作成するという意味です。テーブルを作成する時は必ずidを設定するようにしましょう。

idにはオートインクリメントという機能があり、自動で番号を振ってくれます。この数字はかぶることがなく、必ず一意になります。

2行目ではNULL値可能なcreated_atとupdated_atカラム追加しています。

cerate_atはtimestamps()というメソッドです。

自動的にcreated_atとupdated_atのカラムを作成されます。

レコードが追加されたときに自動的に現在の時間が格納されます。

また、後ほど説明しますが、update()メソッドを使用するとレコードが更新された際の時間がupdated_atに上書きされます。

では実際にupメソッドを編集し、追加カラムを変更してみましょう。

先ほど作成したマイグレーションファイルのupメソッド内を以下のように追記してください。

$table->id();
// この1行を追加してください
$table->string('content', '255');
$table->timestamps();

$table->string('content', '255');はテーブルにcontentという名前のカラムで255文字以内の文字列型が入るカラムを作成することを指定しています。

その他の利用可能なカラムタイプ

メソッド名説明
date()DATE(日付)カラムを作成する
integer()INTEGER(数値)カラムを作成する

さらに詳しくカラムアイプを知りたい方はこちら

マイグレーション 8.x Laravel

downメソッド

テーブルを削除するための処理を記述する部分で、rollbackを実行したときに走る用として書きます。

downメソッドは新規登録の場面では既に記述されていますが、カラムの追加や削除を行うときはdownメソッドにも記述する必要があります。

記述の仕方は簡単で、upメソッドに記述したカラムに対応したdropColumnを記述するだけです。

それではマイグレーションを実行し、テーブルを作成してみましょう

下記のコマンドをターミナルで実行してください。

php artisan migrate

ターミナルに以下画像のように出力されたら成功です。

次に、テーブルが作成されているかをターミナルで確認していきます。

下記のコマンドを入力してください。

// ターミナルが「mysql>」の状態になっていない場合は下記コマンドを実行
sudo mysql -u root
// 使用するデータベースを選択
USE laravel_app
// テーブルの一覧を表示
SHOW TABLES;

※画像はmemoテーブルですが正しくはmemosテーブルです

memosテーブルが追加されていることが確認できました。

つづいて、memosテーブルの中身を確認しましょう。

DESCRIBE memos;

「id」「content」「created_at」「updated_at」の4つのカラムが作成されています。

「id」は$table->id();「content」は先ほど追加した$table->string('content', '255');「created_at」と「updated_at」は$table->timestamps();から作成されています。

補足:テーブルとそのカラム名一覧を一度に確認したい場合は、下記のコマンドを実行してください。

// テーブルとそのカラム名の一覧を表示
SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_schema = 'laravel_app';

07モデルについて学ぶ

モデルはMVCモデルのMにあたるかなり大切な部分になります。

しっかり理解するようにしましょう。

モデルとは?

関数名用途
allすべてのレコードを取得する
findidを指定して検索
first最初のレコードを1件だけ取得する
where検索条件を指定
saveレコードの作成および更新
delete, destroyデータの削除。destroyは主キーを複数指定して削除可能

モデルの作成方法

LaravelのModelはartisanコマンドで簡単に作成することができます。

php artisan make:model モデル名

// Memoモデルの場合(コマンドを実行)
php artisan make:model Memo

Modelの生成先を指定したい場合はModel名の前にパスを指定します。

php artisan make:model Models\User

ちなみにModelを削除したい場合は、オプションが用意されていないため、手動でファイルを削除する必要があります。

作成されたモデルを見てみましょう。

<?php

namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Database\\Eloquent\\Model;

class Memo extends Model
{
    use HasFactory;

    //
}

このメモアプリではMemoモデルには記述するコードは不要です。

Memoモデルが存在するだけでmemosテーブルにアクセスできるようになります。

モデルはDBに接続するために必要な機能です。必ず1つのテーブルに対して1つのモデルを作成しましょう。

また、 class Message extends Model { // }と書かれているだけで中身がない空クラスに思えますが、実は extendsしている Illuminate\\Database\\Eloquent\\Modelに多くの関数やパラメータがあらかじめ定義されています。

Memoモデル特有の機能が必要な場合にのみ上記の //部分に関数を追加します。

下記の参考を読むと、かなり多くの関数やパラメータが定義されていることがわかることでしょう。

補足ですが、 Laravelのモデルは use Illuminate\\Database\\Eloquent\\Model; でも書かれているように、 Eloquent(エロケント)モデルと呼ばれます。それほど気にする必要はありませんが、LaravelではモデルをEloquentと呼ぶことがあります。この点を覚えておきましょう。

モデルの命名規則

LaravelのModelには命名規則があります。

例えば、テーブル名がusersの場合、Model名はUserになります。

テーブル名を単数形にしたものがModel名となり、自動的にテーブルを操作することができるようになります。

この命名規則以外にモデル名を設定したい場合は、以下のように$tableにテーブル名を設定します。

例)テーブル名が「premium_users」の時

**<?php 
namespace App; 
use Illuminate\\Database\\Eloquent\\Model; 

class User extends Model{    
    protected $table = 'premium_users';
}**

このようなカスタマイズ方法は、大抵はLaravelのドキュメントにて説明されていますが、中にはコアの実装を見ることで方法を知るケースもあるので、Laravelのコアのソースを時間がある時にでも読んで見ると良いでしょう。

コントローラについて

コントローラはモデルとビューの橋渡しをする存在です。

主に2つの役割を持っています。

  • ルートから受け取った情報をモデルに処理をお願いする
  • モデルから受け取った情報をビューに表示する

具体的にはモデルからDBにアクセスし、取得したデータをコントローラで加工してビューに渡すと行ったことや、ビューからのデータをモデルに渡し、DBに保存をしたりします。

またバリデーション(データが正当かどうかを判断する機能)もコントローラに記述します。

08コントローラを作成する

php artisan make:controller コントローラ名

// Memoコントローラの場合(コマンドを実行)
php artisan make:controller MemoController

09コントローラに追加する

作成したコントローラに次のコードを追加して下さい。

public function show(){
    return view('home');
}

10Routeファイルを編集する

コントローラは作成しただけでは何の役割も持ちませんし実行されません。

実行されるようにするためにはRouteファイルに追加してあげなければなりません。

Routeファイルを開いて以下のコードを追加してください。

もともとあったコードは削除してください。

// この部分は削除
Route::get('/', function() {
    return view('welcom');
});

// この部分を追加
Route::get('/', 'App\\Http\\Controllers\\MemoController@show');

コードの説明をします。

URLにアクセスされると今回はApp\Http\Controllers\配下にあるMemoControllerが呼び出されています。さらに@showの部分でMemoControllerのshowメソッドを表示するように設定しています。

もう一度URLにアクセスしてみましょう。

画面は変わりませんが先ほどと違うのはコントローラを経由しているかどうかです。

処理の流れとしては、

RouteでMemoControllerのshowメソッドが呼び出される

showメソッドの中身が実行されrerurn view('home');が実行されhome.blade.phpが表示される。

という流れになります。

メモを追加してみる

メモを追加 = DBに値を追加するです。

実際にデータを追加してみましょう。

流れとしては以下のとおりです。

  1. ブレードファイルからコントローラにデータを送信する
  2. コントローラでデータを受け取る
  3. コントローラでモデルを呼び出しDBに追加する

です。

順に実装していきましょう。

1. ブレードファイルからコントローラにデータを送信する

home.blade.phpの「メモを追加」部分を以下のように修正してください。

<div class="memo_form">
     <h2>メモを追加</h2>
     <form action="{{ asset('/add') }}" method="post">
	@csrf
         <input class="memo_text" type="text" name="memo_text" id="memo_text">
         <input type="submit" value="追加">
     </form>
</div>

<form action=”{{ asset('/add') }}” method="post"></form>の部分に注目してみましょう。

まず、action=”{{ asset('/add') }}”についてです。

actionはformの送信先を設定することができます。

属性値に URI を指定することで、入力されたフォームの送信データの送信先を設定することができます。

今回は{{ asset('/add') }}を設定しています。asset()は前に解説した通り、publicディレクトリのパスを返す関数となっています。なので実際にはhttp://localhost:800/addというURLに変換されます。

よって、action=”{{ asset('/add') }}”の部分はhttp://localhost:800/addにデータを送信するよ、という意味になります。

ちなみにですが送信されるデータは<form></form>内にあるinput属性が送信されます。

今回で言うと、<input class="memo_text" type="text" name="memo_text" id="memo_text">この部分です。

memo_textというname属性のテキストボックスに入力された文字列がサーバーに送信されることになります。

続いてmethod="post"の部分ですが、method=””ではデータの送信方法を選択することができます。

大体はpostかget通信になります。今回はpost通信を選択しています。

続いてコントローラを編集します。

MemoController.phpに以下のコードを追加しましょう。

public function add()
{
    return view('home');
}

コントローラの中身は、home.blade.phpを表示するだけの簡素なコードです。

コントローラとブレードファイルは作成できましたがこのままでは何も動きません。

コントローラメソッドとurlを結び付けるためにルートファイルを編集します。

web.phpに以下のコードを追記してください。

Route::post('/add', 'App\\Http\\Controllers\\MemoController@add');

お分かりかもしれませんが、/addのurlにPOST通信でアクセスされた時にMemoControllerのaddメソッドを実行するという意味になります。

これで無事にメモの追加ボタンを押したときコントローラに入力されたテキストが送信されるようになりました。

実際にデータを送信できているか確認してみましょう。

画面上で右クリックし(またはctrl + shift + j)検証をクリックしデベロッパーツールを開きましょう。

次にタブ「NetWork」をクリックしてください。

NetWorkは送信されたデータの中身や読み込まれたファイル、アクセスされたurl情報を見ることができます。

実際にメモを追加のテキストボックスにテキストを入力し追加ボタンを押してみましょう。

Name欄にaddが表示されているはずです。

何かエラーが出た場合はどこかで記述が間違ってしまっている可能性があるのでもう一度確認しましょう。

addのPaloadをクリックすると、addのurlに送信されたデータの中身を見ることができます。

今回は「_token」「memo_text」の2つが送信されています。

「memo_text」に今回テキストボックスに入力したデータがはいっています。

今後開発をする中でもどんなデータが送信されているかなどを確認する場面が多々あるので、NetWorkから確認できることを覚えておきましょう。

では続きに戻ります。現状データは送信されていますが受信する側に何もコードを書いていないためデータが追加されることはありません。

2.コントローラでデータを受け取る

それではデータを受け取る部分を書いていきましょう。

memoController.phpのaddメソッドを以下のように追記してください。

public function add(Request $request)
{
    dd($request);
    return view('home');
}

追記できたらメモを追加してみましょう。

追加ボタンを押すと上記画像のように黒い画面が表示されると思います。

これはdd($request);が影響しています。

dd()は「dump and die」の略でdd()の行で処理を止め、引数の中身の変数を画面に表示させます。

今回は$requestの中身が表示されています。

続いて$requestについてですが、$requestはLaravelに標準搭載されているRequestクラスが格納されており、ブレードから送信された情報やその他のサーバーやセッションなどの情報が詰まっています。

今回ほしい情報は「memo_text」のメモ追加のテキストボックスに入力されたテキストだけです。

requestのparametersを見てみましょう。

「_token」と「memo_text」が入っています。

この中でも「memo_text」の情報のみを取得するときは以下のように記述します。

public function add(Request $request)
    {
        $memo_text = $request->memo_text; // これで「memo_text」を取得できます
        dd($memo_text);
        return view('home');
    }

ページを再度読み込んでみると「memo_text」の中身のサンプルテキストのみが取得できています。

$memo_text = $request->memo_text;この部分が$requestの受信データの塊からmemo_textという名のname属性を持ったデータを取得し$memo_textという変数に格納しています。

ここまでの手順でデータを取得できたので、続いてデータをDBに登録してみましょう。

3.コントローラでモデルを呼び出しDBに追加する

DBに追加や削除する場合にはモデルを使います。

以下のコードをMemoController.phpに追加してください。

use App\Models\Memo; // 追加
(省略)
public function add(Request $request)
{
    $memo_text = $request->memo_text;
    $memo_model = new Memo();
    $memo_model->content = $memo_text;
    $memo_model->save();

    return self::show(); // ここを書き替える
}

コードの解説をしていきます。

まずMemoモデルを使用するため、use App\Models\Memo;を追加しています。

次に$memo_model = new Memo();この部分ですが、Memoモデルをインスタンス化して$memo_modelに格納しています。

ここから作成した空っぽのインスタンスにデータを追加していきます。

$memo_model->content = $memo_text;この部分でインスタンスのcontentというプロパティに$memo_textつまりメモ追加テキストボックスに入力された文字列を格納しています。

ここまでではインスタンスにデータが格納されただけでDBにはデータが追加されていません。

最後にインスタンスの内容をDBに登録します。

$memo_model->save();インスタンスにsave()を使うことによってDBに保存することができます。

実際にDBの中身を確認してみましょう

ターミナルでmysqlに入り(sudo mysql -u root)、下記コマンドを実行しましょう。

SELECT * FROM memos;

データがしっかり入っていますね。

これで無事にDBに値を追加する部分を実装することができました。

では、続いてDBの中身を画面に表示させてみましょう。

DBからデータを取得する

DBからデータを取得する時もモデルを使います。

取得する方法はとてもシンプルです。

MemoController.phpのshowメソッドに以下のコードを追加しましょう。

public function show()
{
    $memo_info = Memo::get(); // 追加

    return view('home')
        ->with('memo_info', $memo_info); // 追加
}

注目すべきは$memo_info = Memo::get();です。ここでは、Memoモデルからデータを取得しています。試しに取得した中身を確認してみましょう。

dd($memo_info);を追加して$memo_infoの中身を確認してみましょう。

先ほど追加したメモ情報が格納されています。

では、なぜデータが取れるのでしょうか。

$memo_info = Memo::get();の部分を$memo_info = Memo::*toSql*();に書き換えて画面を再度読み込んでください。

すると上記のようなSQL文が表示されたかなと思います。

toSql()はEloquentORMをSQL文に変換してくれるメソッドです。

Laravel上では$memo_info = Memo::get();となっていますが、実際には”SELECT * FROM ‘memos’”というSQLが発行されています。Memoの部分でメモテーブルにアクセスし、get()がselectの意味になっています。

WHEREやORDER BYなどのメソッドも用意されています。

そして、最後のwith('memo_info', $memo_info)の部分ですがhome.blade.phpに$memo_infoを送りブレードファイル内で$memo_infoという変数で使えるようになります。

試しにブレードファイル内でdd();し確認してみましょう。

home.blade.php

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>メモ帳</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
<?php dd($memo_info); ?> // 追加
<div class="container">
    <div class="memo_area">

MemoController.php

public function show()
    {
        $memo_info = Memo::get();

        return view('home')
            ->with('memo_info', $memo_info);
    }

画面を読み込んでみましょう。

ちゃんとブレードファイルで$memo_infoが使えるようになっています。

試しにブレードファイルのdd($memo_info);をdd($data);に変更してみましょう。

当然ですが$dataは定義されていないのでエラーになります。

コントローラのwithをwith(’data’, $memo_info);に変更するとエラーが出力されず、ブレードファイル内で$dataとして$memo_infoを使用することができます。

DBに登録されたメモを画面に表示する

ここまででDBから値を取得しブレードに送信するところまでを実装してきました。

続いて、受け取ったDBの情報を画面に表示させてみましょう。

home.blade.phpのmemo_showクラスの部分を以下のように書き換えてください。

<div class="memo_show">
     @foreach($memo_info as $memo)
         <div class="memo_item">
             <div class="memo_title">
                 <time>{{$memo->created_at}}</time>
                 <p>{{$memo->content}}</p>
             </div>
             <div class="btn_area">
                <div class="edit_form">
                   <form action="">
                      <input type="submit" value="編集">
                   </form>
                </div>
                <div class="del_area">
                   <form action="">
                      <input type="submit" value="削除">
                   </form>
                </div>
            </div>
         </div>
    @endforeach
</div>

ブレード内ではたくさんのテンプレートエンジンという便利な機能が用意されています。

HTML内でPHPのforeachを記述しようとすると、<?php foreach() ?>となります。

しかし、bladeテンプレートエンジンを用いると@foreach()と記述するだけで<?php foreach() ?>と同じ意味になります。よく使われるメソッド等についてはあらかじめLaravel側が簡単に記述できるようにテンプレートを用意してくれています。

では続きの解説をします。

{{$memo->content}}この部分ですが、まず{{ }}このかっこは前に紹介した通り<?php echo ?>の省略形で、PHPを出力することができます。

つまり$memo->contentを出力しています。$memoに格納されているデータを確認しましょう。

home.blade.php

@foreach($memo_info as $memo)
    <?php dd($memo); ?> // 追加
    <div class="memo_item">
       <div class="memo_title">
           <time>{{$memo->created_at}}</time>
           <p>{{$memo->content}}</p>
       </div>

dd($memo);を追加し、画面を読み込んでみましょう。

すると上記の画像のように表示されたはずです。

つまり$memoの中にはメモの情報である「id」「content」「created_at」「update_at」が含まれています。

ここで、contentの”サンプルテキスト”を取り出したい場合は、$memo→contentと記述します。

なので{{ $memo→content }}の部分はサンプルテキストを出力しているという意味になります。

同じように{{ $memo→created_at }}ではcreated_atに格納されている時間のデータを取得することができます。

これで無事にメモを追加して表示させる部分までを実装することができました。

試しにメモを追加してみましょう!

無事に追加されていますね。

ではこの調子で削除、編集機能も実装していきましょう。

11削除機能を実装する

続いて削除機能を実装していきます。

まずは削除ボタンを編集していきます。今のままではボタンをクリックしてもなにも起こりません。

home.blade.phpに追記

<div class="del_area">
    <form action="{{ asset('/delete') }}" method="post"> // この部分を編集
   @csrf
        <input type="hidden" name="delete_id" value="{{$memo->id}}">
        <input type="submit" value="削除">
    </form>
</div>

次にルートを編集していきます。

web.php

Route::post('/add', 'App\\Http\\Controllers\\MemoController@add');
Route::post('/delete', 'App\\Http\\Controllers\\MemoController@delete'); // 追加

MemoController.phpに追加

public function delete(Request $request)
{
    $delete_id = $request->delete_id;

    $memo_model = Memo::find($delete_id);
    $memo_model->delete();

    return self::show();
}

ではページを読み込んで削除ボタンをクリックしてみましょう。

無事に予定が削除されています。

コードを解説していきます。

<input type="hidden" name="delete_id" value="{{$memo->id}}">この部分ですが、valueにメモのidを入れています。

削除するときにどのメモの削除ボタンが押されたかがわからなければすべてのメモが削除されることになってしまいます。どのメモかを判別する値は必ず一意である必要があります。そこで今回はidを用いています。

メモを1つ追加してデベロッパーツールで確認してみましょう。

サンプルテキストのvalueは1、サッカーのvalueは3になっていますね。

name="delete_id"としているのでコントローラでdelete_idと名前でこのidを取得することができます。

$delete_id = $request->delete_id;コントローラのこの部分です。$delete_idに「サンプルテキスト」の削除ボタンが押されたときは1、「サッカー」の時は3が入ることになります。

また、typeがhiddenになっているためこのidが画面上に表示されることはありません。

では、つづいてコントローラの削除処理を見てみましょう。

先ほど解説した$delete_id = $request->delete_id;この部分で削除対象のメモのidを取得しています。

$memo_model = Memo::find($delete_id);
$memo_model->delete();

削除処理のメインはこの部分です。

1行目のMemo::find($delete_id);ですが、find()メソッドで引数のidと一致するレコードを取得しています。所得したレコードは$memo_modelに格納されています。

その後、delete()メソッドで対象のレコードを削除しています。

これで無事に削除できるようになりました。

では最後に編集できるようにしてみましょう。

編集機能を実装する

編集機能ですが以下の流れで実装していきます。

  1. 編集ボタンをクリック
  2. 編集ページに移動
  3. 編集ページでテキストを編集し、編集完了ボタンをクリック
  4. DBが上書きされる

まずは編集ボタンがクリックされると編集ページに移動する処理を書いていきましょう。

resource/viewsの中に新しくedit.blade.phpを作成し以下のコードをコピペしてください。

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>メモ帳|編集</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
<div class="container">
    <div class="memo_area">
        <div class="memo_form">
            <h2>メモを編集</h2>
            <form>
                @csrf
                <input class="memo_text" type="text" name="edit_memo" value="">
                <input type="submit" value="追加">
            </form>
        </div>
    </div>
</div>
</body>
</html>

home.blade.phpを編集

<div class="edit_form">
    <form action="{{ asset('/edit/'.$memo->id) }}" method="get">
         @csrf
         <input type="submit" value="編集">
    </form>
</div>

web.php

Route::get('edit/{edit_id}', 'App\\Http\\Controllers\\MemoController@getEdit');

MemoController.php

public function getEdit($edit_id)
{
    return view('edit');
}

ではページを読み込んで編集ボタンをクリックしてみましょう。

無事に編集画面に遷移することができました!

ここまでのコードを解説します。

まずはhome.blade.phpについてです。

action="{{ asset('/edit/'.$memo->id) }}"この部分ですが、action属性に「/edit/メモのid」というURLを指定しています。

‘/edit/’という文字列と$memo→idでえられるidを「.」で文字列結合しています。

実際にURLを見てみましょう。

デベロッパーツールからURLを確認してみましょう。

「localhost:800/edit/3」というURLになっていますね。

続いてルートファイルの'edit/{edit_id}’この部分についてです。

先ほどしたURLは/edit/の部分は定数ですが、後ろのメモのidの部分は変数になっています。

ルートでは変数を受け取ることができます。コードにもある通り、{edit_id}と記述するとコントローラで$edit_idとして使うことができます。

続いて、コントローラです。

public function getEdit($edit_id)メソッドの引数に$edit_idを入れることで、ルートで設定された変数を受け取ることができます。

現状ではテキストボックスに編集したいメモの内容が入っていないので、次はテキストボックスにメモの中身を表示させましょう。

MemoControllerのgetEditメソッドに以下のコードを追記してください。

public function getEdit($edit_id)
{
    $memo_info = Memo::find($edit_id); // 追記
        
    return view('edit')
         ->with('memo_info', $memo_info); // 追記
}

edit.blade.php

<form action="{{asset('/update')}}" method="post">
   @csrf
   <input type="hidden" name="edit_id" value="{{$memo_info->id}}">
   <input class="memo_text" type="text" name="edit_memo" value="{{$memo_info->content}}"> // 編集
   <input type="submit" value="追加">
</form>

先ほど説明した通り、コントローラでpublic function getEdit($edit_id)メソッドの引数に$edit_idを入れることで、ルートで設定された変数を受け取ることができます。

受け取った$edit_id を用いて対象のメモ情報を取得します。

$memo_info = Memo::find($edit_id);この部分でfind()メソッドを用いて対象のメモ情報を取得しています。

その後、取得した情報を->with('memo_info', $memo_info);でedit.blade.phpに送信しています。

続いてブレードファイルの説明です。

追記したのは以下の部分です。

<input class="memo_text" type="text" name="edit_memo" value="{{$memo_info->content}}">

テキストボックスに初期入力したい場合は、inputタグのvalue属性に初期入力したい値を設定します。

今回テキストボックスに表示させたいのはメモの内容なので、コントローラから送信された$memo_infoの中に入っているメモ内容を設定します。具体的には$memo_info→contentで取得できます。

それでは画面を読み込んでメモの編集ボタンをクリックしましょう。

無事にメモ内容が入っていますね!

次は更新処理です。

ここでは、編集された内容を受け取り、テーブルをアップデートする処理を書いていきましょう。

以下のコードを追記してください。

web.php

Route::post('update', 'App\\Http\\Controllers\\MemoController@postEdit');

MemoController.php

public function postEdit(Request $request)
{
     $edit_id = $request->edit_id;
     $edit_memo = $request->edit_memo;

     Memo::where('id', $edit_id)->update(['content' => $edit_memo]);

     return self::show();
}

メソッドを新たに1つ追加しました。

updateのURLにpost通信でアクセスされると実行されるメソッドです。

edit.blade.phpで<form action="{{asset('/update')}}" method="post">とupdateにデータを送信するように設定しているので、postEditが実行されます。

postEditメソッドでは、まず、

$edit_id = $request->edit_id;
$edit_memo = $request->edit_memo;

この部分でフォームから取得した、メモのidと編集後のメモ内容を取得し、それぞれ「$edit_id」「$edit_memo」という変数に格納しています。

続いて、Memo::where('id', $edit_id)->update(['content' => $edit_memo]);この部分についてです。

whereメソッドは、SQLのWHERE句のことです。第一引数にカラム名、第二引数に値を設定することで絞り込むことができます。

今回はwhere('id', $edit_id)になっているので、idが$edit_idのレコードを絞り込んでいます。

その後、updataメソッドで、カラムを上書きしています。

updateメソッドは、引数に連想配列でデータを渡すことで、対象のカラムを上書きできます。

updata(
   [
      'カラム名' => '上書きしたいデータ',
      'カラム名2' => '上書きしたいデータ2',
   ]
)

今回は、contentというカラムを上書きしたいのでupdataメソッドの引数は['content' => $edit_memo]にしています。

今回はupdateメソッドを使用していますが、データの更新にsaveメソッドを用いることもできます。

12saveメソッドの使い方と違い

saveメソッドは、既存のモデルインスタンスを使用してデータベースのレコードを更新します。

モデルの属性を手動で変更した後、saveメソッドを呼び出すことで、その変更がデータベースに保存されます。

$memo = Memo::find($edit_id); // 変更するレコードを取得

$memo->content = $edit_memo; // 変更後のメモの内容

$memo->save(); // 変更内容を保存

どちらでも更新することができますが、まとめて上書きする場合などはupdateメソッドの方が便利なので、使い分けには注意が必要です。

これで上書き処理も実装することができました。

では画面を再読み込みし、メモを編集してみましょう。

メモを編集

無事に編集されましたね!「サンプルテキスト」が「サンプルテキスト【編集後】」に上書きされています。

これでメモ帳の完成です! お疲れ様でした。

最後にコントローラの全体を下記に記述しておきます。

エラー等が出ている場合は見比べてみてください。

<?php

namespace App\\Http\\Controllers;

use App\\Models\\Memo;
use Illuminate\\Http\\Request;

class MemoController extends Controller
{
    /**
     * 画面を表示
     * @return View
     */
    public function show()
    {
        $memo_info = Memo::get();

        return view('home')
            ->with('memo_info', $memo_info);
    }

    /**
     * メモ追加処理
     * @param Request $request
     * @return View
     */
    public function add(Request $request)
    {
        $memo_text = $request->memo_text;
        $memo_model = new Memo();
        $memo_model->content = $memo_text;
        $memo_model->save();

        return self::show();

    }

    /**
     * 削除処理
     * @param Request $request
     * @return View
     */
    public function delete(Request $request)
    {
        $delete_id = $request->delete_id;

        $memo_model = Memo::find($delete_id);
        $memo_model->delete();

        return self::show();
    }

    /**
     * 編集ページに遷移
     * @param $edit_id
     * @return View
     */
    public function getEdit($edit_id)
    {
        $memo_info = Memo::find($edit_id);

        return view('edit')
            ->with('memo_info', $memo_info);
    }

    /**
     * 編集処理
     * @param Request $request
     * @return View
     */
    public function postEdit(Request $request)
    {
        $edit_id = $request->edit_id;
        $edit_memo = $request->edit_memo;

        Memo::where('id', $edit_id)->update(['content' => $edit_memo]);

        return self::show();
    }

}

追加・削除・更新一通りの処理が学べたかなと思います。次からはより応用の認証機能(ログイン機能)や1対多・多対多やバリデーションについて学んでいきます。

Gitcd ディレクトリまでのパス

ここまでの変更点をコミットします。

git add .

git commit -m "メモ帳の作"

git init

また、現在の状態を保存しておくためにも、リモートリポジトリにソースコードを反映させましょう。

リモートリポジトリの作成方法とpushの方法は、Gitの教材を参考にしてください。

13課題

作成したメモ帳に追記機能を2つ実装してみよう。

  1. 検索機能の実装
  2. 自分で考えた追加機能

1つめの検索機能ですが、仕様は以下の通りです。

メモを追加のフォーム直下に画像のような検索ボックスを追加してください。

HTMLは以下の通りです。

<div class="memo_form">
     <h2>メモを追加</h2>
     <form action="{{ asset('/add') }}" method="post">
         @csrf
         <input class="memo_text" type="text" name="memo_text" id="memo_text">
         <input type="submit" value="追加">
     </form>
		 <!-- ここから追加  -->
     <div class="search_area" style="margin-top: 50px">
         <h2>検索</h2>
         <form action="">
            <input class="memo_text" type="text" name="search_word" id="search_word">
            <input type="submit" value="検索">
         </form>
     </div>
   <!-- ここまでを追加  -->
</div>

HTMLの構造は追加しましたが、アクション属性などは自分で追記してください。

検索ボックスに検索ワードを入れ検索ボタンをクリックすると、検索ワードが含まれるメモのみが表示されるようにしてください。

例)

「検索ワード:りんご」

メモ内容表示判定
りんご表示される
りんごアイス表示される
ぶどう表示されない
青りんご表示される
りん表示されない

上記のように、「りんご」が含まれるメモのみ表示されるようにしてください。

  • 自分で考えた機能を追加してみよう。

並び替え機能や一括削除機能など自分なりに考えた機能を実装してみよう。

※適宜、コミットやプッシュをしてソースコードを管理してください。簡単に元の状態に戻れるように、作業用のブランチを作成することもおすすめです。


投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です