RitoLabo

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

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,MySQL,5.5,Beginner,MVC,Database,phpMyAdmin

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

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

アジェンダ
  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.1

Laravelのバージョンに関しては5.6/5.5/5.4/5.3で動作確認済みです。

上記環境でなくても(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にしています。

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フレームワーク一覧

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

JavaScriptフレームワーク一覧

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

Pythonフレームワーク一覧

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

全フレームワーク一覧

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

まとめ

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

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

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

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

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