Symfony2使用查询字符串参数路由到控制器

gra*_*ney 5 php routing query-string symfony

我目前住在Bizzaro World,有一位客户.

因为我们正在编写的symfony应用程序将响应注入到另一个应用程序的页面中,所以我们被迫只为应用程序提供一个URL,但幸运的是我们确实将查询字符串完整地传递给了我们.

因此,我需要与symfony如何做事完全相反,这是一种旧式的MVC方法.我需要路由通过查询字符串参数工作,路由到正确的控制器并呈现正确的响应,而不是使用标准的,理智的路径方法.

所以网址将是,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);
    }

}
Run Code Online (Sandbox Code Playgroud)

Cor*_*tin 4

解决方案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('...');
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案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('...');
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您就可以从 Sf2 路由组件中受益。请注意,我自己还没有测试过。