http://symfony.localhost/frontend_dev.php/job/show/id/3
というURLで何故frontendアプリケーションのjobActions::executeShow()が実行されるのか、というお話。
まずテンプレート上で
url_for('a/b?c=d&e=f')
と書くと、url_for関数が勝手に
<a href="frontend_dev.php/a/b/c/d/e/f">といったふうにリンクを書き換えます。
indexという文字が現れたときとかの例外はありますが、今のところは特に気にする必要はありません。
リンク先をクリックした場合、まず第一引数であるaというモジュールを探し、その中のaActions::executeB()を実行しようとします。
三番目以降の引数はリクエストパラメータとなります。
まあこれが基本なのですが、そのルーティングの設定はapps/frontend/config/routing.ymlというファイルで決定されています。
これを変更することで、一部のリクエストだけ特別な処理を行ったりすることができます。
先にマッチしたルートが実行されるので、設定の順番は狭い順にします。
とりあえずデフォルトの設定を見てみます。
最初の段落、
1
2
3
|
homepage:
url: /
param: { module: default, action: index }
|
/はindex.phpとかfrontend_dev.php/といった、引数が一個もない状態で来た場合にマッチします。
この場合、defaultモジュールのindexアクションが実行されます。
defaultモジュールは作成していませんが、Symfonyで最初から用意されているモジュールで、index以外にもerror404やdisabled、secureといった基本的なページが用意されています。
前回あったforward404Unless()は、内部的にdefaultモジュールのerror404アクションを呼び出しています。
homepage:は単なるラベルなので適当に変更してもかまいません。
ただ後述の@のためにわかりやすい名前にしておきましょう。
二段落目は
1
2
3
|
default_index:
url: /:module
param: { action: index }
|
これはモジュール名だけやってきてアクション名がなかった場合、デフォルトのアクション名はindexにするよ、というだけの内容です。
たとえば
param: { action: hoge }
に変更して
http://symfony.localhost/frontend_dev.php/job
にアクセスすると、jobモジュール内にhogeアクションが見つからないよ、というエラーになります。
http://symfony.localhost/frontend_dev.php/job/index
とアクション名まで書いた場合はきちんと表示されますが、これは最後の段落です。
1
2
|
default:
url: /:module/:action/*
|
モジュール名とアクション名が入っていれば、その後どのようなパラメータが入っていてもこの段落に当てはまります。
具体的な指定は何もありませんが、すなわちモジュール名とアクション名をそのまま何も変更しないということです。
ではルートをカスタマイズしてみましょう。
まずはチュートリアルの通りに
1
2
3
|
homepage:
url: /
param: { module: job, action: index }
|
と上書きします。
これで、引数が無い場合にはjobモジュールのindexアクションが実行されるということになり、
http://symfony.localhost/frontend_dev.php
http://symfony.localhost/frontend_dev.php/job/index
この両者が同じになります。
更にルーティングを追加。
1
2
3
4
|
job_show_user:
url: /job/:company/:location/:id/:position
param: { module: job, action: show }
requirements: {id: \d+ }
|
default:の/:module/:action/*が先に来るとそちらに引っかかってしまうので、default:より先に記述する必要があります。
そして以下のURLでアクセスします。
http://symfony.localhost/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer
urlに:が付く場合は該当するパラメータの内容を表し、付かない場合はURLそのものを表します。
url: /job/:company/:location/:id/:position
の場合、
/job/はそのものが必須であり、
http://symfony.localhost/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer
のようなURLには引っかかりますが、
http://symfony.localhost/frontend_dev.php/jobs/sensio-labs/paris-france/1/web-developer
などのURLにはひっかからないということを示します。
/:companyは、その位置に該当するパラメータということで、今回の場合は"sensio-labs"を表します。
このパラメータは、アクション内で$request->getParameter('company')として受け取ることができます。
どのような場合に使うかというと、URLをわかりやすくすることができます。
とりあえず今思いついたものとしては静的ページを配置する場合などに使えるかもしれません。
1
2
3
|
static_page:
url: /static/:name
param: { module: index, action: static }
|
としてindexActions::executeStaticで$this->setTemplate($request->getParameter('name'))とか。
requirementsエントリはリクエストパラメータの絞り込みです。
id: \d+なので、:idの位置に来る値が数値であることを要求します。
当てはまらなかった場合はstatic_page:のルーティングには該当しないということになります。
@を使用したリンクを作成してみます。
url_for('@job_show_user?id=1&position=pos&company=comp&location=loc');
とすると、URLの形式がjob_show_user:のURL形式である、/job/:company/:location/:id/:positionに合致するように変形されます。
@を使わない形式ではurl_forに配列を渡せるのに@を使用するとできないのは何故なんだろう。
長くなったので続きは後日。
これ一時間とか絶対無理だよな。
Symfonyの記事一覧
これを、分解して解説しているところは、感服いたしました。
他にも、"Practiacal symfony" を読んで違和感を覚えたところが絶妙に解説されていて、非常にスッキリします。
終わりまで続けてください。