👩‍💻

Symfony3公式チュートリアル「Create your First Page in Symfony」を実施する

7 min read

これは何?

公式ページの Create your First Page in Symfony を試したときのメモです。[1]
前記事「Windows10でSymfony3を動かす」の続きです。

動作検証環境

ローカルwebサーバを立ち上げる

作成済の test_project に移動して、ローカルwebサーバを立ち上げます。

cd test_project
symfony server:start

http://127.0.0.1:8000/ にアクセスできることを確認します。

ルートとコントローラの設定

チュートリアルでは、 http://127.0.0.1:8000/lucky/number にアクセスしたとき、ランダムな数字が表示されるページの作成を行うようです。
試しにアクセスしてみると、現状は HTTP 404 Not Found が表示されます。

まずは /lucky/number にアクセスがあったとき、どのような処理を行うか定義する「コントローラ」を作成します。(今回の場合は、「ランダムな数字を表示する」。)
src/Controller/ の中に、LuckyController.php というファイルを新規作成し、以下の内容を記載します。

src/Controller/LuckyController.php
<?php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class LuckyController
{
    public function number()
    {
        $number = random_int(0, 100);

        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }
}

このコントローラの書き方だと、単に number() メソッドを定義しているだけなので、見た目上は特になにも変わりません。/lucky/number にアクセスがあったとき、作成した LuckyController クラスの number() メソッドを使うためにルーティングを設定します。

config/routes.yaml に以下の内容を追記します。

config/routes.yaml
# the "app_lucky_number" route name is not important yet
app_lucky_number:
    path: /lucky/number
    controller: App\Controller\LuckyController::number

再度、http://127.0.0.1:8000/lucky/number にアクセスしてみます。
Lucky number が表示されていたら成功です。

ここで私は、404エラーのままでハマってしまいました。
原因は「URLの最後に/を入れていたから」。(「トレイリングスラッシュ」というそうです。)
OK:http://127.0.0.1:8000/lucky/number
NG:http://127.0.0.1:8000/lucky/number/
その他、numberをnunberとしてしまっていたり……。typoにはご注意ください。

アノテーションを使ったルーティング

config/routes.yaml にルーティングを列記していく以外に、アノテーションを使って各コントローラーに直接ルーティングを書くことができます。
src/Controller/LuckyController.php を以下のように書き換えます。

src/Controller/LuckyController.php
<?php
  namespace App\Controller;
  
  use Symfony\Component\HttpFoundation\Response;
+ use Symfony\Component\Routing\Annotation\Route;

  class LuckyController
  {
+     /**
+      * @Route("/lucky/number")
+      */
      public function number()
      {
          $number = random_int(0, 100);
  
          return new Response(
              '<html><body>Lucky number: '.$number.'</body></html>'
          );
      }
  }

config/routes.yaml に追記した内容を削除します。

config/routes.yaml
- app_lucky_number:
-     path: /lucky/number
-     controller: App\Controller\LuckyController::number

再度、http://127.0.0.1:8000/lucky/number にアクセスして、先程とは別のLucky number が表示されたら成功です。

404になってしまった場合、 src/Controller/LuckyController.php に追加した @Route の3行は、public function number() の上になっているか、typoしていないか確認してみてください。

ルートを確認する

公式サイトには「Annotations are the recommended way to configure routes.」とあったので、YAMLを使ったルーティングとアノテーションを使ったルーティング、どちらを使うか迷うようであればアノテーションを使う方がいいかもしれません。
アノテーションを使うと、アクションとの関連性がわかりやすい一方、全体を俯瞰して見ることができないので一見不便なようにも感じます。
でも大丈夫です。ルートの一覧を見るコマンドが用意されています。

新たにコマンドプロンプトを開いて(今開いているのはローカルwebサーバが起動していて操作できないので)、test_project に移動し、以下のコマンドを打ちます。

php bin/console debug:router

エクスプローラーで test_project を開いている場合は、アドレスバーに cmd と入力すると、その場所からコマンドプロンプトが開けるので、cd で移動が不要です。

「'php' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」というメッセージが出る場合、phpが入っていないかパスが通っていません。ページ上部の「動作検証環境」にPHPのインストール方法とパスの通し方の参考URLを貼っていますのでご参考ください。

テンプレート(Twig)を使う

SymfonyにはデフォルトのテンプレートエンジンとしてTwigが使えるので、Twigを使って出力するように変更してみます。
src/Controller/LuckyController.php を修正します。

src/Controller/LuckyController.php
  // ...
  use Symfony\Component\Routing\Annotation\Route;
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

- class LuckyController
+ class LuckyController extends AbstractController
  {
      /**
       * @Route("/lucky/number")
       */
-     public function number()
+     public function number(): Response
      {
          $number = random_int(0, 100);

-         return new Response(
-             '<html><body>Lucky number: '.$number.'</body></html>'
-         );
+         return $this->render('lucky/number.html.twig', [
+             'number' => $number,
+         ]);
      }
    }
  }

render() で指定した lucky/number.html.twig/templates の中に新規に作成します。

templates/lucky/number.html.twig
<h1>Your lucky number is {{ number }}</h1>

再度、http://127.0.0.1:8000/lucky/number にアクセスして、Lucky number が大きく表示されたら成功です。

しかし、Webデバッグツールバー(ページ最下部に出ていたバー)が表示されなくなってしまいました。
どうやら <body> タグがないと出力されないようです。
直接追記してもいいのですが、共通した骨組み部分ですので、 base.html.twig を使って管理したいと思います。

すでに 用意されている、templates/base.html.twig の中身を確認します。

templates/base.html.twig
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        {# Run `composer require symfony/webpack-encore-bundle`
           and uncomment the following Encore helpers to start using Symfony UX #}
        {% block stylesheets %}
            {#{{ encore_entry_link_tags('app') }}#}
        {% endblock %}

        {% block javascripts %}
            {#{{ encore_entry_script_tags('app') }}#}
        {% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>

{% block body %}{% endblock %} の部分に出力させたいので、templates/lucky/number.html.twig を以下のように修正します。

templates/lucky/number.html.twig
+ {% extends 'base.html.twig' %}
+ {% block body %}
  <h1>Your lucky number is {{ number }}</h1>
+ {% endblock %}

http://127.0.0.1:8000/lucky/number にアクセスして、ページの最下部にWebデバッグツールバーが表示されていること、ソースにタグが追加されたことを確認します。

構造のまとめ

ディレクトリ名 含まれる内容
bin/ bin/console など実行可能ファイル
config/ ルート、サービス、およびパッケージを構成するためのファイル
migrations/ データベースのテーブル操作を行うためのマイグレーションファイル
public/ 静的なHTMLファイルや画像などの公開ファイル
src/ PHPコードが記載されたファイル
templates/ Twigテンプレートファイル
var/ キャッシュファイル(var/cache/)やログ(var/log/)など、自動的に作成されたファイル
vendor/ サードパーティ(ベンダー)のライブラリ
脚注
  1. 閲覧にあたって、Symfonyのバージョンを選択できるのですが、素直に3.4を選択したところ構造がだいぶ変わっていてうまくいきませんでした。バージョン3.4のSymfonyでも、デフォルトの5.2バージョンのままで動きましたので、そちらの方法でまとめています。 ↩︎

Discussion

ログインするとコメントできます