Symfony2:使用对象设置路由参数

时间:2012-01-16 09:17:09

标签: symfony

我有一个包含2个参数的路线:

BBBundle_blog_show:
    pattern:  /{id}/{slug}
    defaults: { _controller: BloggerBlogBundle:Blog:show }
    requirements:
        _method: GET
        id: \d+

这两个参数都是对象博客的属性。

我想设置一个自定义映射器(路由生成器),以便我可以这样写:

 {{ path('BBBundle_blog_show', {'blog': blog}) }}

而不是:

 {{ path('BBBundle_blog_show', {'id':blog.id, 'slug':blog.slug) }}

2 个答案:

答案 0 :(得分:7)

这是我最终提出的:

我通过自己的生成器基类实现,它查找'object'参数并尝试从该对象获取所需的参数。

//src/Blogger/BlogBundle/Resources/config/services.yml
parameters:    
    router.options.generator_base_class: Blogger\BlogBundle\Routing\Generator\UrlGenerator
//src/Blogger/BlogBundle/Routing/Generator/UrlGenerator.php

namespace Blogger\BlogBundle\Routing\Generator;

use Symfony\Component\Routing\Generator\UrlGenerator as BaseUrlGenerator;

use Doctrine\Common\Util\Inflector;

/**
 * UrlGenerator generates URL based on a set of routes.
 *
 * @api
 */
class UrlGenerator extends BaseUrlGenerator
{
    protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute)
    {
        if (isset($parameters['object']) && is_object($parameters['object'])) {
            $object = $parameters['object'];
            $parameters = array_replace($this->context->getParameters(), $parameters);
            $tparams = array_replace($defaults, $parameters);
            $requiredParameters = array_diff_key(array_flip($variables), $tparams);

            $parameters = $this->getParametersFromObject(array_flip($requiredParameters), $object);
        }

        return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute);
    }

    protected function getParametersFromObject($keys, $object)
    {
        $parameters = array();
        foreach ($keys as $key) {
            $method = 'get' . Inflector::classify($key);
            if (method_exists($object, $method)) {
                $parameters[$key] = $object->$method();
            }
        }

        return $parameters;
    }

}

现在我可以写:{{path('BBBundle_blog_show',{'object':blog})}}并且它将从对象获得所需的参数(id,slug)。

答案 1 :(得分:0)

前段时间,我觉得因为无法将对象作为路由参数传递而感到恼火。我不得不关心路线的知识以及模板中的确切参数值以及生成这些路线的其他事物。

我为symfony构建了这个包,它允许你使用和扩展这个能力(Symfony 2.7和更高版本)。请看一下:https://github.com/iltar/http-bundle。它也可以在Packagist上作为iltar / http-bundle使用。

关于这个捆绑的最好的事情是你不需要使用另一个路由器对象或生成器。它只是打开捆绑包,根据您的需要调整配置,如果默认设置不符合您的偏好,那么您就可以了。自述文件应该解释您需要知道的所有内容,但这是一个片段:

旧式:

/**
 * @Route("/profile/{user}/", name="app.view-profile")
 */
public function viewProfileAction(AppUser $user);

// php
$router->generate('app.view-profile', ['user' => $user->getId()]);

// twig
{{ path('app.view-profile', { 'user': user.id }) }}
{{ path('app.view-profile', { 'user': user.getid }) }}
{{ path('app.view-profile', { 'user': user.getId() }) }}
{{ path('app.view-profile', { 'user': user[id] }) }}

新风格:

// php
$router->generate('app.view-profile', ['user' => $user]);

// twig
{{ path('app.view-profile', { 'user' : user }) }}