Laravel HTTPリクエスト

リクエスト情報を取得

  1. コントローラのアクションの引数にRequest $requestのように型宣言を行う
  2. アクション内でその引数を使う
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SampleController extends Controller
{
    public function sample(Request $request) {
        // HTTPリクエストに含まれるuser_nameパラメータの値を取得し、変数$user_nameに代入する
        $user_name = $request->input('user_name');

        return view('sample', compact('user_name'));
    }    
}

Requestインスタンスに使える代表的なメソッド

メソッド 説明 引数
input() HTTPリクエストに含まれる、単一のパラメータの値を取得する。 パラメータ名
all() HTTPリクエストに含まれる、すべてのパラメータの値を配列で取得する。 なし
only() HTTPリクエストに含まれる、指定したパラメータの値のみを取得する。 パラメータ名の配列
except() HTTPリクエストに含まれる、指定したパラメータを除く値を取得する。 パラメータ名の配列
has() 指定したパラメータがHTTPリクエストに存在するかどうかを判定する。存在すればtrue、存在しなければfalseを返す。 パラメータ名
filled() 指定したパラメータがHTTPリクエストに存在し、かつ値が空でないかどうかを判定する。空でなければtrue、空であればfalseを返す。 パラメータ名
method() HTTPリクエストメソッド(GET、POST、PUT、PATCH、DELETEなど)を取得する。 なし
cookie() 指定したクッキーの値を取得する(クッキーについては25章で学習)。 クッキー名
path() HTTPリクエストのパスを取得する(https://example.com/vendors/5であればvendors/5の部分)。 なし
is() HTTPリクエストのパスが指定したパターンに一致するかどうかを判定する。一致すればtrue、一致しなければfalseを返す。パターンには0文字以上の任意の文字列を表すワイルドカード*が使える。 パターン(例:'vendors/*')
url() HTTPリクエストのURLを取得する。 なし
fullUrl() HTTPリクエストの完全なURLを取得する(末尾のパラメータも含む)。 なし
ip() HTTPリクエストを送信したクライアントのIPアドレスを取得する。 なし

Laravel Eloquent ORM

Eloquent ORM

Eloquent ORMを利用し、モデルを介してデータベースとやりとりする

  • クエリビルダ:モデルを介さず、直接データベースとやりとりを行う
  • Eloquent ORM:モデルを介し、間接的にデータベースとやりとりを行う

Eloquent ORMにおけるクエリの書き方

すべてのクエリに共通する書き方

  1. use App\Models\モデル名;を記述してモデルのuse宣言を行う
  2. モデル名::メソッド名またはインスタンス名->メソッド名のように、モデルまたはインスタンスに対してメソッドを使う(メソッドによってモデルとインスタンスのどちらに使うかは決まっている)

    Eloquent ORMにおいてクエリビルダを使う方法

    クエリビルダのメソッドは、以下のようにモデルに対して直接使います。

use App\Models\Product;

// productsテーブルから、priceカラムの値が1000以下のデータを最大で10件まで取得する
$products = Product::where('price', '<=', 1000)->take(10)->get();

Eloquent ORM独自の代表的なメソッド

all()メソッド

all()メソッドは、モデルにマッピングされているテーブルから、すべてのデータをインスタンスのコレクションとして取得する。

  • コレクション=配列やオブジェクトを効率的に操作するための、Laravel独自のラッパークラス(「配列の強化版」)
  • ラッパークラス=あるデータ型などに対し、機能やメソッドなどを追加するために包み込む(ラップする)クラス
use App\Models\Product;

// productsテーブルから、すべてのデータをインスタンスのコレクションとして取得する
$products = Product::all();

find()メソッド

find()メソッドは、モデルにマッピングされているテーブルから、引数に指定した主キーを持つデータを単一のインスタンスとして取得

use App\Models\Product;

// productsテーブルから、主キーの値が1のデータを単一のインスタンスとして取得する
$product = Product::find(1);

クエリビルダとORMの違い

  • Eloquent ORM:引数に指定した主キーを持つデータをモデルのインスタンスとして取得
  • クエリビルダ:引数に指定した主キーを持つデータをstdClassクラスのインスタンスとして取得

first()メソッド

first()メソッドは、モデルにマッピングされているテーブルから、条件に一致する最初のデータを単一のインスタンスとして取得

use App\Models\Product;

// productsテーブルから、priceカラムの値が1000と等しい最初のデータを単一のインスタンスとして取得する
$product = Product::where('price', 1000)->first();

クエリビルダとORMの違い

  • Eloquent ORM:条件に一致する最初のデータをモデルのインスタンスとして取得
  • クエリビルダ:条件に一致する最初のデータをstdClassクラスのインスタンスとして取得

create()メソッド

create()メソッドは、連想配列として指定したカラムとその値にもとづいて、モデルにマッピングされているテーブルに新しくデータを追加

use App\Models\Product;

// product_nameカラムの値が'小物入れ'、priceカラムの値が800のデータをproductsテーブルに追加する
Product::create(['product_name' => '小物入れ', 'price' => 800]);

ただしcreate()メソッドを使うには、モデルに対して$fillableプロパティまたは$guardedプロパティを設定する必要があります(両方ではなくどちらか1つ)。
$fillableプロパティを設定する場合

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    // 一括代入を許可するカラム名の配列を$fillableプロパティに代入する
    protected $fillable = ['product_name', 'price'];
}

$guardedプロパティを設定する場合

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    // 一括代入を禁止するカラム名の配列を$guardedプロパティに代入する
    protected $guarded = ['id'];
}

update()メソッド

update()メソッドは、連想配列として指定したカラムとその値にもとづいて、モデルにマッピングされているテーブルの条件に一致するデータを一括更新

use App\Models\Product;

// productsテーブルのpriceカラムの値が1000のデータについて、priceカラムの値を1100に一括更新する
Product::where('price', 1000)->update(['price' => 1100]);

update()メソッドを使う際もcreate()メソッドと同様に、モデルに対して$fillableプロパティまたは$guardedプロパティを設定する必要があります

delete()メソッド

delete()メソッドは、モデルのインスタンスマッピングされているデータを削除する

use App\Models\Product;

// productsテーブルから、主キーの値が1のデータを単一のインスタンスとして取得する
$product = Product::find(1);

// インスタンスにマッピングされているデータを削除する
$product->delete();

以下のようにwhere()メソッドなどと組み合わせて使い、条件に一致するすべてのデータを削除することもできます。

use App\Models\Product;

// productsテーブルから、priceカラムの値が1000未満のデータをすべて削除する
Product::where('price', '<', 1000)->delete();

save()メソッド

save()メソッドは、モデルのインスタンスを保存し、モデルにマッピングされているテーブルに対してデータを追加・更新する

データを追加する場合
use App\Models\Product;

// Productモデルをインスタンス化する
$product = new Product();

// インスタンスのプロパティを一括設定する(fill()は引数として渡された連想配列でインスタンスのプロパティを一括設定するメソッド)
$product->fill(['product_name' => '小物入れ', 'price' => 800]);

// インスタンスを保存し、productsテーブルにデータを追加する
$product->save();

以下のように、fill()メソッドを使わずインスタンス化と同時にプロパティを一括設定することも可能

use App\Models\Product;

// Productモデルをインスタンス化する(同時にプロパティを一括設定する)
$product = new Product(['product_name' => '小物入れ', 'price' => 800]);

// インスタンスを保存し、productsテーブルにデータを追加する
$product->save();

なお、上記のようにプロパティを一括設定する場合、例によってモデルに対して$fillableプロパティまたは$guardedプロパティを設定する必要があります。

データを更新する場合
use App\Models\Product;

// productsテーブルから、主キーの値が1のデータを単一のインスタンスとして取得する
$product = Product::find(1);

// インスタンスのプロパティに値を代入する
$product->price = 1000;

// インスタンスを保存し、productsテーブルのデータを更新する
$product->save();

Laravel クエリビルダ

クエリビルダとは

SQLのクエリ(テータベースに対する問い合わせ、命令文)を簡単に作成・実行できるLaravelの機能

-- SQL文
SELECT * FROM products;

// クエリビルダ
DB::table('products')->get();

クエリビルダの書き方

すべてのクエリビルダに共通

  1. use Illuminate\Support\Facades\DB;を記述してDBファサードのuse宣言を行う
  2. DB::table('テーブル名')を記述してデータベース操作を行うテーブルを指定する

    SELECT文

SQL
-- 1つのカラムのデータを取得する場合
SELECT カラム名 FROM テーブル名;

-- 複数のカラムのデータを取得する場合
SELECT カラム名1, カラム名2, カラム名3, ...... FROM テーブル名;

-- すべてのカラムのデータを取得する場合
SELECT * FROM テーブル名;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 1つのカラムのデータを取得する場合
DB::table('テーブル名')->select('カラム名')->get();

// 複数のカラムのデータを取得する場合
DB::table('テーブル名')->select('カラム名1', 'カラム名2', 'カラム名3', ......)->get();

// すべてのカラムのデータを取得する場合
DB::table('テーブル名')->get();

INSERT文

SQL
--「カラム名1には値1」「カラム名2には値2」のように、それぞれ対応する値が入ったデータが追加される
INSERT INTO テーブル名 (カラム名1, カラム名2, カラム名3, ......) VALUES (値1, 値2, 値3, ......);


クエリビルダ
use Illuminate\Support\Facades\DB;

//「カラム名1には値1」「カラム名2には値2」のように、それぞれ対応する値が入ったデータが追加される
DB::table('テーブル名')->insert(['カラム名1' => 値1, 'カラム名2' => 値2, 'カラム名3' => 値3, ......]);

UPDATE文

SQL
-- 条件式に当てはまるデータを検索し、セットされた値で更新する
UPDATE テーブル名 SET カラム名1 = 値1, カラム名2 = 値2,  カラム名3 = 値3, ...... WHERE 条件式;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 条件式(where()メソッドの引数)に当てはまるデータを検索し、セットされた値で更新する
DB::table('テーブル名')->where('カラム名', '比較演算子', 値)->update(['カラム名1' => 値1, 'カラム名2' => 値2, 'カラム名3' => 値3, ......]);

DELETE文

SQL
-- 条件式に当てはまるデータを検索し、削除する
DELETE FROM テーブル名 WHERE 条件式;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 条件式(where()メソッドの引数)に当てはまるデータを検索し、削除する
DB::table('テーブル名')->where('カラム名', '比較演算子', 値)->delete();

WHERE句

SQL
-- 条件式に当てはまるデータを検索し、取得する
SELECT カラム名 FROM テーブル名 WHERE 条件式;

-- 条件式に当てはまるデータを検索し、セットされた値で更新する
UPDATE テーブル名 SET カラム名1 = 値1, カラム名2 = 値2,  カラム名3 = 値3, ...... WHERE 条件式;

-- 条件式に当てはまるデータを検索し、削除する
DELETE FROM テーブル名 WHERE 条件式;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 条件式(where()メソッドの引数)に当てはまるデータを検索し、取得する
DB::table('テーブル名')->where('カラム名', '比較演算子', 値)->get();

// 条件式(where()メソッドの引数)に当てはまるデータを検索し、セットされた値で更新する
DB::table('テーブル名')->where('カラム名', '比較演算子', 値)->update(['カラム名1' => 値1, 'カラム名2' => 値2, 'カラム名3' => 値3, ......]);

// 条件式(where()メソッドの引数)に当てはまるデータを検索し、削除する
DB::table('テーブル名')->where('カラム名', '比較演算子', 値)->delete();

クエリビルダにおける条件式の書き方

クエリビルダのwhere()メソッド - 第1引数:カラム名 - 第2引数:比較演算子 - 第3引数:値

複数の条件式を組み合わせる方法

where()メソッドやorWhere()メソッドをつなげることで、「AかつB」「AまたはB」といった演算を実現

LIMIT句

SQL
-- 指定した最大件数までのデータを取得する
SELECT カラム名 FROM テーブル名 LIMIT 最大件数;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 指定した最大件数までのデータを取得する
DB::table('テーブル名')->take(最大件数)->get();

// limit()メソッドもtake()メソッドと同じ動作をする
DB::table('テーブル名')->limit(最大件数)->get();

ORDER BY句

SQL
-- 特定のカラムを昇順(ASC)または降順(DESC)で並び替え、その順番でデータを取得する
SELECT 取得するカラム名 FROM テーブル名 ORDER BY 並び替えるカラム名 並べ方(ASCまたはDESC);


クエリビルダ
use Illuminate\Support\Facades\DB;

// 特定のカラムを昇順(ASC)または降順(DESC)で並び替え、その順番でデータを取得する
DB::table('テーブル名')->orderBy('並び替えるカラム名', '並べ方(ascまたはdesc)')->get();

GROUP BY句

SQL
-- 指定したカラムでグループ化する
SELECT カラム名 FROM テーブル名 GROUP BY カラム名1, カラム名2, ......;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 指定したカラムでグループ化する
DB::table('テーブル名')->groupBy('カラム名1', 'カラム名2', ......)->get();

HAVING句

SQL
-- グループ化したあとに指定した条件でデータを絞り込む
SELECT カラム名 FROM テーブル名 GROUP BY カラム名1, カラム名2, ...... HAVING 条件式;


クエリビルダ
use Illuminate\Support\Facades\DB;

// グループ化したあとに指定した条件(having()メソッドの引数)でデータを絞り込む
DB::table('テーブル名')->groupBy('カラム名1', 'カラム名2', ......)->having('カラム名', '比較演算子', 値)->get();

JOIN句

SQL
-- 指定した結合条件でテーブル1とテーブル2を内部結合する
SELECT カラム名 FROM テーブル名1 INNER JOIN テーブル名2 ON 結合条件;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 指定した結合条件でテーブル1とテーブル2を内部結合する
DB::table('テーブル名1')->join('テーブル名2', 'テーブル名1.カラム名1', '比較演算子', 'テーブル名2.カラム名2')->get();

クエリビルダのjoin()メソッドでは、以下のように4つの引数を渡して条件式を作成します。

  • 第1引数:結合するテーブル名(テーブル名2)
  • 第2引数:紐付けるカラム(テーブル名1.カラム名1)
  • 第3引数:比較演算子(『データベースとSQLの基礎を学ぼう』の7章を参照)
  • 第4引数:紐付けるカラム(テーブル名2.カラム名2)
    LEFT OUTER JOIN(左外部結合)
SQL
-- 指定した結合条件でテーブル1とテーブル2を左外部結合する
SELECT カラム名 FROM テーブル名1 LEFT OUTER JOIN テーブル名2 ON 結合条件;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 指定した結合条件でテーブル1とテーブル2を左外部結合する
DB::table('テーブル名1')->leftJoin('テーブル名2', 'テーブル名1.カラム名1', '比較演算子', 'テーブル名2.カラム名2')->get();

leftJoin()メソッドの引数の指定方法はjoin()メソッドと同じ

RIGHT OUTER JOIN(右外部結合)

SQL
-- 指定した結合条件でテーブル1とテーブル2を右外部結合する
SELECT カラム名 FROM テーブル名1 RIGHT OUTER JOIN テーブル名2 ON 結合条件;


クエリビルダ
use Illuminate\Support\Facades\DB;

// 指定した結合条件でテーブル1とテーブル2を右外部結合する
DB::table('テーブル名1')->rightJoin('テーブル名2', 'テーブル名1.カラム名1', '比較演算子', 'テーブル名2.カラム名2')->get();

rightJoin()メソッドの引数の指定方法はjoin()メソッドと同じ

CROSS JOIN(交差結合)

SQL
-- テーブル1とテーブル2を交差結合する
SELECT カラム名 FROM テーブル名1 CROSS JOIN テーブル名2;


クエリビルダ
use Illuminate\Support\Facades\DB;

// テーブル1とテーブル2を交差結合する
DB::table('テーブル名1')->crossJoin('テーブル名2')->get();

sailにphpMyAdminを追加

docker-compose.yml修正

Laravel Sailで環境構築が済んでいること

Sailの中身はDockerですので、Laravelプロジェクト直下にあるdocker-compose.ymlを修正します。
phpMyAdminに関する情報を、servicesブロック内に追記します。

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    laravel.test:
...
    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        links:
            - mysql:mysql
        ports:
            - 8080:80
        environment:
            #PMA_USER: "${DB_USERNAME}"
            #PMA_PASSWORD: "${DB_PASSWORD}"
            PMA_HOST: mysql
        networks:
            - sail
...

sail起動後、sail up
以下のURLにアクセスします。http://localhost:8080/

.envに記載している、DBのユーザとパスワードでログイン

DB_USERNAME=sail
DB_PASSWORD=password

Laravel Bladeテンプレート

データの表示

  1. 【コントローラ側】 変数をビューに渡す
  2. 【ビュー側】 コントローラから受け取った変数を{{}}で囲む
    変数をビューに渡すには、上記のようにview()ヘルパ関数の第2引数にPHPのcompact()関数を指定する方法が一般的   compact()関数の引数にはビューに渡す変数名を文字列で指定、先頭の$(ドル記号)は不要
    コントローラ側
class HelloController extends Controller {
    public function index() {
        $name = 'へのへのもへじ';

        // 変数$nameをindex.blade.phpファイルに渡す
        return view('index', compact('name'));
    }
}

ビュー側

<!--======== 前略 ========-->

<body>
    <p>こんにちは、{{ $name }}さん!</p>
</body>

</html>

ブラウザ
こんにちはへのへのもへじさん

ディレクティブ

代表的なディレクティブ

Laravelの代表的なディレクティブ 処理の内容
@if () ~ @elseif () ~ @else ~ @endif PHPのif文
@for () ~ @endfor PHPのfor文
@while () ~ @endwhile PHPのwhile文
@foreach () ~ @endforeach PHPのforeach文
@csrf CSRFからの保護

@foreachの例
--Controller.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller {
    public function index() {
        $name = 'へのへのもへじ';
        $languages = ['HTML', 'CSS', 'JavaScript', 'PHP'];
        // 変数$name、$languagesをindex.blade.phpファイルに渡す
        return view('index', compact('name', 'languages'));
    }
}

index.blade.php

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BladeTemplate</title>
</head>

<body>
    <p>こんにちは、{{ $name }}さん!</p>
    <ul>
        @foreach($languages as $language)
            <li>{{ $language }}</li>
        @endforeach
    </ul>
</body>
</html>

こんにちはへのへのもへじさん

Laravel ビューの基本

ビューの作成

resources/viewsフォルダの中に手動で作成。ファイル名は○○○.blade.php 表示はルーティングやコントローラでLaravelview()ヘルパ関数でviewを返す。
view()ヘルパ関数でビューを指定するときはresources/viewsを省略し、フォルダ名.ファイル名(.blade.phpは不要)と記述 ---Controller.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller {
    public function index() {
        return view('index');
    }
}