1. Home
  2. PHP
  3. Laravel
  4. Laravel入門 MVC モデルを使ってデータベースからデータ取得・表示を行う

Laravel入門 MVC モデルを使ってデータベースからデータ取得・表示を行う

  • 公開日
  • 更新日
  • カテゴリ:Laravel
  • タグ:PHP,Laravel,MySQL,Beginner,MVC,Database
Laravel入門 MVC モデルを使ってデータベースからデータ取得・表示を行う

prev:Laravel インストール後の初期設定と入門/簡単に MVC で HelloWorld&データ受け渡しを行う

前回の記事で Laravel を使った基本的な MVC 操作を行いましたが、今回はモデルを導入して、本格的にデータベースからのデータ取得、そして表示を行います。

Contents

  1. 開発環境
  2. データベースとデータの用意
    1. データベース作成
    2. テーブル作成
    3. テーブルにデータを挿入する
  3. モデルの作成
  4. ルーティング
  5. コントローラ
  6. ビュー
  7. 動作確認
  8. 取得データの絞込み
    1. ルーティング
    2. コントローラ
    3. モデル
    4. 動作確認

開発環境

今回の開発環境に関しては以下になります。

  • Linux CentOS 7
  • Apache 2.4
  • MySQL 5.7
  • PHP 7.2
  • Laravel 5.7

上記環境でなくても(XAMPP など)進めていけます。また、途中、artisan コマンドを叩きますが、環境的に難しい場合は手動でのファイル作成でも進めていけます。

そして、今回はデータベースを使います。 MySQL で進めますが、サンプルデータを作成できれば他のデータベースでも OK です。

データベースの作成についてはコンソール画面から行いますが、難しい場合、XAMPP などの場合は phpMyAdmin を使って作成してもらえれば進めていけます。

データベースとデータの用意

Laravel 側の実装を行う前に、まずはデータベースとデータを用意していきます。

今回のサンプルデータとして、各種フレームワークの名前を収録したデータを用意しました。それぞれ、フレームワークの名前と、そのタイプとして、PHP と JavaScript と Python の識別子を収録しています。

作成やインサートに関しては MySQL の CUI で進めていきますので、別のデータベースを使用している場合には適宜、読み替えてください。

また、生成用の各種 SQL 文などは、本記事最下部の Github リンクから取得もできます。

データベース作成

「sample 」という名前のデータベースを作成します。データベースにログインし、MySQL であれば以下の SQL を流してデータベースを作成します。

# 「sample 」という名前のデータベースを作成
mysql> create database sample;
Query OK, 1 row affected (0.00 sec)

# データベース確認
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sample             |
| sys                |
+--------------------+
10 rows in set (0.00 sec)

データベースが作成できたら、Laravel 側の環境変数ファイルへデータベース名を設定しておきます。

laravel/.env
DB_DATABASE=sample

テーブル作成

「frameworks 」という名前のテーブルを作成します。カラムは「id 」「name 」「type 」とします。それぞれの役割は以下の通りです。

id 主キー name フレームワークの名称 type フレームワークのタイプ 1=PHP 2=JavaScript 3=Python 以下の SQL を流してテーブルを作成します。

# frameworks テーブルを作成する SQL 文(改行版)
CREATE TABLE `frameworks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `type` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  INDEX type_index(type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

テーブルにデータを挿入する

作成したテーブルへデータを挿入します。以下の SQL を流してデータをインサートします。

# frameworks テーブルにデータを挿入する
INSERT INTO `frameworks` (`id`, `name`, `type`) 
VALUES 
(NULL, 'Laravel', 1),(NULL, 'CakePHP', 1),(NULL, 'Symfony', 1),(NULL, 'Silex', 1),(NULL, 'Zend Framework', 1),
(NULL, 'CodeIgniter', 1),(NULL, 'FuelPHP', 1),(NULL, 'Slim', 1),(NULL, 'Yii', 1),(NULL, 'Flight', 1),(NULL, 'Ethna', 1),
(NULL, 'BEAR.Sunday', 1),(NULL, 'Kohana', 1),(NULL, 'Ice Framework', 1),(NULL, 'AngularJS', 2),(NULL, 'Backbone.js', 2),
(NULL, 'Ember.js', 2),(NULL, 'Vue.js', 2),(NULL, 'Knockout.js', 2),(NULL, 'React', 2),(NULL, 'Riot.js', 2),
(NULL, 'Aurelia.js', 2),(NULL, 'Bottle', 3),(NULL, 'Django', 3),(NULL, 'Flask', 3),(NULL, 'Pyramid', 3),
(NULL, 'Plone', 3),(NULL, 'Tornado', 3),(NULL, 'CherryPY', 3),(NULL, 'pandas', 3);

SELECT して確認します。インサート後はこんな感じになります。

mysql> select * from frameworks;
+----+----------------+------+
| id | name           | type |
+----+----------------+------+
|  1 | Laravel        |    1 |
|  2 | CakePHP        |    1 |
|  3 | Symfony        |    1 |
|  4 | Silex          |    1 |
|  5 | Zend Framework |    1 |
|  6 | CodeIgniter    |    1 |
|  7 | FuelPHP        |    1 |
|  8 | Slim           |    1 |
|  9 | Yii            |    1 |
| 10 | Flight         |    1 |
| 11 | Ethna          |    1 |
| 12 | BEAR.Sunday    |    1 |
| 13 | Kohana         |    1 |
| 14 | Ice Framework  |    1 |
| 15 | AngularJS      |    2 |
| 16 | Backbone.js    |    2 |
| 17 | Ember.js       |    2 |
| 18 | Vue.js         |    2 |
| 19 | Knockout.js    |    2 |
| 20 | React          |    2 |
| 21 | Riot.js        |    2 |
| 22 | Aurelia.js     |    2 |
| 23 | Bottle         |    3 |
| 24 | Django         |    3 |
| 25 | Flask          |    3 |
| 26 | Pyramid        |    3 |
| 27 | Plone          |    3 |
| 28 | Tornado        |    3 |
| 29 | CherryPY       |    3 |
| 30 | pandas         |    3 |
+----+----------------+------+
30 rows in set (0.00 sec)

これでデータベースとデータの準備は完了です。

モデルの作成

ここからは Laravel 側の実装です。まずはモデルを作成していきます。

まず、Laravel には Model ディレクトリというものが存在していません。
「Model の定義(解釈)って人によって違うところあるから、好きなところに作ってくれていいよ」
というポリシーでデフォルトでは提供していないので、自分で作成する必要があります。(厳密には作らなくてもいけますが、後々モデルファイルが散らかるので作成しておく方が良いです)

という事で、laravel/app 配下に Models ディレクトリを作成します。

Models ディレクトリを作成したら、以下の artisan コマンドを叩いてモデルクラスを生成します。

# laravel のルートディレクトリへ移動
cd /path/to/laravel

# artisan コマンドでモデルクラスを生成
php artisan make:model Models/frameworks

# 実行結果
[demo@localhost laravel]# php artisan make:model Models/frameworks
Model created successfully.

モデルクラス名はテーブル名と同じにしましょう。わかりやすいので後々メンテナンスがしやすくなります。

ディレクトリ作成と、モデルクラス生成で、最終的には以下のファイル階層になります。

laravel
├─ app
│   ├─ Models
│   │   └─ frameworks.php

laravel/App/Models/frameworks.php を開いてみます。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class frameworks extends Model
{
    //
}

クラス宣言のみのシンプルなコードです。ここにデータベースからデータを取得する仕組み記述していきます。ひとまず、以下のようになります。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class Frameworks extends Model
{
  protected $table = 'frameworks';

  protected $guarded = array('id');

  public $timestamps = false;

  public function getData()
  {
    $data = DB::table($this->table)->get();

    return $data;
  }
}

上から解説していきます。

use Illuminate\Support\Facades\DB;

Laravel では、SQL 文を組み立てる際に「クエリビルダ」と呼ばれる、簡単に SQL 文を組み立てる事の出来るインターフェイスが提供されており、それを使用する為に DB ファサードを use しています。

protected $table = 'frameworks';

protected $guarded = array('id');

public $timestamps = false;

この3つは結構お約束のメンバ変数になります。上から、

  • テーブル名のセット
  • 主キーのセット
  • 自動タイムスタンプ挿入の是非

になります。テーブル名のセットについてはいわずもがなです。そのままこのモデルで使用するメインテーブルの名前をセットしています。

主キー(PRIMARY KEY を持つカラム)のセットについては、「id 」という名であればセットしなくても Laravel 側で自動認識してくれますが、今回は紹介の為に記述しています。

自動タイムスタンプ挿入というのは、Laravel ではそのテーブル内に作成日時を示す「created_at 」と、更新日時を示す「updated_at 」のカラムを作成した際に、インサートやアップデートの時に自動で値を入れてくれるように出来るので、その機能の是非をここで設定できます。今回は日時カラムは持たないので false にしています。

尚、これらの設定は EloquentORM を使用する際に最も力を発揮しますが、今回は使用せず、よりベーシックな方法でデータベースを操作していきます。

EloquentORM については、以下で解説しています。
Laravel の EloquentORM の基本から具体的な使い方

public function getData()
{
  $data = DB::table($this->table)->get();

  return $data;
}

ここでデータベースからデータを取得し返す getData() メソッドを実装しています。

DB ファサードを使いテーブルを指定して取得を行っています。尚、今回は条件などはつけずに全てを取得していますが、この形がクエリビルダの基本文法となって、ここから WHERE 句や ORDER 句などを付け足す事によって色々な条件でデータを取得する事が出来ます。

そして最後に、変数 $data に入ってきたデータを return して返しています。

これでモデルの作成は完了です。

ルーティング

次に、データ取得から表示までのルーティングを設定していきます。

laravel/routes/web.php に以下を追記します。

Route::get('sample/model', 'SampleController@model');

http://YOURDOMAIN/sample/model にアクセスしたら、sample コントローラの model アクションを実行する」という記述になります。

コントローラ

ルーティングに沿って、コントローラとアクションの作成を行います。

laravel ルートディレクトリへ移動し、以下の artisan コマンドを叩きます。

# laravel のルートディレクトリへ移動
cd /path/to/laravel

# artisan コマンドでモデルクラスを生成
php artisan make:controller SampleController

# 実行結果
[demo@localhost laravel]# php artisan make:controller SampleController
controller created successfully.

生成された SampleController.php を開き、以下を記述します。

laravel/app/Http/Controller/SampleController.php
<?php

namespace App\Http\Controllers;

use App\Models\Frameworks;

class SampleController extends Controller
{
  public function model()
  {
    // Frameworksモデルのインスタンス化
    $md = new Frameworks();
    // データ取得
    $data = $md->getData();

    // ビューを返す
    return view('sample.model', ['data' => $data]);
  }
}

上から解説します。

use App\Models\Frameworks;

先ほど作成した Frameworks モデルクラスを use しています。

public function model()
 {
   // Frameworksモデルのインスタンス化
   $md = new Frameworks();
   // データ取得
   $data = $md->getData();

   // ビューを返す
   return view('sample.model', ['data' => $data]);
 }

メインの model アクションを実装しています。

まずは Frameworks モデルをインスタンス化し、getData() メソッドを呼んでデータを取得しています。

そして変数 $data をセットし、ビューを返しています。

簡単ですが、コントローラはこれだけで実装完了です。

ビュー

最後に、ビューを実装します。ここでは、取得したデータをリストの形で出力していこうと思います。

まずは、laravel/resources/views/sample 配下に model.blade.php を作成します。(ちなみに sample ディレクトリは今回のデモ用のディレクトリであり、デフォルトでは存在していないので自分で作成してください。)

model.blade.php を開いて、以下を記述します。

laravel/resources/views/sample/model.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>model sample</title>
</head>
<body>
  <ul>
    @foreach($data as $d)
      <li>{{$d->name}}</li>
    @endforeach
  </ul>
</body>
</html>

簡単な HTML ですが、以下だけ解説します。

@foreach($data as $d)
  <li>{{$d->name}}</li>
@endforeach

ここは、ビューに渡されてきたデータを、Blade記法で foreach(ループ)を行い、一件ずつ表示を行っています。

コントローラからモデル経由で取得したデータベースのデータはオブジェクトで返ってきますが、その際の各データの識別子(KEY の部分)はカラム名で入ってきますので、フレームワークの名前を出力したい場合はこのように $d->name とすれば取り出せる。という事になります。

動作確認

これで一通りの実装が完了したので、実際にブラウザからアクセスして確認してみます。

ブラウザから http://YOURDOMAIN/sample/model にアクセスしてみます。

無事にデータベースからデータを取得し表示させる事ができました。

取得データの絞込み

先ほどは、データ取得の部分に関して、特に条件を指定せずに全件を取得し表示させました。

しかし全てのデータを取得する場面というのはそうそうあるわけではありません。常になにかしらの条件の下で取得していく事が求められてくると思います。

今回用意したデータも、フレームワークを収納したデータですが、それぞれ、PHP のフレームワーク、JaveScript のフレームワーク、Python のフレームワークと3つに分かれています。

それではこれらを、タイプを指定して取得出来るようにしてみます。

ルーティング

まずルーティングを変更します。 laravel/routes/web.php を開き、先ほど記述したルーティングを以下へ変更します。

Route::get('sample/model', 'SampleController@model');
↓
Route::get('sample/model/{type?}', 'SampleController@model');

/{type?} を追加しています。「sample/model/1 」のようにして値を渡せるようなルーティングになっています。{}の中に type と記述する事によって、変数名 $type としてコントローラで受け取る事ができ、かつ、 ? をつける事で、パラメータがある場合・無い場合の両方で許容されます。

コントローラ

次に、コントローラを変更します。先ほど実装した model() アクションを、次のように変更します。

laravel/app/Http/Controllers/SampleController.php
public function model($type=null)
{
  // Frameworksモデルのインスタンス化
  $md = new Frameworks();
  // データ取得
  $data = $md->getData($type);

  // ビューを返す
  return view('sample.model', ['data' => $data]);
}

ルーティングで記述した{type}によって、 $type 変数が受け取れるので、それを getData() メソッドに引数として渡している。という変更になります。

ちなみに、model() アクションの引数を $type=null としているのは、タイプパラメータが無い場合にも対応する為に、初期値に null を指定している。という意図になります。

モデル

最後にモデルです。 Frameworks.php の getData() メソッドを次のように変更します。

laravel/app/Models/Frameworks.php
public function getData($type=null)
{
  $query = DB::table($this->table);

  if($type != null) $query->where('type', $type);

  $data = $query->get();

  return $data;
}

変数 $type として引数を受け取り、値が入ってきた場合にはクエリに追加する。という流れになっています。

こんな感じで、一度で get しない流れも Laravel では簡単に書くことが出来ます。

動作確認

全ての変更が完了したので、ブラウザからアクセスして確認してみます。

データベースに格納したデータには、type カラムに

  • 1 = PHP
  • 2 = JavaScript
  • 3 = Python

として入っていますので、それぞれアクセスしてみます。

URL はルーティングで記述した通り

  • http://YOURDOMAIN/sample/model/1
  • http://YOURDOMAIN/sample/model/2
  • http://YOURDOMAIN/sample/model/3

のようになります。

PHP フレームワークのみの一覧が表示されています。

こちらは JavaScript のフレームワークのみです。

そしてこちらは Python のフレームワーク

最後に、パラメータがなければ全ての一覧が表示されます。

まとめ

以上で作業は完了となります。
ここまででコントローラ、モデル、ビュー、ルーティングと、一通り使ってきましたが、Laravel は他の PHP フレームワークと比べてとてもシンプル、かつ制約も少なく WEB アプリケーションを構築していけます。

自由に書ける=無秩序になりやすい。とよく言われますが、しっかりと整理して記述していけばメンテナンスもしやすい綺麗なコードを保てます。それにはやはり、たくさんコードを書くことと、Laravel の機能を知る事だと思います。

本ラボでも、Laravel に関する便利な機能を紹介しているので、是非参考にしてみてください。

尚、今回のサンプルソースは以下よりダウンロード出来ます。

[Github]www.ritolab.com-sample-sources-Laravel-Beginner-mvc-model

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級