Symfony 5.3功能测试POST参数无法传递到控制器该如何解决?
问题核心原因
你遇到的两个核心问题分别是控制器获取请求的方式不符合Symfony规范,以及大概率存在路由重定向导致POST转GET、参数丢失。
1. 修正控制器请求获取逻辑
这是最核心的问题:Request::createFromGlobals() 是从PHP全局变量($_POST/$_GET等)中读取请求参数,而Symfony测试环境的模拟请求不会修改全局变量,你手动赋值$_POST也无法被Symfony测试内核识别。
正确的做法是直接在控制器方法中注入Request对象,Symfony会自动把测试提交的参数赋值到该对象中:
use Symfony\Component\HttpFoundation\Request; // 你的控制器方法,直接注入Request public function searchResult(Request $request) { // 从POST参数中获取searchwords,$_POST对应的是$request->request $temp_searchwords = explode(' ', $request->request->get('searchwords')); // 后续原有逻辑不变 }
2. 排查POST转GET的问题
POST请求自动变成GET基本都是路由重定向导致的,最常见的两种情况:
- 你的
search_result路由定义的地址和测试请求的地址不一致,比如路由定义的是/de/search/result/(带尾部斜杠),你测试请求的是/de/search/result(不带斜杠),Symfony会自动返回301重定向到带斜杠的地址,重定向过程中请求方法会变成GET、POST参数全部丢失。 - 你的
search_result路由配置了只允许GET方法请求,触发了405重定向。
可以在测试中临时关闭自动跟随重定向确认问题:
$client->followRedirects(false); $crawler = $client->request('POST', '/de/search/result', ["searchwords" => "test"]); // 打印状态码,如果是301/302就是重定向导致的问题 dump($client->getResponse()->getStatusCode());
确认问题后把测试请求的地址和路由定义的地址保持完全一致即可。
3. 测试代码的正确写法
修正控制器和路由问题后,两种测试写法都可以正常使用:
直接发起POST请求
$crawler = $client->request('POST', '/de/search/result', ["searchwords" => "test"]); // 验证参数是否正常获取 dump($client->getRequest()->request->get('searchwords'));
表单提交写法
因为你的提交按钮只有图标没有文本,建议先给按钮加name属性方便选择:
{# 表单中的按钮增加name属性 #} <button type="submit" name="search_submit" class="btn search rounded"><i class="far fa-search"></i></button>
测试代码调整为:
$buttonCrawlerNode = $crawler->selectButton('search_submit'); $form = $buttonCrawlerNode->form(); $form['searchwords'] = "test string"; $crawler = $client->submit($form);
内容的提问来源于stack exchange,提问作者Olray
相关产品推荐
相关产品推荐

