Laravel入門 - 使い方チュートリアル - - Qiita (2023)

Laravelの使い方をチュートリアル形式でまとめています。
バージョンは5.7です。
解説をしながら、CRUD処理(登録、取得、更新、削除)を実装していきます。

DockerでLaravel環境を構築するにはこちら。
Dockerを使って1コマンドで起動できるLaravel開発環境を構築する

Laravelのインストール

Laravelのインストールには様々な方法がありますが、ここではComposerを使用します。

Composerについてはこちら

create-projectコマンドを使用することで、インストールと同時にプロジェクトを作成することができます。

% composer create-project laravel/laravel sample

sampleというディレクトリが作成されるので、ディレクトリを移動しましょう。

% cd sample

以降はsampleディレクトリで作業をしていきます。

Laravelプロジェクトのディレクトリ構成

Laravelプロジェクトを作成すると、以下のようなディレクトリを構成します。

─── sample ├── app ・・・アプリケーションのロジック ├── bootstrap ・・・laravelフレームワークの起動コード ├── config ・・・設定ファイル ├── database ・・・MigrationファイルなどDB関連 ├── public ・・・Webサーバのドキュメントルート ├── resources ・・・ビューや言語変換用ファイルなど ├── routes ・・・ルーティング用ファイル ├── storage ・・・フレームワークが使用するファイル ├── tests ・・・テストコード └── vendor ・・・Composerでインストールしたライブラリ

Laravelのバージョンによって構成が異なる場合があります。

この構成に従ってWebアプリケーションを作っていくことになります。
いくつか重要なファイルがあるので、実際に使用する前に簡単に紹介します。

.envファイル

sampleディレクトリ直下に「.env」というファイルがあります。
アプリケーションの環境設定情報を記述するファイルです。
具体的には暗号化キーやデータベースの接続情報を記述します。

GitHubなどPublicなリポジトリを利用される場合は扱いに注意しましょう。

artisanファイル

sampleディレクトリ直下に「artisan」というファイルがあります。
artisanファイルはLaravelのコマンドラインツールであるArtisanの実行ファイルです。
LaravelではArtisanコマンドを使用して様々な操作を行います。
主なものを紹介します。

serveコマンド

PHPの組み込みサーバーでLaravelプロジェクトを動作させます。

% php artisan serve --host=localhost --port=8000Laravel development server started: <http://localhost:8000>

--hostオプションと--portオプションは省略できます。

route:listコマンド

ルーティング定義の一覧を表示します。

% php artisan route:list+--------+----------+----------+------+---------+--------------+| Domain | Method | URI | Name | Action | Middleware |+--------+----------+----------+------+---------+--------------+| | GET|HEAD | / | | Closure | web || | GET|HEAD | api/user | | Closure | api,auth:api |+--------+----------+----------+------+---------+--------------+

例えば1行目は、ルート(http://localhost:8000 )でGETリクエストを受け付けていることを表しています。
詳しくは後ほど使いながら見てみましょう。

tinkerコマンド

プロジェクトをREPL(Read Eval Print Loop)で起動します。
REPLとは、打ち込んだコードが即時に結果を返してくれる仕組みのことを言います。

% php artisan tinkerPsy Shell v0.9.9 (PHP 7.1.16 — cli) by Justin Hileman>>> $name = 'Laravel';=> "Laravel">>> echo 'Hello ' . $name;Hello Laravel⏎>>>

プロジェクト内のオブジェクトがどんなメソッドを持っていたかなど簡単に確認できます。
tinkerはデバッグ時に力を発揮します。「ビューの作成」の章で説明します。

データベース設定

Laravelプロジェクトを作成したら、まずデータベースの設定をします。
最初は以下の作業が必要になります。

  • 接続設定
  • マイグレーション
  • モデル作成
  • シーディング

接続設定

データベースへの接続情報は.envファイルに記述します。
初期値では以下のようになっています。自身の環境に合わせて設定してください。

DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=homesteadDB_USERNAME=homesteadDB_PASSWORD=secret

上記の場合、ローカルにMySQLをインストールし、homesteadデータベースを作成、homeseteadというユーザーをsecretというパスワードで作成すればOKです。

マイグレーション

マイグレーションとは、テーブルの作成や編集などをSQLによって行うのではなく、PHPのソースで管理する仕組みです。
次の手順で行います。

  1. マイグレーションファイルの作成
  2. マイグレーションの実行

1.マイグレーションファイルの作成

マイグレーションファイルの作成にはArtisanのmake:migrationコマンドを使用します。
ファイル名は何でも構いませんが、どのような操作を行ったのかわかる名前をつけると良いでしょう。
Booksテーブルを作成するマイグレーションファイルを作成します。

% php artisan make:migration create_books_table --create=booksCreated Migration: 2018_10_30_085034_create_books_table

マイグレーションファイルはdatabase/migrationsディレクトリに作成されます。

database/migrations/2018_10_30_085034_create_books_table.php

<?phpuse Illuminate\Support\Facades\Schema;use Illuminate\Database\Schema\Blueprint;use Illuminate\Database\Migrations\Migration;class CreateBooksTable extends Migration{ /** * Run the migrations. * * @return void */ public function up() { Schema::create('books', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('books'); }}

マイグレーションファイルではupメソッドにテーブル作成時の情報、downメソッドにマイグレーションを取り消す際の情報を記述します。
現在の内容は、列IDとタイムスタンプを持つBooksテーブルを作成、取り消し時はBooksテーブルを削除するという内容になっています。
以下のようなテーブルを作成したいとしましょう。

制約
idAUTO_INCREMENTPRIMARY KEY
nameVARCHAR(50)NOT NULL
priceINTNOT NULL
authorVARCHAR(50)
created_attimestamp
updated_attimestamp

この場合、upメソッドを以下のように書き換えます。

database/migrations/2018_10_30_085034_create_books_table.php

public function up(){ Schema::create('books', function (Blueprint $table) { $table->increments('id'); $table->string('name', 50); $table->integer('price'); $table->string('author', 50)->nullable(); $table->timestamps(); });}

この記述方法はスキーマビルダと呼ばれています。
詳細は公式ドキュメントを参考にしてください。
https://readouble.com/laravel/5.0/ja/schema.html

これでマイグレーションファイルの作成が完了しました。

usersとpassword_resetsのマイグレーションファイルはプロジェクト作成時に自動的に作成されたものです。今回は無視します。

2.マイグレーションの実行

マイグレーションの実行にはArtisanのmigrateコマンドを実行します。

(Video) 【Laravelチュートリアル決定版】初心者でも作れるノートアプリを現役Laravelエンジニアが解説

% php artisan migrateMigrating: 2018_10_30_085034_create_books_tableMigrated: 2018_10_30_085034_create_books_table

これで、MySQLサーバー上にテーブルが作成されます。

MySQL

mysql> show tables;+-------------------+| Tables_in_laravel |+-------------------+| books || migrations |+-------------------+2 rows in set (0.00 sec)

booksテーブルが指定された通りに作成されているか確認しましょう。

MySQL

mysql> desc books;+------------+------------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+------------+------------------+------+-----+---------+----------------+| id | int(10) unsigned | NO | PRI | NULL | auto_increment || name | varchar(50) | NO | | NULL | || price | int(11) | NO | | NULL | || author | varchar(50) | YES | | NULL | || created_at | timestamp | YES | | NULL | || updated_at | timestamp | YES | | NULL | |+------------+------------------+------+-----+---------+----------------+6 rows in set (0.01 sec)

migrationsテーブルにはマイグレーションの情報が保存されます。

マイグレーションを取り消したい場合はmigrate:rollbackコマンド、またはmigrate:resetコマンドを使用します。
migrate:rollbackコマンドは直前のマイグレーションのみ取り消します。

% php artisan migrate:rollbackRolling back: 2018_10_30_085034_create_books_tableRolled back: 2018_10_30_085034_create_books_table

migrate:resetは全てのマイグレーションを取り消します。

% php artisan migrate:resetRolling back: 2018_10_30_085034_create_books_tableRolled back: 2018_10_30_085034_create_books_table

モデルの作成

モデルはテーブルとマッピングされたオブジェクトです。
DB操作を行うためのクラスになります。
詳しくは「Eloquent ORM」の章で説明します。
モデルはArtisanのmake:modelコマンドで作成します。

% php artisan make:model BookModel created successfully.

モデルはApp直下に作成されます。

App/Book.php

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Book extends Model{ //}

中身は空ですが、このままで構いません。

モデルの命名規則

モデルは命名規則によってテーブルとマッピングされます。
テーブル名の単数形を名前につけることで、自動的にそのテーブルとマッピングします。

シーディング

シーディングはテストデータやマスタデータなどのアプリケーション起動時に必要なレコードをコマンドで登録する仕組みです。
次の手順で実行します。

  1. シーダーファイルの作成
  2. シーディングの実行

1.シーダーファイルの作成

シーダーファイルはArtisanのmake:seederコマンドを使用して作成します。

% php artisan make:seeder BooksTableSeederSeeder created successfully.

database/seedsディレクトリにBooksTableSeeder.phpが作成されます。

database/seeds/BooksTableSeeder.php

<?phpuse Illuminate\Database\Seeder;class BooksTableSeeder extends Seeder{ /** * Run the database seeds. * * @return void */ public function run() { // }}

Booksテーブルに以下のレコードを登録したいとしましょう。

IDNAMEPRICEAUTHORCREATED_ATUPDATED_AT
1PHP Book2000PHPER現在時刻現在時刻
2Laravel Book3000NULL現在時刻現在時刻
3Ruby Book2500Rubyist現在時刻現在時刻

その場合は、シーダーファイルのrunメソッドを以下のように修正します。

database/seeds/BooksTableSeeder.php

public function run(){ // テーブルのクリア DB::table('books')->truncate(); // 初期データ用意(列名をキーとする連想配列) $books = [ ['name' => 'PHP Book', 'price' => 2000, 'author' => 'PHPER'], ['name' => 'Laravel Book', 'price' => 3000, 'author' => null], ['name' => 'Ruby Book', 'price' => 2500, 'author' => 'Rubyist'] ]; // 登録 foreach($books as $book) { \App\Book::create($book); }}

さらにDatabaseSeeder.phpのrunメソッドを以下のように修正します。runメソッド内でcallしたクラスが、シーディングコマンドで実行されるようになります。

database/seeds/DatabaseSeeder.php

public function run(){ // BooksTableSeederを読み込むように指定 $this->call(BooksTableSeeder::class);}

2.シーディングの実行

シーディングを実行するにはArtisanのdb:seedコマンドを実行します。

% php artisan db:seedSeeding: BooksTableSeederDatabase seeding completed successfully.

完了したらテーブルを確認しましょう。

MySQL

mysql> select * from books;+----+--------------+-------+---------+---------------------+---------------------+| id | name | price | author | created_at | updated_at |+----+--------------+-------+---------+---------------------+---------------------+| 1 | PHP Book | 2000 | PHPER | 2018-10-30 10:11:33 | 2018-10-30 10:11:33 || 2 | Laravel Book | 3000 | NULL | 2018-10-30 10:11:33 | 2018-10-30 10:11:33 || 3 | Ruby Book | 2500 | Rubyist | 2018-10-30 10:11:33 | 2018-10-30 10:11:33 |+----+--------------+-------+---------+---------------------+---------------------+3 rows in set (0.00 sec)

以上でデータベース関連の設定は完了です。
作業量が多かったかもしれませんが一度作ってしまえば、プロジェクトを共有しているユーザー全てがmigratedb:seedの2つのコマンドのみで、DBの初期化を行うことができます。

ルーティング

データベースの準備が整ったらアプリケーションを作成します。
まずはルーティングから行なっていきましょう。
ルーティングとは、クライアントからのリクエストを受け付け、その内容によって処理を振り分けることです。
ルーティング情報はroutes/web.phpファイルに記述します。

routes/web.php

(Video) 【Laravel入門・準備編】LaravelインストールとComposer #01

<?phpRoute::get('/', function () { return view('welcome');});

すでに一つルーティングが定義されています。
これは、ルート(/)にGETリクエストがきた場合に、welcomeというビューをレスポンスとして返すという意味です。
welcomeはresources/views/welcome.blade.phpのことです。

Laravelはview関数を呼び出すと、resources/views/ディレクトリを探しにいきます。
その中からファイル名(拡張子除く)が一致するものを返す仕組みとなっています。

Artisanコマンドでサーバーを立ち上げ、http://localhost:8000/ にアクセスしてみるとwelcome.blade.phpの内容が表示されます。

直接ビューを返すのではなく、コントローラを経由するようにルーティングするには以下のように記述します。

routes/web.php

<?phpRoute::get('book', 'BookController@index');

上記のように記述した場合、「localhost:8000/bookにGETリクエストがきたら、BookControllerのindexメソッドに処理を振り分けて」という意味になります。この段階ではまだBookControllerを作成していないので正常に動作しません。

BookControllerは「Controllerの作成」の章で作成します。

ルートパラメータ

コントローラを作る前にルートパラメータについても知っておきましょう。

routes/web.php

<?phpRoute::get('book/{id}', 'BookController@show');

上記のように記述した場合、「localhost:8000/book/1にGETリクエストがきたら、BookControllerのshowメソッドに処理を振り分けて」という意味になります。
BookControllerではshowメソッドに引数を持たせるようにします。

app/Http/Controllers/BookController.php(未作成)

public function show($id){ return view('book', ['book' => Book::findOrFail($id)]);}

URIに指定された「1」という数字が$idという引数の中に代入されます。

Restfulリソースコントローラ

Route::resourceメソッドを使用することで、Restfulなルーティングを行うことができます。

routes/web.php

<?phpRoute::resource('book', 'BookController');

この場合、以下のようにルーティングされます。

リクエストメソッドURIコントローラーCRUD画面を作る際の主な用途
GET/bookBookController@index一覧画面の表示
GET/book/{book}BookController@show詳細画面の表示
GET/book/createBookController@create登録画面の表示
POST/bookBookController@store登録処理
GET/book/{book}/editBookController@edit編集画面の表示
PUT/book/{book}BookController@update編集処理
DELETE/book/{book}BookController@destroy削除処理

以降、resourceメソッドでルーティングしている前提でコントローラを作成します。

コントローラの作成

ルーティングを設定したら次はコントローラを作成します。
コントローラはルーティングされてきたリクエストを受け取り、レスポンスを作成する役割を果たします。
レスポンスとしてHTMLを返す場合はViewに処理を依頼します。
コントローラの作成にはArtisanのmake:controllerコマンドを使用します。

% php artisan make:controller BookControllerController created successfully.

コントローラはapp/Http/Controllersディレクトリに作成されます。
以下のようにindexメソッドとeditメソッドを追加してください。
use App/Bookの記述を忘れないようにしてください。

app/Http/Controllers/BookController.php

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;use App\Http\Controllers\Controller;use App\Book;class BookController extends Controller{ public function index() { // DBよりBookテーブルの値を全て取得 $books = Book::all(); // 取得した値をビュー「book/index」に渡す return view('book/index', compact('books')); } public function edit($id) { // DBよりURIパラメータと同じIDを持つBookの情報を取得 $book = Book::findOrFail($id); // 取得した値をビュー「book/edit」に渡す return view('book/edit', compact('book')); }}

コントローラのメソッドでビューを返したい場合、view関数を使用します。
view関数は第一引数にビューの名前、第二引数にビューに渡したい値を設定します。
第二引数は連想配列で渡すようにします。
compact関数を使うことで簡単に連想配列を渡すことができます。
例えば、edit関数のcompact('book')['book' => $book]としているのと同意です。

ルーティングされているメソッドのうち、とりあえずindexメソッドとeditメソッドを用意しました。
DBからの値取得はEloquentという仕組みを利用しています。
Eloquentに関しては「Eloquent ORM」の章で説明します。

ビューの作成

では最後にビューを作成しましょう。
ビューはresources/viewsディレクトリに作成します。
bookディレクトリを作成し、その中にindex.blade.phpを作成しましょう。

resources/views/book/index.blade.php

<head> <title>Laravel Sample</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></head><div class="container ops-main"><div class="row"> <div class="col-md-12"> <h3 class="ops-title">書籍一覧</h3> </div></div><div class="row"> <div class="col-md-11 col-md-offset-1"> <table class="table text-center"> <tr> <th class="text-center">ID</th> <th class="text-center">書籍名</th> <th class="text-center">価格</th> <th class="text-center">著者</th> <th class="text-center">削除</th> </tr> @foreach($books as $book) <tr> <td> <a href="/book/{{ $book->id }}/edit">{{ $book->id }}</a> </td> <td>{{ $book->name }}</td> <td>{{ $book->price }}</td> <td>{{ $book->author }}</td> <td> <form action="/book/{{ $book->id }}" method="post"> <input type="hidden" name="_method" value="DELETE"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <button type="submit" class="btn btn-xs btn-danger" aria-label="Left Align"><span class="glyphicon glyphicon-trash"></span></button> </form> </td> </tr> @endforeach </table> <div><a href="/book/create" class="btn btn-default">新規作成</a></div> </div></div>

Laravelではビューの作成にBladeというテンプレートエンジンを用いています。
Bladeでは{{ $variables }}とすることで、コントローラから受け取った値を画面に出力することができます。
また@foreach($array as $elem)@if($bool)と記述することで制御構文を使用することもできます。
その場合、制御構文の終端は@endforeach@endifと記述します。

Bladeの詳細に関しては以下のサイトで確認してください。
https://readouble.com/laravel/5.7/ja/blade.html

ここまで完成したら、Artisanでサーバーを立ち上げ、http://localhost:8000/book にアクセスしてみましょう。
一覧画面が表示されるはずです。

ここで一度流れを整理しておきましょう。
route:listコマンドでルーティングを再確認します。

% php artisan route:list+--------+-----------+------------------+--------------+---------------------------------------------+--------------+| Domain | Method | URI | Name | Action | Middleware |+--------+-----------+------------------+--------------+---------------------------------------------+--------------+| | GET|HEAD | / | | Closure | web || | GET|HEAD | api/user | | Closure | api,auth:api || | GET|HEAD | book | book.index | App\Http\Controllers\BookController@index | web || | POST | book | book.store | App\Http\Controllers\BookController@store | web || | GET|HEAD | book/create | book.create | App\Http\Controllers\BookController@create | web || | GET|HEAD | book/{book} | book.show | App\Http\Controllers\BookController@show | web || | PUT|PATCH | book/{book} | book.update | App\Http\Controllers\BookController@update | web || | DELETE | book/{book} | book.destroy | App\Http\Controllers\BookController@destroy | web || | GET|HEAD | book/{book}/edit | book.edit | App\Http\Controllers\BookController@edit | web |+--------+-----------+------------------+--------------+---------------------------------------------+--------------+

今、ブラウザからhttp://localhost:8000/book にアクセスしました。
つまりGETリクエストでbookにアクセスしたことになります。
その場合、BookControllerのindexメソッドが呼び出されるように設定されていました。

+--------+-----------+------------------+--------------+---------------------------------------------+--------------+| Domain | Method | URI | Name | Action | Middleware |+--------+-----------+------------------+--------------+---------------------------------------------+--------------+| | GET|HEAD | book | book.index | App\Http\Controllers\BookController@index | web |+--------+-----------+------------------+--------------+---------------------------------------------+--------------+

そのため、BookControllerのindexメソッドが呼び出されます。
indexメソッドでは、書籍の一覧情報を取得し、resources/views/book/index.blade.phpに渡しました。

app/Http/Controllers/BookController.php

public function index(){ // DBよりBookテーブルの値を全て取得 $books = Book::all(); // 取得した値をビュー「book/index」に渡す return view('book/index', compact('books'));}

最後にindex.blade.phpでは受け取った値を元に画面を生成し、それが最終的にブラウザに表示されたというわけです。

では、次にedit.blade.phpを作成しましょう。今の流れを意識しながら作成してください。

(Video) 【Laravel入門】初心者が学ぶ手順を現役PHPエンジニアが解説!本から学ばず最低限必要な機能から学んでいこう!

resources/views/edit.blade.php

<head> <title>Laravel Sample</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></head><div class="container ops-main"> <div class="row"> <div class="col-md-6"> <h2>書籍登録</h2> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-1"> <form action="/book/{{ $book->id }}" method="post"> <!-- updateメソッドにはPUTメソッドがルーティングされているのでPUTにする --> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label for="name">書籍名</label> <input type="text" class="form-control" name="name" value="{{ $book->name }}"> </div> <div class="form-group"> <label for="price">価格</label> <input type="text" class="form-control" name="price" value="{{ $book->price }}"> </div> <div class="form-group"> <label for="author">著者</label> <input type="text" class="form-control" name="author" value="{{ $book->author }}"> </div> <button type="submit" class="btn btn-default">登録</button> <a href="/book">戻る</a> </form> </div> </div></div>

これで編集画面が作成できました。書籍一覧のIDをクリックすると、編集画面に遷移します。

ビューの継承

ところで、ヘッダー部分は書籍一覧画面と書籍登録画面で同じですね。
こういう時、ビューの継承を利用すると効率的に作成することができます。
親ビューになるlayout.blade.phpを作成します。共通となる要素のみ記述します。

views/book/layout.blade.php

<head> <title>Laravel Sample</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></head>@yield('content')

次にindex.blade.phpを書き換えます。

@extends('book/layout')@section('content')<div class="container ops-main"><div class="row"> <div class="col-md-12"> <h3 class="ops-title">Books</h3> </div></div><div class="row"> <!-- 中略 --></div>@endsection

共通要素を消去し、代わりに@extends('book/layout')を記述します。
これで、layout.blade.phpを継承することを宣言したことになります。
すると、layoutの@yield('content')部分に@section('content')@endsectionで囲った部分が挿入されます。
では、edit.blade.phpにもlayoutを継承させましょう。

@extends('book/layout')@section('content')<div class="container ops-main"> <div class="row"> <div class="col-md-6"> <h2>書籍登録</h2> </div> </div> <!-- 中略 --></div>@endsection

共通のCSSの読み込みや、フッター、ヘッダーなどをlayout.blade.phpに記入することで、継承している全ての画面に反映させることができます。
次はDB操作の処理を実装していくことになりますが、その前にEloquentについて学びましょう。

Eloquent ORM

EloquentはLaravelでデータ操作をするための実装です。
Bookモデルというのを作成したのを思い出してください。
BookモデルはBookテーブルにマッピングされており、テーブルの登録や取得更新などの操作を持っています。
Bookモデルとした場合、特に指定しなければ命名規則によりbooksテーブルとマッピングされます。

レコードの取得

モデルにマッピングされたテーブルの全てのレコードを取得するにはallメソッドを利用します。
tinkerを立ち上げてDB操作してみましょう。
use \App\Book;を忘れないようにしてください。

% php artisan tinkerPsy Shell v0.9.9 (PHP 7.1.16  cli) by Justin Hileman>>> use \App\Book;>>> $books = Book::all();=> Illuminate\Database\Eloquent\Collection {#2925 all: [ App\Book {#2926 id: 1, name: "PHP Book", price: 2000, author: "PHPER", created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }, App\Book {#2927 id: 2, name: "Laravel Book", price: 3000, author: null, created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }, App\Book {#2928 id: 3, name: "Ruby Book", price: 2500, author: "Rubyist", created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }, ], }>>>

countメソッドやforeachを利用することができます。

>>> $books->count();=> 3

取得条件の設定

取得レコードに条件を設定する場合はwhereメソッドを使います。

>>> $expensiveBooks = Book::where('price', '>=', 2500)->get();=> Illuminate\Database\Eloquent\Collection {#2931 all: [ App\Book {#2903 id: 2, name: "Laravel Book", price: 3000, author: null, created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }, App\Book {#2929 id: 3, name: "Ruby Book", price: 2500, author: "Rubyist", created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }, ], }>>>

単一行の取得であれば、findメソッドを使うことで効率的に記述できます。
findメソッドは主キーによる検索を行います。

>>> $book = Book::find(2);=> App\Book {#2923 id: 2, name: "Laravel Book", price: 3000, author: null, created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }>>>

レコードの登録

登録するにはモデルのインスタンスを作成し、saveメソッドを呼び出します。

>>> $newBook = new Book();=> App\Book {#2934}>>> $newBook->name = 'Python Book';=> "Python Book">>> $newBook->price = 3500;=> 3500>>> $newBook->save();=> true>>> $pythonBook = Book::find(4);=> App\Book {#2932 id: 4, name: "Python Book", price: 3500, author: null, created_at: "2018-10-31 01:51:38", updated_at: "2018-10-31 01:51:38", }

レコードの更新

更新はモデルを取得後、プロパティを変更してsaveメソッドを呼び出します。

>>> $pythonBook;=> App\Book {#2932 id: 4, name: "Python Book", price: 3500, author: null, created_at: "2018-10-31 01:51:38", updated_at: "2018-10-31 01:51:38", }>>> $pythonBook->author = 'Pythonista';=> "Pythonista">>> $pythonBook->save();=> true>>> $pythonBook = Book::find(4);=> App\Book {#2910 id: 4, name: "Python Book", price: 3500, author: "Pythonista", created_at: "2018-10-31 01:51:38", updated_at: "2018-10-31 01:54:45", }>>>

複数件の更新も可能です。

>>> Book::where('price', '>=', 2500)->update(['price' => 2500]);=> 3>>> Book::all();=> Illuminate\Database\Eloquent\Collection {#2912 all: [ App\Book {#2908 id: 1, name: "PHP Book", price: 2000, author: "PHPER", created_at: "2018-10-30 10:33:14", updated_at: "2018-10-30 10:33:14", }, App\Book {#2937 id: 2, name: "Laravel Book", price: 2500, author: null, created_at: "2018-10-30 10:33:14", updated_at: "2018-10-31 01:57:27", }, App\Book {#2935 id: 3, name: "Ruby Book", price: 2500, author: "Rubyist", created_at: "2018-10-30 10:33:14", updated_at: "2018-10-31 01:57:27", }, App\Book {#2932 id: 4, name: "Python Book", price: 2500, author: "Pythonista", created_at: "2018-10-31 01:51:38", updated_at: "2018-10-31 01:57:27", }, ], }>>>

レコードの削除

削除にはdeleteメソッドを使います。

>>> $pythonBook;=> App\Book {#2910 id: 4, name: "Python Book", price: 3500, author: "Pythonista", created_at: "2018-10-31 01:51:38", updated_at: "2018-10-31 01:54:45", }>>> $pythonBook->delete();=> true>>> $pythonBook = Book::find(4);=> null>>>

CRUD機能の実装

では、残していた更新、登録、削除の機能を実装していきましょう。
まずは、更新を作成します。

更新処理

編集画面はできているので、コントローラにupdateメソッドを定義します。

app/Http/Controllers/BookController.php

public function update(Request $request, $id){ $book = Book::findOrFail($id); $book->name = $request->name; $book->price = $request->price; $book->author = $request->author; $book->save(); return redirect("/book");}

updateメソッドの$idにはURIbook/{book}の{book}の部分の値が代入されます。
つまり、http://localhost:8000/book/3 にPUTメソッドでアクセスしたら、updateメソッドが呼び出され、$idに3が代入されます。
$requestはクライアントからのリクエスト情報が入っています。
クライアントが入力した値を取得する場合は$request->[要素名]で取得します。

削除処理

書籍一覧画面にすでに削除ボタンは作成しているので、コントローラにdestroyメソッドを定義します。

app/Http/Controllers/BookController.php

public function destroy($id){ $book = Book::findOrFail($id); $book->delete(); return redirect("/book");}

登録処理

最後に登録処理ですが、画面はedit.blade.phpとほぼ同じなので再利用するようにしましょう。
まずviews/bookディレクトリに共通部分を記述するform.blade.phpを作成します。
edit.blade.phpの@section内部を全て移動させます。

resources/views/book/form.blade.php

<div class="container ops-main"> <div class="row"> <div class="col-md-6"> <h2>書籍登録</h2> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-1"> <form action="/book/{{ $book->id }}" method="post"> <!-- updateメソッドにはPUTメソッドがルーティングされているのでPUTにする --> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label for="name">書籍名</label> <input type="text" class="form-control" name="name" value="{{ $book->name }}"> </div> <div class="form-group"> <label for="price">価格</label> <input type="text" class="form-control" name="price" value="{{ $book->price }}"> </div> <div class="form-group"> <label for="author">著者</label> <input type="text" class="form-control" name="author" value="{{ $book->author }}"> </div> <button type="submit" class="btn btn-default">登録</button> <a href="/book">戻る</a> </form> </div> </div></div>
(Video) 【laravel入門】コントローラーの基本を実践解説!役割と正しい書き方を現役Laravelエンジニアが解説

次に新規登録時と更新時で異なる部分だけ@ifを使用して分岐させます。
今回の場合、formタグ部分だけ書き換えればOKです。

resources/views/book/form.blade.php

<div class="container ops-main"> <div class="row"> <div class="col-md-6"> <h2>書籍登録</h2> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-1"> @if($target == 'store') <form action="/book" method="post"> @elseif($target == 'update') <form action="/book/{{ $book->id }}" method="post"> <input type="hidden" name="_method" value="PUT"> @endif <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label for="name">書籍名</label> <input type="text" class="form-control" name="name" value="{{ $book->name }}"> </div> <div class="form-group"> <label for="price">価格</label> <input type="text" class="form-control" name="price" value="{{ $book->price }}"> </div> <div class="form-group"> <label for="author">著者</label> <input type="text" class="form-control" name="author" value="{{ $book->author }}"> </div> <button type="submit" class="btn btn-default">登録</button> <a href="/book">戻る</a> </form> </div> </div></div>

次はedit.blade.phpを以下のように書き換えます。

resources/views/book/edit.blade.php

@extends('book/layout')@section('content')@include('book/form', ['target' => 'update'])@endsection

@includeを使用して、form.blade.phpを@section内に挿入します。
その際、target変数にupdateという値を渡します。

では、新しくviews/book/ディレクトリにcreate.blade.phpを作成しましょう。

resources/views/book/create.blade.php

@extends('book/layout')@section('content')@include('book/form', ['target' => 'store'])@endsection

targetをstoreに書き換えるだけです。
これで、新規登録の時と編集の時で、formの内容が分岐される仕組みができます。
登録時のコントローラが未作成ですのでcreateメソッドとstoreメソッドを追加しましょう。

app/Http/Controllers/BookController.php

public function create(){ // 空の$bookを渡す $book = new Book(); return view('book/create', compact('book'));}public function store(Request $request){ $book = new Book(); $book->name = $request->name; $book->price = $request->price; $book->author = $request->author; $book->save(); return redirect("/book");}

create.blade.phpでは$bookを受け取るようになっています。
そこで、createメソッドでは空のインスタンスを渡すようにします。
画面には空の状態で出力されるようになります。

変数を渡さないとUndefined Variableエラーになってしまいます。

以上でCRUD処理全てが実装できました。
ルーティングと流れを意識しながら色々動かして見てください。

バリデーション

最後にバリデーションを作成しましょう。
バリデーションとは入力内容のチェックのことです。
いくつか方法がありますが、フォームリクエストを作成する方法を紹介します。
フォームリクエストを作成するにはArtisanのmake:requestを使用します。

% php artisan make:request BookRequestRequest created successfully.

app/Http/Requestsディレクトリが作成され、そこにBookRequest.phpが作成されます。
BookRequest.phpのrulesメソッドを以下のように修正します。

app/Http/Requests/BookRequest.php

<?phpnamespace App\Http\Requests;use Illuminate\Foundation\Http\FormRequest;class BookRequest extends FormRequest{ public function rules() { return [ 'name' => 'required|string|max:50', 'price' => 'required|integer', 'author' => 'nullable|string|max:50', ]; }}

連想配列の値のはバリデーションルールを記述します。

名前ルール
required必須入力
string文字列のみ
max:5050文字以下
integer数値のみ
nullable空もOK

バリデーションルールの詳細に関しては公式サイトを参考にしてください。
https://readouble.com/laravel/5.7/ja/validation.html

次にBookController.phpのstoreメソッドとupdateメソッドの引数の型指定をRequestからBookRequestに書き換えます。
use App\Http\Requests\BookRequest;を忘れないようにしてください。

app/Http/Contorllers/BookController.php

<?phpnamespace App\Http\Controllers;use App\Http\Controllers\Controller;use App\Http\Requests\BookRequest;use App\Book;class BookController extends Controller{ // 中略 public function store(BookRequest $request) { $book = new Book(); $book->name = $request->name; $book->price = $request->price; $book->author = $request->author; $book->save(); return redirect("/book"); } public function update(BookRequest $request, $id) { $book = Book::findOrFail($id); $book->name = $request->name; $book->price = $request->price; $book->author = $request->author; $book->save(); return redirect("/book"); } // 中略}

これで書籍名を空にしたまま登録や編集しようとすると、同じ画面にリダイレクトするようになります。
このままでは何が起きているのかわからないので、エラーメッセージを表示するようにしましょう。
views/bookディレクトリにmessage.blade.phpを作成します。

<div class="row"> <div class="col-md-12"> @if ($errors->any()) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif </div></div>

これをform.blade.phpに挿入します。

<div class="container ops-main"> <div class="row"> <div class="col-md-6"> <h2>書籍登録</h2> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-1"> @include('book/message') <!-- 中略 --> </div> </div></div>

これでエラーメッセージが表示されるようになります。

以上でCRUD機能を持つWebアプリケーションが完成しました。
以降は認証機能などを追加するとさらに理解が深まると思います。
最後に補足としてPsyによるデバッグの方法を載せておきます。

(補足)Psyによるデバッグ

Psyを使用して効率的にデバッグすることができます。
BookControllerのeditメソッドを以下のように書き換えてみましょう。

public function edit($id){ // DBよりURIパラメータと同じIDを持つBookの情報を取得 $book = Book::findOrFail($id); // tinkerによるデバッグ eval(\Psy\sh()); // 取得した値をView「book/edit」に渡す return view('book/edit', compact('book'));}

サーバーを起動して、書籍編集画面にアクセスしてみましょう。
コンソールを見てみると処理がeval(\Psy\sh());を記述した箇所で処理が停止しています。

sy Shell v0.9.9 (PHP 7.1.16 — cli-server) by Justin Hileman 23| 24| // tinkerによるデバッグ > 25| eval(\Psy\sh()); 26| 27| // 取得した値をView「book/edit」に渡す

この状態でecho $book;とタイプすると$book変数の中身が表示されます。

echo $book;{"id":1,"name":"PHP Book","price":2000,"author":"PHPER","created_at":"2018-10-30 10:33:14","updated_at":"2018-10-30 10:33:14"}⏎

また、lsコマンドで現在参照可能な変数の一覧を表示させることができます。

lsVariables: $book, $id, $this

Videos

1. Laravel入門講座:環境設定【前半】Laravelのインストールを実演
(はじめてプログラミング【LaravelエンジニアJunko】)
2. 【Laravel入門】ディレクトリ構成とDBマイグレーション ~ブログアプリを作る~ #02
(渋谷で働くエンジニア福の「実践で学ぶプログラミング入門」)
3. Laravelのディレクトリ構造がスッキリ分かる10分解説【Laravel超入門】
(はじめてプログラミング【LaravelエンジニアJunko】)
4. 【Laravel入門】私の勉強法とおすすめの書籍や教材を紹介しています
(ふじしゅーちゃんねる)
5. Laravel入門 その16「Eloquent(4)」
(大阪コード学園)
6. PHPとLaravelに「一生」関わる必要がない理由
(KENTA / 雑食系エンジニアTV)
Top Articles
Latest Posts
Article information

Author: Fr. Dewey Fisher

Last Updated: 11/19/2022

Views: 6513

Rating: 4.1 / 5 (62 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Fr. Dewey Fisher

Birthday: 1993-03-26

Address: 917 Hyun Views, Rogahnmouth, KY 91013-8827

Phone: +5938540192553

Job: Administration Developer

Hobby: Embroidery, Horseback riding, Juggling, Urban exploration, Skiing, Cycling, Handball

Introduction: My name is Fr. Dewey Fisher, I am a powerful, open, faithful, combative, spotless, faithful, fair person who loves writing and wants to share my knowledge and understanding with you.