【问题标题】:Symfony2 : Automatically map query string in Controller parameterSymfony2:在控制器参数中自动映射查询字符串
【发布时间】:2015-11-29 11:32:36
【问题描述】:

在 Symfony2 中,路由参数可以自动映射到控制器参数,例如:http://a.com/test/foo will return "foo"

    /**
     * @Route("/test/{name}")
     */
    public function action(Request $request, $name) {
        return new Response(print_r($name, true));
    }

http://symfony.com/doc/current/book/routing.html#route-parameters-and-controller-arguments

但我想改用 查询字符串 例如:http://a.com/test?name=foo

如何做到这一点? 对我来说只有 3 个解决方案:

还有其他解决方案吗?

【问题讨论】:

    标签: symfony


    【解决方案1】:

    我为那些想要使用转换器的人提供代码:

    use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
    use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
    use Symfony\Component\HttpFoundation\Request;
    
    /**
     * Put specific attribute parameter to query parameters
     */
    class QueryStringConverter implements ParamConverterInterface{
        public function supports(ParamConverter $configuration) {
            return 'querystring' == $configuration->getConverter();
        }
    
        public function apply(Request $request, ParamConverter $configuration) {
            $param = $configuration->getName();
            if (!$request->query->has($param)) {
                return false;
            }
            $value = $request->query->get($param);
            $request->attributes->set($param, $value);
        }
    }
    

    services.yml:

    services:
      querystring_paramconverter:
        class: AppBundle\Extension\QueryStringConverter
        tags:
          - { name: request.param_converter, converter: querystring }
    

    在您的控制器中:

    /**
     * @Route("/test")
     * @ParamConverter("name", converter="querystring")
     */
    public function action(Request $request, $name) {
      return new Response(print_r($name, true));
    }
    

    【讨论】:

    【解决方案2】:

    基于 Remy 的答案的改进解决方案,它将参数映射到实体:

    <?php
    namespace AppBundle\Extension;
    
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
    use Symfony\Component\HttpFoundation\Request;
    use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter;
    
    /**
     * Put specific attribute parameter to query parameters
     */
    class QueryStringConverter extends DoctrineParamConverter {
    
        protected function getIdentifier(Request $request, $options, $name)
        {
            if ($request->query->has($name)) {
                return $request->query->get($name);
            }
    
            return false;
        }
    
    }
    

    services.yml:

    services:
      querystring_paramconverter:
        class: MBS\AppBundle\Extension\QueryStringConverter
        arguments: ['@doctrine']
        tags:
          - { name: request.param_converter, converter: querystring }
    

    在您的控制器中:

    /**
     * @Route("/test")
     * @ParamConverter("myobject")
     */
    public function action(Request $request, AnyEntity $myobject) {
      return new Response(print_r($myobject->getName(), true));
    }
    

    【讨论】:

    • 不错的解决方案,但是它破坏了 DoctrineParamConverter 的功能。我会在此处添加if ($id = parent::getIdentifier($request, $options, $name)) return $id
    • getIdenfitier 不再是受保护的方法。最好扩展apply函数而不是它。
    • 当然。这个解决方案肯定已经过时了。但问题是关于 Symfony 2。
    【解决方案3】:

    和#2一样,解决私有方法(getIdentifier)首先设置属性并正常执行(parent::apply)。在 Symfony 4.4 上测试

    <?php
    
    namespace App\FrameworkExtra\Converters;
    
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
    use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter;
    use Symfony\Component\HttpFoundation\Request;
    
    class QueryStringEntityConverter extends DoctrineParamConverter 
    {
        public function supports(ParamConverter $configuration)
        {
            return 'querystringentity' == $configuration->getConverter();
        }
    
        public function apply(Request $request, ParamConverter $configuration)
        {
            $param = $configuration->getName();
            if (!$request->query->has($param)) {
                return false;
            }
            $value = $request->query->get($param);
            $request->attributes->set($param, $value);
    
            return parent::apply($request, $configuration);
        }
    }
    

    【讨论】:

      【解决方案4】:

      我没有检查,但似乎 FOSRestBundle 提供了 @QueryParam 注释,它可以做到这一点: http://symfony.com/doc/current/bundles/FOSRestBundle/param_fetcher_listener.html

      【讨论】:

        猜你喜欢
        • 2014-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-09
        相关资源
        最近更新 更多