普通の日記ですこの広告は、90日以上更新していないブログに表示しています。Symfony始める前に昨日、Jobeetデザインコンテストを開始しました。参加したいならばチュートリアルで開発しているメインページのアーカイブを使ってください(アーカイブは静的なHTMLファイル、スタイルシート、画像を含みます)。21日目に投票をするので、前日までにデザインのモックアップを(fabien.potencier[.at.]symfony-project.org)まで送ってください。健闘を祈ります!前回までのJobeet4日目を完璧にこなしているなら、MVCパターンはもう熟知できていて、ますますコーディングの方法を性質ごとにしたいと考えるようになっているでしょう。時間をかけて学ぶことで、振り返らないようになるでしょう。昨日のチュートリアルで、Jobeetのページデザインや処理のカスタマイズをし、レイアウトやヘルパー、スロットといったsymfonyのコンセプトについても見直しました。今日は、symfonyのルーティングフレームワークのすばらしい世界へダイブしましょう。いうURLを見慣れているでしょう。symfonyはどうやって動作しているのでしょうか?symfonyはどうやってこのURLを基本としてactionを決めているのでしょうか?なぜ仕事のidは$request->getParameter('id')で取得できるのでしょうか?今日は、これら全ての問題の答えを見ていきます。初めに、URLとURLが正確に指すものについて話します。Webコンテキスト上で、URLはWebリソースのユニークな名前です。URL先へ行くと、ブラウザにURLによって分類されているリソースを取得するように頼みます。URLはWebサイトとユーザ間のインターフェースとして、リソースが参照している意味のある情報を伝えます。旧来のURLは実際にはリソースについての説明をしておらず、アプリケーションの内部構造を公開してしまっています。ユーザはWebサイトがPHPで開発されているとか、仕事が持つデータベースのある識別子というようなことはあまり気にしません。アプリケーションの内部動作を公開することはセキュリティの観点から見ても、非常にまずいです。ユーザがURL先にアクセスすることなくリソースを予想することができたらどうだろうか?開発者は適切な方法でアプリをセキュアすべきで、機密情報は隠した方がよいです。URLはsymfonyでフレームワーク全体を管理するのに重要なものです。それはルーティングフレームワークで管理します。ルーティングは内部URIと外部URLを管理します。リクエストを受け取った時、ルーティングはURLを解析して内部URIに変換します。showSuccess.phpテンプレートで仕事のページの内部URIをすでに見ています。'job/show?id='.$job->getId()url_for()ヘルパーはこの内部URIを適切なURLに変換します。/job/show/id/1内部URIはいくつかのパーツから構成されます。jobはモジュール名で、showはアクション名、その後にアクションに渡すパラメータをクエリストリングとして追加します。内部URIの一般的なパターンを下記に示します。MODULE/ACTION?key=value&key1=value1&...symfonyのルーティングは2つの処理方法があるので、技術的実装を変更することなくURLを変換することができます。このことはフロントコントローラデザインパターンの主なアドバンデージの1つです。内部URIと外部URL間のマッピングはrouting.ymlファイルで行われます。/:module/:action/*routing.ymlはルートについて記述されています。ルートは名前(homepage)、パターン(/:module/:action/*)といくつかのパラメータ(paramキー下の値)を持ちます。リクエストが来たとき、URLから得られるパターンにマッチするかを試します。routing.yml内の最初にマッチしたルートが重要となります。このルーティングの動作を理解するためにもっとたくさんの例を見ることにしましょう。URLを持つJobeetホームページにリクエストをすると、マッチする最初のルートはdefault_indexです。後にマッチする何か」ということを意味します。この例の中では、module変数は値としてjobを持ちます。この値は$request->getParameter('module')で取得することができます。このルートはaction変数にはデフォルト値が定義されています。よってこのルートにマッチする全てのURLのリクエストはactionパラメータにはindexという値を持つようになります。ページにリクエストするなら、symfonyは最後のパターンである(/:modules/:action/*)にマッチします。パターン内ではスター(*)はスラッシュ(/)で分けられた変数と値のペアの一群にマッチします。1module、action変数は実行するアクションを決定するため、symfonyによって使われる特別なものです。URLは下記で使われているurl_for()ヘルパーによってテンプレートから作られます。<?phpurl_for('job/show?id='.$job->getId())@をプリフィックスにしたルート名も使えます。<?phpurl_for('@default?id='.$job->getId())上記2つは同じものですが、後者の方が全てのルートを解析することなくベストなマッチングをするため速く動作しますし、実装する上でもより少ないコードになります(モジュール名、アクション名を内部URI内に含まないので)。URLにリクエストすると、symfonyのデフォルトのcongratulationsページになります。その理由はこのURLがhomepageルートにマッチしているからです。Jobeetホームページとして意味をなすために変更します。変更するには、homepageルートのmodule変数の値をjobに変更します。}レイアウト内のJobeetロゴのリンクをhomepageルートを使うように変更します。</a></h1>簡単でしょう!少しややこしくなりますが、もっと意味のある仕事のページのURLに変更してきましょう。LabsがフランスのパリでWeb開発者を探しているということが理解できます。きれいなURLはユーザに情報を伝える上で重要となります。メールの中でURLをコピペしたり検索エンジン向けに自分のWebサイトを最適化するのに役立ちます。URLを下記のようなパターンにマッチさせます/job/:company/:location/:id/:positionrouting.ymlファイルを編集し、先頭にjobルートを追記します。}Jobeetホームページをリフレッシュするなら、仕事へのリンクは変更しません。ルートを生成するなら、必要な変数を全て渡すことが必要となります。indexSuccess.php内で呼ばれるurl_for()を変更する必要があります。'&location='.$job->getLocation().'&position='.$job->getPosition())内部URIは配列として表すこともできます。初日のチュートリアルの間、良い結果をもたらすバリデーションとエラーハンドリングについて話しました。ルーティングシステムはバリデーション要素がビルトインされています。各パターンの変数はルート定義の中のrequirementsエントリを使って正規表現によるバリデーションができます。\d+上記のrequirementsエントリはidが数値であることを強制しています。数値でなければルートにはマッチしません。ルートクラスrouting.ymlで定義されている各ルートは内部でsfRouteオブジェクトに変換されます。このクラスはルート定義のclassエントリで定義することで変更可能です。HTTPプロトコルをよく知っているのなら、GET、POST、HEAD、DELETE、PUTのようなメソッドを定義することもできます。PUT)はサポートされていません。あるリクエストメソッドだけにマッチするようルートを制限するには、sfRequestRouteクラスを使うようにルートクラスを変更して、requirementsエントリにsf_method変数を追加できます。[GET]あるHTTPメソッドだけに必要なルートがマッチするようにするのはsfWebRequest::isMethod()をアクション内で使うのと同じことです。オブジェクトルートクラス仕事ページの新しい内部URIはかなり長く、書くのがつまらないものです。前のセクションで学習したようにルートクラスは変更できます。jobルートにとってPropelオブジェクトやその一群を示すために最適化されたクラスであるsfPropelRouteを使うのはよりよいことです。[GET]optionエントリはルートの振る舞いをカスタマイズします。ここでは、modelオプションはルートに関係するPropelモデルクラス(JobeetJob)を定義して、typeオプションではこのルートに関係するオブジェクトを定義します(オブジェクトの一群を示すならlistも使えます)。job_show_userルートはJobeetJobオブジェクトの関係を知らないので、url_for()で呼ぶのは簡単です。$job)最初の例はオブジェクトに複数の引数を渡したいとき必要となります。ルート内の全ての変数はJobeetJobクラスのアクセサと対応して動きます(例えば、companyルートの変数はgetCampany()の値に置き換えれます)。生成されたURLを見ると、それらはまだ完全に欲しいURLにはなっていません。http://jobeet.localhost/frontend_dev.php/job/Sensio+Labs/Paris%2C+France/1/Web+Developer全ての非ASCII文字をハイフン(-)に置き換えたカラム値にする必要があります。JobeetJobファイルを開いて、クラスへ下記メソッドを追加してください。Jobeet::slugify($this->getLocation());}それから、lib/Jobeet.class.phpファイルを作ってslugifyメソッドを追加してください。}}3つの新しい仮想アクセサを定義しました。getLocationSlug()です。このアクセサは対応するカラム値をslugify()メソッドに適用した値を返します。今からjob_show_userルートの実際のカラム名をこれら仮想カラム名に置き換えます。[GET]Jobeetホームページをリフレッシュする前に新しいクラスを追加したのでキャッシュを消す必要があります。ccこれで期待したURLが利用できるようになります。http://jobeet.localhost/frontend_dev.php/job/sensio-labs/paris-france/4/web-developerしかし、話の半分が終わっただけです。ルートはオブジェクトを基づいたURLを生成できますが、得られたURLから関連するオブジェクトを見つけることもできます。関連オブジェクトはルートオブジェクトのgetObject()メソッドを使って取得できます。入ってきたリクエストを解析するとき、ルーティングはアクション内で使うためマッチしたルートオブジェクトを保存します。executeShow()メソッドをgetObject()を使うように変更できます。...}もし未知のIDの仕事を取得しようとするなら404エラーページを見れますが、エラーメッセージが変更されているでしょう。この理由は404エラーがgetRoute()メソッドによって自動で投げられているからです。executeShow()メソッドはもっと単純にできます。...}もしルートで404エラーを作りたくないなら、allow_emptyルーティングオプションにtrueをセットできます。アクションとテンプレートにおけるルーティングテンプレートではurl_for()ヘルパーは内部URIを外部URLに変換します。その他のsymfonyヘルパーにも引数として内部URIを持つものがあります。タグを生成するlink_to()ヘルパーがその1つです。?>下記のようなHTMLコードを生成します。Developer</a>url_for()とlink_to()の両方とも絶対パスでもURLを生成できます。アクションからURLを生成したいなら、generateUrl()メソッドが使えます。delete)のURLはまだdefaultルートで管理されています。/:module/:action/*defaultルートは多くのルートを定義することなくコーディングを始めれるすばらしい方法です。全てのアクションをキャッチしてしまうので固有の設定が必要でも設定できません。jobアクションはJobeetJobモデルクラスと関連しているので、もうshowアクションに適応させているように簡単にカスタムしたsfPropelRouteルートを定義できます。jobモジュールはモデルで利用される典型的な7つのアクションを定義しますが、sfPropelRouteCollectionクラスも利用できます。}上記jobルートは実際には下記に示す7つのsfPropelRouteルートを自動的に生成しています。}sfPropelRouteCollectionで生成されたいくつかのルートは同じURLを持ちます。それらは要求するHTTPメソッドが全て異なっているので使うことができます。job_deleteとjob_updateルートが必要としているHTTPメソッドはブラウザでサポートされていません(DELETEとPUT)。この動作はsymfonyがシミュレートしているので動きます。例を見るために_form.phpテンプレートを開いてください。?>全てのsymfonyヘルパーは特有のsf_methodパラメータを通って要求されたHTTPメソッドは何でもシミュレートさせます。symfonyはsf_methodのようなsf_を接頭辞とする特有のパラメータをそれ以外にも持ちます。上記のルート生成の中で、別のパラメータが見れます。それはsf_formatであり、次の日に説明します。ルートのデバッグコレクションルートを使うなら、生成されたルートを一覧するのが時々役立ちます。app:routesタスクはアプリケーションから得られた全てのルートを出力します。frontend引数にルート名を追加することで指定したルートに関するたくさんのデバッグ情報を取得できます。job_editデフォルトルート全てのURLにルートを定義することは良い練習になります。定義し終えたなら、routing.ymlファイルからdefaultルートを削除するかコメントアウトしましょう。Services実践入門を読みました最近読んだ本Dockerを読みました月別アーカイブはてなブログをはじめよう!Kiskeさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。