Symfony2 使用查询字符串参数路由到控制器
Symfony2 routing to controllers using querystring parameters
我目前和一位客户住在 Bizzaro World。
因为我们正在编写的 symfony 应用程序将响应注入到另一个应用程序的页面中,我们被迫只有一个 URL 用于该应用程序,但幸运的是我们确实将查询字符串完整地传递给了我们.
因此,我需要做与 symfony 做事完全相反的事情,一种老派的 MVC 方法。我需要路由通过查询字符串参数工作,路由到正确的控制器并呈现正确的响应,而不是使用标准的、理智的路径方法。
因此 url 将是 http://www.bizzaro.com/appname?route=%2fblog
而不是 http://www.bizzaro.com/appname/blog
,依此类推。
路由部分中有很好的示例,说明如何确保将查询字符串作为参数传递给控制器操作,但不适用于这种相当倒退的方法。
我从哪里开始?
我实现了下面Corentin Dandoy提出的解决方案2,但稍微修改以防止在查找根时出现循环。
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FrontControllerControllerController extends Controller
{
/**
* Forward the request to the appropriate controller
* @param Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction(Request $request)
{
// get the parameter that specifies the route to the 'real' homepage controller
$homeroute = $this->container->getParameter('homeroute');
$route = $request->query->get('route');
// Convert the query-string route into a valid path route
$path = '/'.$route;
// if it is the route, then use the 'real' homepage controller, otherwise you end up in a routing loop!
if ($path === '/')
{
$match = $this->get('router')->match('/' . $homeroute);
} else {
try {
$match = $this->get('router')->match($path);
} catch (ResourceNotFoundException $e) {
throw $this->createNotFoundException('The route does not exist');
}
}
$params = array(
'request' => $request,
);
return $this->forward($match['_controller'], $params);
}
}
解决方案 1
一个简单的解决方案(虽然不可扩展)是这样的:
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class MainController
{
/**
* @Route("/app", name="bizarro_app")
*/
public function mainAction(Request $request)
{
$route = $request->query->get('route');
switch ($route) {
case 'blog':
return $this->blogAction($request);
default:
throw $this->createNotFoundException('The route does not exist');
}
}
protected function blogAction(Request $request)
{
// Your blog page here
return new Response('...');
}
}
解决方案 2
如果你不介意有两种可用的路线,你可以试试这个:
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class MainController
{
/**
* @Route("/app", name="bizarro_app")
*/
public function mainAction(Request $request)
{
$route = $request->query->get('route');
// Convert the query-string route into a valid path
$path = '/'.$route;
try {
$match = $this->get('router')->match($path);
} catch (ResourceNotFoundException $e) {
throw $this->createNotFoundException('The route does not exist');
}
$params = array(
'request' => $request,
);
return $this->forward($match['_controller'], $params);
}
/**
* @Route("/blog", name="bizarro_blog")
*/
public function blogAction(Request $request)
{
// Your blog page here
return new Response('...');
}
}
这样,您就可以从 Sf2 路由组件中获益。
请注意,我没有亲自测试过。
我目前和一位客户住在 Bizzaro World。
因为我们正在编写的 symfony 应用程序将响应注入到另一个应用程序的页面中,我们被迫只有一个 URL 用于该应用程序,但幸运的是我们确实将查询字符串完整地传递给了我们.
因此,我需要做与 symfony 做事完全相反的事情,一种老派的 MVC 方法。我需要路由通过查询字符串参数工作,路由到正确的控制器并呈现正确的响应,而不是使用标准的、理智的路径方法。
因此 url 将是 http://www.bizzaro.com/appname?route=%2fblog
而不是 http://www.bizzaro.com/appname/blog
,依此类推。
路由部分中有很好的示例,说明如何确保将查询字符串作为参数传递给控制器操作,但不适用于这种相当倒退的方法。
我从哪里开始?
我实现了下面Corentin Dandoy提出的解决方案2,但稍微修改以防止在查找根时出现循环。
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FrontControllerControllerController extends Controller
{
/**
* Forward the request to the appropriate controller
* @param Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction(Request $request)
{
// get the parameter that specifies the route to the 'real' homepage controller
$homeroute = $this->container->getParameter('homeroute');
$route = $request->query->get('route');
// Convert the query-string route into a valid path route
$path = '/'.$route;
// if it is the route, then use the 'real' homepage controller, otherwise you end up in a routing loop!
if ($path === '/')
{
$match = $this->get('router')->match('/' . $homeroute);
} else {
try {
$match = $this->get('router')->match($path);
} catch (ResourceNotFoundException $e) {
throw $this->createNotFoundException('The route does not exist');
}
}
$params = array(
'request' => $request,
);
return $this->forward($match['_controller'], $params);
}
}
解决方案 1
一个简单的解决方案(虽然不可扩展)是这样的:
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class MainController
{
/**
* @Route("/app", name="bizarro_app")
*/
public function mainAction(Request $request)
{
$route = $request->query->get('route');
switch ($route) {
case 'blog':
return $this->blogAction($request);
default:
throw $this->createNotFoundException('The route does not exist');
}
}
protected function blogAction(Request $request)
{
// Your blog page here
return new Response('...');
}
}
解决方案 2
如果你不介意有两种可用的路线,你可以试试这个:
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class MainController
{
/**
* @Route("/app", name="bizarro_app")
*/
public function mainAction(Request $request)
{
$route = $request->query->get('route');
// Convert the query-string route into a valid path
$path = '/'.$route;
try {
$match = $this->get('router')->match($path);
} catch (ResourceNotFoundException $e) {
throw $this->createNotFoundException('The route does not exist');
}
$params = array(
'request' => $request,
);
return $this->forward($match['_controller'], $params);
}
/**
* @Route("/blog", name="bizarro_blog")
*/
public function blogAction(Request $request)
{
// Your blog page here
return new Response('...');
}
}
这样,您就可以从 Sf2 路由组件中获益。 请注意,我没有亲自测试过。