8. Routingとリンク

Laravelのリンク

相対パスの問題

システム開発でURLリンクする時は、相対パスが一般的ですが、プログラムで相対リンクをするには現在のURLから見て、どこのURLにアクセスするかが重要です。

「/search」から「/item/1」

例えば、現在のURLが「http://localhost:8000/search」から、「http://localhost:8000/item/1」へのアクセスリンクは以下のようになります。

<a href="./item/1">詳細</a>

「/item/1」から「/item/edit/1」

次に、現在のURLが「http://localhost:8000/item/1」から、「http://localhost:8000/item/edit/1」へのアクセスリンクは以下のようになります。このように、現在のパスを意識しながらプログラミングするのはとても非効率です。

<a href="../edit/1">編集</a>

ルート名

LaravelのRouting設定では、ルート名というラベルのようなものを設定でき、現在のパスを意識することなくリンクできます。

nameメソッド

「Routing」クラスの「name」メソッドでルート名を設定できます。

Route::get(パス, ルーティング)->name(ルート名);

routeヘルパー

routeヘルパーは、設定したルート名でURLリンクを自動生成してくれるメソッドです。

route(ルート名);

aリンク

aリンクでリンクする場合、「href」プロパティに「route」を指定します。

<a href="{{ route(ルート名) }}">リンク</a>

routeのGETパラメータ

リンクにGETパラメータをつけることもできます。パラメータは、route() の第2引数に連想配列で指定するのが基本です。

<a href="{{ route(ルート名, [キー1 => 値1, キー2 => 値2, ...]) }}">リンク</a>

idパラメータ

リンクにGETパラメータをつけることもできます。パラメータは、route() の第2引数に連想配列で指定するのが基本です。

<a href="{{ route(ルート名, ID) }}">リンク</a>

Routeでリンク

ファイル構成

/
├── about.blade.php
├── components/
│         ├── head.blade.php
│         └── nav.blade.php
├── item
│         ├── edit.blade.php
│         └── show.blade.php
├── layouts
│         └── app.blade.php
├── search.blade.php
└── welcome.blade.php

トップページリンク

ナビゲーションコンポーネント作成

ナビゲーション用のコンポーネント「components/nav.blade.php」を作成して、ページリンクします。ナビゲーションの構成はBootstrap5を利用します。

nav.blade.php
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">Home</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
      <div class="navbar-nav">
        <a class="nav-link" href="#">About</a>
        <a class="nav-link" href="#">Search</a>
      </div>
    </div>
  </div>
</nav>

ルーティング設定

トップページのルーティング「 / 」に、ルート名「 / 」を設定します。

web.php
Route::get('/', function () {
    return view('welcome');
})->name('/');

リンク設定

ナビゲーションコンポーネントの「Home」リンクをルート名「 / 」で設定します。

nav.blade.php
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container-fluid">
    <a class="navbar-brand" href="{{ route('/') }}">Home</a>
    ...

リンク確認

「Home」リンクをクリックしてトップページにリンクするか確認してみましょう。

その他ページリンク

「About」ページ、「Search」ページにリンクしてみましょう。

ルーティング設定

ルート名はできるだけ、URLパターンとあわせつつ意味を持つキーワードにすると管理しやすくなります。また、パラメーター部分は不特定な値なのでルート名に追加はしません。

web.php
Route::get('/about', [HomeController::class, 'about'])->name('about');
Route::get('/search', [HomeController::class, 'search'])->name('search');
Route::get('/item/{id}', [ItemController::class, 'show'])->name('item.show');
Route::get('/item/edit/{id}', [ItemController::class, 'edit'])->name('item.edit');

ルーティング一覧

ページ URL ルート名
トップ / /
About /about about
検索 /search search
商品詳細 /item/{id} item.show
商品編集 /item/edit/{id} item.edit

リンク作成

ナビゲーションコンポーネントに、「About」「検索」ページのリンクを追加します。

nav.blade.php
<a class="nav-link" href="{{ route('about') }}">About</a>
<a class="nav-link" href="{{ route('search') }}">Search</a>

フォーム

FormタグのactionでURLを指定し、検索をしてみましょう。

search.blade.php
<form action="{{ route('search') }}" method="get">
    <input class="form-control" type="text" name="keyword">
    <button class="btn btn-primary">検索</button>
</form>

パラメータつきリンク

編集リンク

ルーティング設定

「ItemController」クラスの「show」メソッドで、「id」パラメータをBladeに受け渡します。

ItemController.php
    public function show(int $id)
    {
        $items = [
            1 => "コーヒー",
            2 => "紅茶",
            3 => "ほうじ茶",
        ];
        $item = "";
        if ($id > 0 && array_key_exists($id, $items)) $item = $items[$id];
        $data = ['item' => $item, 'id' => $id];
        return view('item.show', $data);
    }

リンク追加

「item/show.blade.php」に編集リンクを追加します。

item/show.blade.php

パラメータ

@extends('layouts.app')

@section('content')
<h2 class="mt-2">商品名</h2>
<p>{{ $item }}</p>
<div>
    <a href="{{ route('item.edit', $id) }}">編集</a>
</div>
@endsection

編集画面

パラメータ取得

「ItemController」クラスの「edit」メソッドで、「id」パラメータをBladeに受け渡します。

    public function edit(int $id)
    {
        $data = ['id' => $id];
        return view('item.edit', $data);
    }

パラメータ確認

「item/show.blade.php」でID表示と戻るリンクを追加します。

item/edit.blade.php
@extends('layouts.app')

@section('content')
<h2 class="mt-2">商品編集</h2>
<p>{{ $id }}</p>
<div>
    <a href="{{ route('item.show', $id) }}">戻る</a>
</div>
@endsection

動作確認してみましょう。

Laravel超入門