Symfony:电子邮件地址作为请求参数

时间:2009-10-19 20:25:10

标签: php .htaccess url-rewriting symfony1

我在将网址中的电子邮件地址传递给symfony应用时遇到了一些问题。

网址看起来像

example.com/unsubscribe/email/me@example.com

除非删除句号,否则始终会生成sfError404Exception。在做了一些谷歌搜索后,我看到的唯一解决方案是htaccess因为存在期间而绕过网址。但是,当我将建议的修复添加到htaccess时,如下所示:

# we skip all files with .something
RewriteCond %{REQUEST_URI} \..+$
RewriteCond %{REQUEST_URI} !@.+    #skip email address
RewriteCond %{REQUEST_URI} \.epl$
RewriteCond %{REQUEST_URI} !\.html$ 
RewriteCond %{REQUEST_URI} !\.rhtml$
RewriteRule .* - [L]

我得到相同的404.当我直接在url(example.com/index.php/unsubscribe/email/me@example.com)中使用前端控制器时,它也会返回404。我已经尝试将转义版本直接放到地址栏中,例如example.com/unsubscribe/me%40example%2Ecom,这样可行,但只适用于Firefox,而不是其他地方。

我已经花了大约2个小时在论坛上回答谷歌搜索地狱而且我的想法已经用完了。

有什么想法吗?

感谢。

更新:这是routing.yml的相关部分:

unsubscribeform:
  url:  /unsubscribe/email/:email
  param: { module: subscribe, action: index }

更新:堆栈跟踪...看起来没有获取任何路线信息给我

404 | Not Found | sfError404Exception
Empty module and/or action after parsing the URL "/unsubscribe/email/me@example.com" (/).
stack trace

1. at ()
  in SF_SYMFONY_LIB_DIR/controller/sfFrontWebController.class.php line 44 ...
          41.
          42.       if (empty($moduleName) || empty($actionName))
          43.       {
          44.         throw new sfError404Exception(sprintf('Empty module and/or action after parsing the URL "%s" (%s/%s).', $request->getPathInfo(), $moduleName, $actionName));
          45.       }
          46.
          47.       // make the first request
2. at sfFrontWebController->dispatch()
  in SF_SYMFONY_LIB_DIR/util/sfContext.class.php line 159 ...
         156.    */
         157.   public function dispatch()
         158.   {
         159.     $this->getController()->dispatch();
         160.   }
         161.
         162.   /**
3. at sfContext->dispatch()
  in /home/web/htdocs/index.php line 10 ...
           7. require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'ProjectConfiguration.class.php');
           8.
           9. $configuration = ProjectConfiguration::getApplicationConfiguration(SF_APP, SF_ENVIRONMENT, SF_DEBUG);
          10. sfContext::createInstance($configuration)->dispatch();

11

3 个答案:

答案 0 :(得分:10)

默认情况下,Symfony将./视为参数分隔符 这样可以很容易地匹配这样的URL:

/some/path/:param.:ext

但对电子邮件地址没有帮助。

幸运的是,您可以通过指定自己的模式来覆盖.分隔符 只需将以下requirements行添加到您的路由:

unsubscribeform:
  url:  /unsubscribe/email/:email
  param: { module: subscribe, action: index }
  requirements: { email: .+ }

需求中的.+是匹配任何内容的正则表达式。 .匹配任何字符,+表示匹配一个或多个。

(在Symfony 1.4中测试)

答案 1 :(得分:3)

我不知道您在Symfony中做了什么,但可能有助于明确以下内容不是有效的网址:

example.com/unsubscribe/email/me@example.com

你几乎肯定想要的(所有浏览器都是如此!)是:

http://example.com/unsubscribe/email/me%40example.com

注意:@符号不安全,必须编码,。但符号是安全的(RFC1738)。如果你没有逃脱@符号,它几乎肯定会造成大麻烦(逃避。几乎肯定不会,但你不需要这样我不会)。

在没有转义的情况下会出现问题,因为@在传递身份验证参数时会被保留为分隔符(例如http://username:password@hostname.domain/url/)。如果@出现在URL中的域之后,某些URL解析器将确定您真正打算键入%40,但其他人不会。

您不应仅仅静态编码@符号,而应使用电子邮件地址上的PHP URL编码功能之一(例如“$ emailAddress = urlencode($emailAddress);”),以确保地址中的其他字符也能正确转义。不要试图将它留到以后或“在你工作之后”从一开始就这样做并保存自己和最终用户头疼! : - )

注意:有几种方法可以在PHP中对URL进行编码,因此您需要阅读urlencode()的文档页面,并将其与rawurlencode()等其他方法进行比较,以确保它是您真正想要的。

答案 2 :(得分:0)

您的问题不在于重写规则。考虑到Symfony正在抛出异常,那么请求正在向Symfony发送。

你可以发布异常的追溯吗?如果你有sf_logging_enabled,它应该记录一些非常有用的信息来调试路由。