例如:
我知道如何匹配www.domain.com/foo/21
sub foo : Path('/foo') Args(1) {
my ( $self, $c, $foo_id ) = @_;
# do stuff with foo
}
Run Code Online (Sandbox Code Playgroud)
但是如何匹配www.domain.com/foo/21或www.domain.com/foo/21/bar/56?
sub foo : <?> {
my ( $self, $c, $foo_id, $bar_id ) = @_;
# do stuff with foo, and maybe do some things with bar if present
}
Run Code Online (Sandbox Code Playgroud)
谢谢
更新: 根据Daxim的建议,我尝试使用:正则表达式
sub foo : Regex('foo/(.+?)(?:/bar/(.+))?') {
my ( $self, $c ) = @_;
my ( $foo_id, $bar_id ) = @{ $c->req->captures };
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用; 网址匹配,但$ bar_id始终为undef.如果我从正则表达式的末尾删除了可选的opperator,那么它会正确捕获$ bar_id,但是必须同时存在foo和bar才能获得url匹配.我不确定这是一个perl正则表达式问题,还是催化剂问题.有任何想法吗?
更新:
正如Daxim指出的那样,它是一个正则表达式问题.我不明白为什么上面的正则表达式不起作用,但我确实设法找到了一个:
sub foo : Regex('foo/([^/]+)(?:/bar/([^/]+))?') {
my ( $self, $c ) = @_;
my ( $foo_id, $bar_id ) = @{ $c->req->captures };
}
Run Code Online (Sandbox Code Playgroud)
(我没有像Daxim那样在捕获中使用\ d +,因为我的id可能不是数字)
感谢大家的帮助和建议,我在Catalyst:D中学到了很多关于处理网址的知识
该Args属性不具备局限于的参数的具体数量.例如,以下应该有效:
sub foo :Args() { # matches /foo, /foo/123, /foo/123/bar/456, /foo/123/bar/456/*
my($self, $c, $foo_id, %optional_params) = @_;
if($optional_params{bar}){
# ...
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,路径前缀和操作名称后面的所有剩余URL段都将出现在@remainder.此外,由于您没有指定所需的参数数量,因此Catalyst将允许没有任何args的URL匹配此操作.相应地验证您的输入!
更新:链式示例
以下(未经测试的)催化剂操作将为您提供一些您似乎正在寻找的更严格的动作匹配.缺点是您必须依靠存储来在所有操作之间共享数据.
sub foo :Chained('/') :PathPart :CaptureArgs(1) {
my($self, $c, $foo_id) = @_;
$c->stash->{foo_id} = $foo_id; # or whatever
}
sub foo_no_bar :Chained('foo') :Args(0) {
my($self, $c) = @_;
# matches on /foo/123 but not /foo/123/bar/456
my $foo_id = $c->stash->{foo_id};
}
sub bar :Chained('foo') :PathPart :Args(1) {
my($self, $c, $bar_id) = @_;
my $foo_id = $c->stash->{foo_id};
# matches on /foo/123/bar/456 but not /foo/123 or /foo/123/baz/456
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1937 次 |
| 最近记录: |