Laravel 演習入門

ランダムな名言

Controller の基礎

問題

GET /random にアクセスすると、ランダムに名言とそれを言った偉人名を出力する web アプリを作成してください。


問題は、以下の手順で解いてください。

  1. Red:小さいテストを作成し、失敗を確認してください
  2. Green:テストを成功させてください
  3. Refactor:整理・整頓してください
  4. 必要に応じて、1から3を繰り返してください

ヒント

背景知識
便利なアサーションの例

アサーションの調べ方 も合わせてご覧ください。
今回は、以下を使うのではないかと思います。

解答例

続きを読む

実行環境:

Red

テストを作成し、実行し、失敗を確認します。
bash:

php artisan make:test InspiringTest

tests/Feature/InspiringTest.php:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Inspiring;
use Tests\TestCase;

class InspiringTest extends TestCase
{
    public function test_出力が名言一覧に含まれている(): void
    {
        $response = $this->get('/random');
        $content = trim($response->getContent());
        $this->assertTrue(Inspiring::quotes()->contains($content));
    }
}

Green

ルーティングファイルから、ランダムにレスポンスします。
route/web.php:

<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Inspiring;

Route::get('/random', function () {
    $quotes = Inspiring::quotes();
    $quote = $quotes->random();
    return $quote;
});

テストを実行し、成功を確認します。
bash:

php artisan test ./tests/Feature/InspiringTest.php

Refactor

ルーティングファイルでは、ルーティングのみを行いたいです。ほかの処理は、別に書きましょう。
コントローラーを作ります。
bash:

php artisan make:controller InspiringController

コントローラーファイルを編集します。
app/Http/Controllers/InspiringController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Foundation\Inspiring;

class InspiringController extends Controller
{
    public function random()
    {
        $quotes = Inspiring::quotes();
        $quote = $quotes->random();
        return $quote;
    }
}

ルーティングをコントローラーに向けます。
routes/web.php

<?php

use Illuminate\Support\Facades\Route;

Route::get('/random', [InspiringController::class, 'random']);

テストが成功することを確認します。
bash:

php artisan test tests/Feature/InspiringTest.php

解説

続きを読む

コントローラーについて

今回の Green の例のように、ルーティングに処理を書いてしまうことも可能ではあります。

しかし、ルーティングファイルには、ルーティングだけを書きたいです。
今回は、たった3行の処理でしたが、たとえば100行の処理をするページが100種類あったら、それだけで1万行のファイルになってしまいます。
そんなルーティングファイル、絶対にメンテナンスしたくないでしょう。

そこで、メイン処理をまとめる場所として、コントローラーがあります。

コントローラーは、処理の司令塔です。
データベース処理から画面表示まで、さまざまな処理の指示を書く場所です。

今回の処理は、メソッドを呼び出すだけの簡単なものだったので、ここに直接書いています。
しかし、将来、もっといろんな処理が必要になってきます。
そのような処理を小分けにして、外部ファイルに切り出し、それを呼び出す指示をコントローラーに書きます。

ルーティングからコントローラーの呼び出し

Route::get('/inspire', [InspiringController::class, 'index']);

この書き方は、最初ギョッとすると思うのですが、これは Laravel 独自の規約ではなく、 PHP の仕様上、このような書き方にするルールです。
本当は(他のプログラミング言語なら)、こう書きたいはずです:

// これは動きません!
Route::get('/inspire', InspiringController->index );

意味としては、「/inspire に GET リクエストが来たら、 InspiringContoller->index() を実行してください」ということです。

しかし、引数として関数やメソッドを渡すとき、 PHP では以下のように決められた方法で渡す必要があります。

ちなみに、 InspiringController::class というのは、その class の名前空間付き正式名称(今回の場合は App\Http\Controllers\InspiringController)を文字列として出力するだけの、静的メソッドです。
つまりこれは、オブジェクトではなく、ただの文字列が入った配列です。

Note

なぜこのような書き方になるのか、興味がある方は、「PHP コールバック関数」「PHP Callable」「PHP 第一級オブジェクト 関数」などで調べみてください。


<= 問題を読んだ・解いた・理解したなどのチェックにご利用ください。クリックすると、チェックが変化します。
問題一覧に戻る