我最近开始使用Symfony Routing 组件。
我的路由 yaml 如下所示:
custom:
path: /custom
defaults: {controller: custom, action: refresh}
methods: [POST]
schemes: [https]
default:
path: /{controller}/{action}
defaults: {controller : index, action: index}
但是,url https://my.domain.com/custom"被解析为默认路由,即使它遵循yaml文件中的自定义路由。根据我的jQuery .ajax设置和Chrome控制台,请求方法是POST:
XHR finished loading: POST "https://my.domain.com/custom".
或根据 Chrome 网络 -> 标头:
Request URL:https://my.domain.com/custom
Request Method:POST
如果我将请求方法更改为 get,保持 yaml 配置不变,它也不会起作用,这当然是意料之中的。如果我将自定义路由的 yaml 配置更改为接受 GET 而不是 POST,并发送 GET 请求,它确实可以正常工作,再次按预期。但是,如果我更改自定义路由的 yaml 配置以接受 GET 并发送 POST 请求,它可以工作,即自定义规则匹配!从某种意义上说,浏览器的 POST 请求似乎在服务器端被解释为 GET。
在这种情况下,这是某种奇怪的Chrome错误,我尝试过Firefox,结果相同。
然后我尝试打印 $_SERVER['REQUEST_METHOD'],结果符合预期,如果请求是 POST,则为 POST,如果请求是 GET,则为 GET。所以在我看来,这是Symfony的错,也许我配置错误了。
这是我相关的PHP代码:
$args = isset($_REQUEST['args']) ? $_REQUEST['args'] : '';
$request = Request::createFromGlobals();
$locator = new FileLocator(HOME_PATH . 'config');
$loader = new YamlFileLoader($locator);
$routes = $loader->load('routes.yml');
$context = new RequestContext($_SERVER['REQUEST_URI']);
$context->setScheme($request->getScheme());
$context->setHost($_SERVER['SERVER_NAME']);
$matcher = new UrlMatcher($routes, $context);
try
{
$match = $matcher->match('/' . rtrim($args, '/'));
....
}
....
我有一种强烈的感觉,我只是在这里对请求和上下文做了一些根本错误的事情,但这就是我设法让它们工作的方式,到目前为止它曾经运行良好,至少在 GET 路由上是这样。提前感谢您的帮助!
很抱歉迟到了将近两年,但我自己解决了这个问题。
您必须使用 Request 对象为 RequestContext 对象设定种子:
$request = Request::createFromGlobals();
$context = new RequestContext($_SERVER['REQUEST_URI']);
$context->fromRequest($request);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
解释:
我遇到了同样的问题(当我发现这个未回答的问题时,我感到很生气),并深入研究了源代码以弄清楚为什么它声称"GET"是每个请求的方法。
我的错误是认为 UrlMatcher 正在使用 Request 对象(转储时显示"POST"),但它没有;它使用 RequestContext 对象。
你可以在symfony/routeting/Matcher/UrlMatcher的第153行看到这一点.php
151 if ($requiredMethods = $route->getMethods()) {
152 // HEAD and GET are equivalent as per RFC
153 if ('HEAD' === $method = $this->context->getMethod()) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^
154 $method = 'GET';
155 }
。当我检查 RequestContext 类时,我发现构造函数默认为 GET:
52 public function __construct($baseUrl = '', $method = 'GET', $host = 'loc....
但我很高兴也发现了fromRequest方法,它很高兴地解释了它如何在文档块中解决我们的问题:
64 /**
65 * Updates the RequestContext information based on a HttpFoundation Request.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
66 *
67 * @param Request $request A Request instance
68 *
69 * @return RequestContext The current instance, implementing a fluent interface
70 */
71 public function fromRequest(Request $request)
72 {
73 $this->setBaseUrl($request->getBaseUrl());
74 $this->setPathInfo($request->getPathInfo());
75 $this->setMethod($request->getMethod());
76 $this->setHost($request->getHost());
77 $this->setScheme($request->getScheme());
78 $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
79 $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
80 $this->setQueryString($request->server->get('QUERY_STRING', ''));
81
82 return $this;
83 }
干杯!
我的问题是当 URL 以 /
(斜杠)结尾时我无法匹配路由