SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Webアプリケーションフレームワーク「Catalyst」入門

初めてのCatalyst入門(4) URLパスとリクエストパラメータ

リクエスト情報やパラメータ、日本語文字列などのデータの取り扱い方法


  • X ポスト
  • このエントリーをはてなブックマークに追加

サンプルアプリケーション

 今回もサンプルアプリケーションで実際のコードを確認しながら説明していきます。この例では「ParamSample」という名前で作成します。

[リスト5]「ParamSample」アプリケーションのスケルトンを作成する
$ catalyst.pl ParamSample

 また、サンプルではビューを使用しますので、「<MyApp>_create.pl」を使用してビューを作成しておきます。ヘルパスクリプトに渡すパラメータは次のようになります。

[リスト6]ビューを作成するパラメータ
$ <MyApp>_create.pl view 作成するビューモジュール名 使用するヘルパモジュール名

 今回のサンプルではビューモジュールとして「Catalyst::View::TT」を使用しますので、次のようにパラメータを指定してヘルパスクリプトを実行します。

[リスト7]ビューを作成する
$ ./ParamSample/script/ParamSample_create.pl view TT TT
実行結果
 exists "/home/test/ParamSample/script/../lib/ParamSample/View"
 exists "/home/test/ParamSample/script/../t"
created "/home/test/ParamSample/script/../lib/ParamSample/View/TT.pm"
created "/home/test/ParamSample/script/../t/view_TT.t"

 本記事のサンプルコードは、すべてUTF-8で保存しています。

URLパスの取り扱い

 :Regex:Pathアトリビュートなどを使用すれば、コントローラのネームスペースに依存することなくパスを自由に定義することが出来ます。ここからはパスの一部を引数として受け取る方法や一部が重複するパスを別々に定義した場合に、どのような基準でアクションにマッチするのか、について説明します。

パスの一部を引数として受け取る

 これまで説明したように、パスの一部を引数として渡すことができますが、「$c->req->args」から取得する以外に、メソッドの引数として受け取ることも出来ます。次の例では、正規表現アクションで2つの引数を受け取る場合のアクション定義を示します。正規表現アクションの場合には、定義したパターンの末尾が「$」である必要があります(そうしなければどこからが引数か区別がつけられないため)。

 次の例では、Root.pmParamSample::Controller::Root)に引数を2つ受け取る「twoargs」アクションを定義しています。

[リスト8]Root.pmで引数を2つ取るアクションの例
package ParamSample::Controller::Root;

# 省略

sub twoargs :Regex('^twoargs$') {
  my ( $self, $c, $first, $second ) = @_;
  $c->response->body( "First: $first, Second: $second" );
}

 メソッドの最初の行で、「@_」から自分自身である「$self」、コンテキスト「$c」の後に、「$first」、「$second」と2つの引数を受け取っています。そしてレスポンスにそれぞれの値を表示させるようにしています。

 次のURLをブラウザで表示させた場合には、$firstに「aaa」が、$secondに「bbb」が設定されていることを確認することが出来ます。

http://<ホスト名またはIPアドレス><:Port>/twoargs/aaa/bbb
「twoargs/aaa/bbb」を表示した画面
「twoargs/aaa/bbb」を表示した画面

 ここで、「/twoargs/aaa」のように2番目のパス要素が省略された場合には、$secondには未定義値が割り当てられます。

指定したパスにマッチする基準

 それではパスの一部が重なる場合に、どのような基準で実行するアクションが決められるのでしょうか? 次のように先頭から「boo/foo/woo」に重複するパスを定義した場合について考えます。

パスの一部が重複するアクションの例
パス アクション
boo boo
boo/foo foo
boo/foo/woo woo

 上の表にあるアクションをRoot.pmに定義してみると次のようになります。

[リスト9]Root.pmでパスの重なる定義を行ったアクションの例
package ParamSample::Controller::Root;

# 省略

sub boo :Path('boo') {
  my ( $self, $c, $first, $second ) = @_;
  $c->response->body( "First: $first, Second: $second at boo" );
}
sub foo :Path('boo/foo') {
  my ( $self, $c ) = @_;
  $c->response->body( 'boo/foo' );
}
sub woo :Path('boo/foo/woo') {
  my ( $self, $c ) = @_;
  $c->response->body( 'boo/foo/woo' );
}

 ここで次のURLをブラウザで表示させると、「woo」アクションが実行されていることが確認できます。

http://<ホスト名またはIPアドレス><:Port>/boo/foo/woo

 このように、リクエストされたパスが複数の定義にマッチする場合には、一致部分がもっとも長いアクションに処理が割り当てられます。

 もし、次のように全く同じパス「/a/b」が割り当てられる場合には、Catalystが最初に見つけたアクションが実行されるため、環境やバージョンによっては呼び出されるアクションが異なる場合があります。

[リスト10]Root.pmで「/a/b」をPathアトリビュートで定義した場合
package ParamSample::Controller::Root;

# 省略

sub match_a_b :Path('/a/b') {
  my ( $self, $c ) = @_;
  $c->response->body( 'Path /a/b' );
}
[リスト11]ParamSample::Controller::Aで「b」アクションを定義した場合
package ParamSample::Controller::A;

# 省略

sub b :Local {
  my ( $self, $c ) = @_;
  $c->response->body('b in ParamSample::Controller::A');
}

 よってこのように複数の定義が重なるようなURLを定義すべきではありません。

次のページ
リクエストパラメータの扱い

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Webアプリケーションフレームワーク「Catalyst」入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 花田 善仁(ハナダ ヨシヒト)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4538 2010/06/11 15:10

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング