Lesson 6

DBを扱う

Lesson 6 Chapter 1
データベースとの接続

Lesson6ではデータベース(DB)について学習を行っていきます。PHPで開発されているサービスのほとんどはDBが利用されていますので、重要な項目になります。この学習でDBについて触れていきましょう。

データベース(DB)とは

データベースとは情報を保存しておく場所を指します。新規登録で作成されたユーザーや掲示板に投稿した内容などDBに登録されている情報を表示させたり編集、削除を行うことが可能です。例えば利用しているサービスのマイページに自身の情報が表示されていたり、掲示板システムのような自身や別のユーザーが投稿したメッセージの内容を確認できるのも全てDBに登録されている為、可能となっています。そしてデータベースには複数種類が存在しており、よく耳にするDBで言うとMysqlやMariaDB、Oracle、Postgresなどが挙げられます。基本的にはどれも同じ役割を果たしているので、現場のプロジェクトに合わせてDBを統一させる必要があります。今回はXAMPPを導入した際に含まれているMariaDBを使用して学習を行っていきましょう。

データベースの確認

以前の項目で簡単にご紹介しましたが、実際にデータベースを確認してみます。

1. Mysqlの起動

Mysqlの起動をしましょう。緑色に点灯しRunningとなっていれば起動完了です。

コントロールパネル画面

2. ダッシュボードへアクセス

XAMPPのダッシュボード画面を表示します。コントロールパネルの「Go to Application」もしくは「http://localhost/dashboard」からアクセスが可能です。

コントロールパネル画面

3. phpMyAdminへアクセス

表示されたページのメニューバーに存在する「phpMyAdmin」をクリックしましょう。

phpmyadmin画面

4. データベースの確認

phpMyAdminからデータベースの確認が行えます。左のサイドバーに表示されているlaravelが今回使用していくデータベースになります。

phpmyadmin画面

もしlaravelが存在しない場合はプロジェクトディレクトリにいる状態で以下コマンドを実行し、再度リロードしてみてください。

ターミナル、コマンドプロンプト
php artisan migrate

コマンドでデータベース「laravel」が作成される理由

.envファイルではインストールしたLaravelに関する設定がされており、DBに関する情報も.envファイルに記載があります。今後別のDB名で作成したい場合はこちらを修正することで任意のDBを作成することが可能です。

.env
DB_DATABASE=laravel

5. テーブルの確認

作成したDBの中にはテーブルが存在します。テーブルとはデータを実際に保存しておく場所を指し、一つのDBの中に複数作成することが可能です。例えばユーザーに関するデータを保存するテーブルであればusersテーブル、投稿に関するテーブルであればpostsテーブルなど関連のあるデータ毎に1つのテーブルを用意しながらデータ管理を行なっていきます。プロジェクトによっては一つのサービスで100前後のテーブルを使用しているケースもあります。

phpmyadmin画面

Laravelをインストールした段階で4つのテーブルがデフォルトで用意されています。又、これらのテーブルは先ほど実行した「php artisan migrate」によって作成されているテーブルです。

コマンドでテーブルが作成される理由

テーブルの構造を定義しているファイルがあります。以下ファイルを確認してみましょう。

databases > migrations > 年_月_日_create_users_table.php

年_月_日_create_users_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('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

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

こちらがphpMyAdminで確認したusersテーブルになります。このようにLaravelではファイルを使用してテーブルを作成し、コマンド一つでDB上へ反映させることが可能となっています。migrationファイルについては先の項目で実践を交えながら詳細を解説していきます。

それでは再度phpMyAdminに戻りusersテーブルの中を確認してみましょう。

phpmyadmin画面

テーブルの中にはカラムが存在します。カラムとはデータが保存される列のことを指します。現段階では8つのカラムが存在しており、ユーザーのID、名前、メールアドレスなどがそれぞれのカラムへ追加されていきます。そしてカラムはmigrationファイルに記述した内容が反映されています。

bigIncrements('id') → usersテーブルのidカラムを作成

string('name') → usersテーブルのnameカラムを作成

string('email') → usersテーブルのemailカラムを作成

timestamp('email_verified_at') → usersテーブルのemail_verified_atカラムを作成

sring('password') → usersテーブルのpasswordカラムを作成

rememberToken() → ログイン保持用のトークンを作成

timestamps() → updated_atとcreated_atのカラムを作成

このようにテーブル内に設置したいカラムを設定することでカラムの作成を行うことが可能です。例えばusersテーブルに年齢のデータを格納する列を追加したい場合は上記に続いて追記してあげます。

以上がデータベースの設定方法と関連する部分の紹介になります。先ほどもお伝えしましたが、今後テーブルをご自身で作成する項目がございますので、その項目で詳細の設定方法などを実践を交えながら行なっていきましょう。

Lesson 6 Chapter 2
Laravelで使用可能なカラムタイプ

chapter2ではカラムのタイプについて学習を行なっていきましょう。カラムタイプの設定を行わない場合はテーブルを作成することができません。又、セキュリティ面においてもカラムタイプを把握しておくことは必須項目とも言えます。

カラムタイプとは

カラムタイプとはカラムに制約する型のことを指します。値がもつデータ型のようにカラムにも型を設定する必要があり、設定しておくことで予期しない値の格納を未然に防ぐことが可能です。デフォルトのusersテーブルのカラムタイプを確認してみましょう。

年_月_日_create_users_table.php
$table->string('name');

nameカラムはstring(文字列型)の設定を行なっています。その為、nameカラムへ整数のint型や小数点のdouble、float型など相違した型を持つ値を格納しようとするとエラーが発生します。

カラムタイプの紹介

migrationファイルに設定できるカラムタイプは60種類以上存在します。今回はその中でも使用頻度が高いものをいくつかピックアップしてご紹介していきます。

1. increments

使用例
$table->increments('id')

idに使用するケースがほとんどのカラムタイプになります。incrementsの特徴としてはレコード(データ)が追加される度に自動で連番が付与されていき、以下の範囲内での付与が可能となります。例えば3人のユーザーが作成された場合、作成された順で1~3のIDが割り当てられます。

INT(符号付き)の範囲:-2147483648〜2147483647

INT(符号なし)の範囲:0〜4294967295

※符号とは-(マイナス)を指します。

2. bigIncrements

使用例
$table->bigIncrements('id')

又は

$table->id();

incrementsよりも更に多くの範囲のデータを格納できるカラムタイプになります。より規模の大きなサービスの場合に使用すると良いでしょう。 尚、デフォルトで設定されている「$table->id()」と「$table->bigIncrements('id')」は記述は異なりますが、役割は同じです。プロジェクトによってbigIncrementsで表現されている場合もある為、どちらの記述方法も認識しておきましょう。

BIGINT(符号付き)範囲:-9223372036854775808から9223372036854775807

BIGINT(符号なし)範囲:0から18446744073709551615。

3. unsignedBigInteger

使用例
$table->unsignedBigInteger('user_id');

又は

$table->foreignId('user_id');

bigIncrementsよりまた更により多くのデータを格納できるカラムタイプになります。その他の相違点としては符号なしのデータのみ登録が可能ということを認識しておきましょう。又、unsignedBigIntegerのエイリアスとしてforeignIdメソッドというメソッドも存在します。役割は同じですが、プロジェクトによっては記述に相違があるケースもあるので、こちらも合わせて認識しておきましょう。

BIGINT(符号なし)範囲:0 ~ 18,446,744,073,709,551,615

4. string

使用例
$table->string('message', 255);

文字列型を格納するカラムタイプになります。第一引数にはカラム名、第二引数には文字数を設定することができますが、文字数に関しては省略することも可能です。その場合、最大文字数の255文字で設定されます。

5. text

使用例
$table->string('remarks');

stringに比べ、より多くの文字数を格納することが可能なカラムタイプになります。最大文字数は65,535バイトとなっており、日本語の場合は1文字あたり3~4バイトとなるため、およそ16,384文字の格納が可能になります。英数字の場合は1文字あたり1バイトとなるため、65,535文字の格納が可能になります。

6. integer

使用例
$table->integer('number');

整数型を格納するカラムタイプになります。

BIGINT(符号あり)範囲:-2147483647〜2147483647

7. boolean

使用例
$table->boolean('flag');

真偽値を格納するカラムタイプになります。trueかfalse、又は1か0のデータの格納が可能です。

8. date

使用例
$table->('day'); // (例)2023-03-11

日付を格納するカラムタイプになります。

9. timestamp

使用例
$table->timestamp('start_at'); // (例)2020-01-01 12:00:00

日時を格納するカラムタイプになります。「$table->timestamp()」で作成されるcreated_atとupdated_atもtimestamp型になります。

10. softDeletes

使用例
$table->softDelete();

削除した日時を格納するdeleted_atカラムを作成するカラムタイプになります。削除には論理削除と物理削除が存在しており、論理削除の場合はDBにデータを残した状態で削除扱いにし、物理削除の場合はDBから完全にデータを抹消します。softDeleteは論理削除に該当します。

11. remenberToken

使用例
$table->rememberToken();

デフォルトのusersテーブルに用意されているカラムタイプになります。ログイン時にログイン情報をsessionに保持させる機能を持っている為、アカウントは継続してログイン状態を保てる仕組みとなっています。remember_tokenカラムが作成されます。

以上がカラムタイプの紹介になります。実際にテーブルを作成する際には、こちらを参考に進めていきましょう。

Lesson 6 Chapter 3
ORM

chapter3ではORMについて学習を行っていきましょう。ORMを理解しておくことでデータの操作を行うことが可能です。PHPで開発されたサービスのほとんどはDBを利用している為、こちらも必須項目として学習をおこなっていきます。

ORMとは

ORM(Object Relational Mapping)とはModelを通じて、データの取得、作成、更新、削除などDBの操作を行う為の機能のことを指します。

Eloquentについて

ORMではModelを通じて、DB操作を行っていることをお伝えしました。もう少し深掘りしてみると、データベースとModelを関連づけているLaravelの機能をEloquentと呼び、Eloquentモデルやモデルを総称してEloquentと呼ばれることも多くあります。又、EloquentはDB上のデータ操作をPHPのクラスを扱うように使用することができるのも一つの特徴です。ここでは実際に一つModelを作成して中身を確認してみましょう。

ターミナル、コマンドプロンプト
php artisan make:model Test

app > Models > Test.php

Test.php
<?php
namespace App\Models;

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

class Test extends Model
{
    use HasFactory;
}

作成したModelはextends Modelとして外部ファイルを継承しています。継承しているModelは「use Illuminate\Database\Eloquent\Model」の部分になります。このようにModelファイル単体がデータベースの操作を行っているわけではなく、Eloquentの機能を継承しデータベース操作を可能としています。

ORMの使用について

ORM使用によるメリットは以下になります。

  • 複雑なDB操作もメソッドを使用することでスマートになる。
  • 取得したデータの加工が行いやすい。

Laravelでデータを操作する手段としてORMが挙げられていますが、これは方法の一つです。Model(Eloquent)を使用せずともControllerの処理にSql文を記述してデータの操作を行うことも可能です。

クエリの実行

Eloquentを使用した場合とそうでない場合のそれぞれをクエリを実行しながら確認していきます。尚、クエリとはデータベースに送る命令文のようなものです。例えばユーザーの作成を行いたい場合はデータベースに対してユーザー作成のクエリを実行しています。

Eloquentでのデータ操作例

1. 全ユーザーを取得する処理

Controller.php
use App\Models\User;

// 全ユーザーの取得
User::all();

2. カラムを指定して全ユーザーを取得する処理

Controller.php
use App\Models\User;

// 全ユーザーからidカラムとnameカラムの取得
User::select("id", "name")->get();

データ取得にポイント

allやgetでは全てのカラムを取得してしまう為、カラム数が多い時は必要なカラムを指定するようにしましょう。その心掛けをしておくことで、システムのパフォーマンス向上やバグの未然防止にも繋がります。

3. idカラムが1のユーザーを取得する処理

Controller
use App\Models\User;

// idカラムが1のユーザー取得
User::find(1);

4. ユーザーを作成する処理

Controller
use App\Models\User;

// ユーザーの作成
User::create(
  [
    "name" => "テスト太郎",
    "age" => "20"
  ];
);

5. idカラムが1のユーザーを更新する処理

Controller
use App\Models\User;

// idカラムが1のユーザーを更新
User::where("id", 1)->update(
  [
     "name" => "テスト二郎",
     "age" => "22",
  ]
);

6. idカラムが1のユーザーを削除する処理

Controller
use App\Models\User;

// idカラムが1のユーザーを削除
User::where("id", 1)->delete();

これらがEloquentを使用したデータの操作例になります。全てのユーザー表示から削除まで一通りの実装例を紹介致しました。このようにEloquentで操作する場合はEloquentのメソッドを使用し、シンプルなコーディングで処理の実装が実現できます。又、Eloquentに関する詳細はLaravel公式(https://readouble.com/laravel/master/ja/eloquent.html)にて確認することが可能ですので、一度目を通してみてください。

Laravel公式リファレンス

DBファサードでのデータ操作例

続いてはDBファサードを使用したデータ操作を確認してみましょう。LaravelではDBファサードを使用することでsql文を実行することができます。

1. 全ユーザーを取得する処理

Controller.php
use App\Models\User;

// 全ユーザーの取得
DB::select("select * from users");

2. idカラムが1のユーザーを取得する処理

Controller
use Illuminate\Support\Facades\DB;

// idカラムが1のユーザー取得
DB::select("select * from users where id = 1");

3. ユーザーを作成する処理

Controller
use Illuminate\Support\Facades\DB;

// ユーザーの作成
DB::insert('insert into users (name, age) values ("テスト太郎", "20")');

4. idカラムが1のユーザーを更新する処理

Controller
use Illuminate\Support\Facades\DB;

DB::update('update users set name = "テスト二郎", age = 22 where id = 1');

5. idカラムが1のユーザーを削除する処理

Controller
use Illuminate\Support\Facades\DB;

// idカラムが1のユーザーを削除
DB::delete('delete from users where id = 1');

これらがDBファサードを使用したデータ操作例になります。Eloquentと比べてみると一つ一つsql文を用いて操作を行っているので、複雑な処理の場合は更に記述量が増えてしまいます。又、DBファサードの場合はModelを経由していない為、Eloquentは機能していません。本来LaravelはMVCモデルを採用しているのに対し、Modelを経由しない場合1ファイルあたりの記述量も増え、今後機能の修正やアップデートが必要になった時は必要以上に時間を掛けてしまう可能性も高くあります。その為、Laravelでは特別な理由がない限りは基本的にEloquentの機能を利用したデータ操作を行っていくと良いでしょう。

以上がEloquentを使用する場合とEloquentを使用せずにsql文を実行するデータの操作例になります。先の項目では実際に一通りの操作を用いた簡単なwebアプリケーションを作成していきますので、そこでEloquentを使用しクエリの実行を行いながら詳細の解説をしていきます。Laravelの機能を生かしたEloquentでの機能実装に今後もチャレンジしていきましょう。

Lesson 6 Chapter 4
Redisの紹介

chapter4ではRedisについて紹介を行っていきます。実際にこの教材で使用はしませんが、プロジェクトによって導入しているケースもある為、認識としては押さえておきましょう。

Redisとは

Redis(Remote Dictionary Server)もデータベースの一つです。Redisの特徴としてシンプルかつスピーディなどが挙げられます。

Redisの特徴 スピーディ

Redisはデータベースの中でもインメモリデータベースと呼ばれるデータベースになります。メモリ上で動作を行いデータの管理を行っている為、ストレージの容量は少ないですが、スピーディにデータを扱うことが可能です。

Redisの特徴 シンプル

key-valueによってデータを管理する為、シンプルで扱いやすい点も特徴の一つです(例:"name" => "テスト太郎")。しかし、Redisの場合は通常のkey-valueによって保存されるデータベースと違い、様々なデータ型が用意されている為、複雑なデータの操作も行うことが可能となっています。

Redisの特徴 データ操作

メモリ上で動作するデータベースの場合はメモリのデータが揮発性の為、一時的にしか扱えないケースが多いですが、Redisにはそのデータを一時的ではなく永久保存することも可能です。

Redisの動作イメージ

特徴の一つである高速なデータ操作ですが、Redisはキャッシュサーバーとしても利用されることがあります。

例えば、冷蔵庫に「水」「お茶」「ジュース」が入っているとしましょう。この場合、冷蔵庫がデータベースでその中に含まれる水などがデータになります。その際、飲み物を飲むために冷蔵庫へ向かう処理が発生するため、一定の時間が掛かりますが、Redisの場合は飲み終えた後も冷蔵庫へは戻さずテーブルの上に置いておくイメージになります。その為、処理速度の高速化が実現されています。

Redisの導入と実行

ここからはRedis実行の為の準備とデータ操作の流れを簡単に確認していきます。

Redisの導入

Redisを使用する為、パッケージのインストールを行います。

Redisパッケージのインストール
composer require predis/predis

インストールが完了したら、database.phpの修正を必要に応じて行います。

config > database.php

database.php
<?php

// 省略

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_DB', 0),
    ],

    'cache' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_CACHE_DB', 1),
    ],

],

.envファイルの修正を行います。

.env
// 省略

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

// 省略

app.php内のaliases部分にRedisの記載があればコメントしておきます。

config > app.php

app.php
// 省略

'aliases' => Facade::defaultAliases()->merge([
        // 'Redis' => Illuminate\Support\Facades\Redis::class,
    ])->toArray(),

// 省略

準備はこれで一旦完了になります。

Redisの実行

続いては実行してみます。今回は本格的に処理として実行するよりも、動作確認を行う為、tinkerを使って動作確認を行います。

備考:tinkerとは

Laravelに標準で搭載されているコマンドラインツールになります。これまでは処理の確認を実際にControllerなどに記載し、ブラウザで確認を行ってきましたが、テストとして処理の動作を確認したい場合にtinkerを使用することで容易に確認することができます。以下コマンドの実行でtinkerを使用することができます。

ターミナル、コマンドプロンプト
php artisan tinker
出力結果
Psy Shell v0.11.12 (PHP 8.0.17 — cli) by Justin Hileman
>
                      

試しにtinkerを使用してみます。まずは変数の定義を行ってみましょう。

ターミナル、コマンドプロンプト
> $test = "これはテストです";

定義した変数を呼び出してみます。

ターミナル、コマンドプロンプト
> echo $test;
これはテストです。

このようにテストなどで処理を確認したい場合にtinkerを使用することでコントローラやルーティングなどのファイルを準備することなく処理の動作を確認することができます。tinkerは今後も積極的に活用してみてください。

それでは本題に戻り、tinkerを使用してRedisの実行を行ってみます。

ターミナル、コマンドプロンプト
> use Redis
ターミナル、コマンドプロンプト
> Redis::set('test', 'これはテストです')
ターミナル、コマンドプロンプト
> Redis::get('test')
ターミナル、コマンドプロンプト
> これはテストです

Redisファサードで保存した情報の出力に成功しました。このようにRedisファサードにsetメソッドを使用して('key', 'value')の形式でデータを登録し、getメソッドの引数に取得したいデータのkeyを代入することでデータの取得が可能です。

以上がRedisの紹介でした。冒頭でもお伝えしましたが、Redisはこの教材では今後使用しません。例えばチャット機能のようにJavaScriptを用いたような素早いデータの登録や削除などのデータ操作が行われる場合に導入する機能の一つとお考えいただければと思います。Laravelではこのようにライブラリを導入し、機能を拡張させながら開発を行っていけることを認識しておきましょう。