【问题标题】:Symfony2: use object to set route parametersSymfony2:使用对象设置路由参数
【发布时间】:2012-01-16 09:17:09
【问题描述】:

我有一个带有 2 个参数的路线:

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

两个参数都是对象blog的属性。

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

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

而不是这个:

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

【问题讨论】:

  • 我很想看到这个(肯定会清理我的代码),但据我所知这是不可能的。

标签: symfony


【解决方案1】:

这是我最终想到的:

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

//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)。

【讨论】:

  • 你能分享你的路线配置吗?
  • 你的意思是routing.yml?与沙盒项目中的相同。
  • 我在这里扩展了这个答案:gist.github.com/3226510,您现在可以只传递对象而不是数组,即path('route', entity)(应该是 BC)。此外,在检查匹配密钥后,路由器将通过_ 分解密钥以检查关系,即parent_slug 将解析为$object->getParent()->getSlug()
  • 请查看我的答案以获得更易于维护的解决方案。
【解决方案2】:

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

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

这个捆绑包的最大优点是您不需要使用其他路由器对象或生成器。它只是打开捆绑包,如果默认设置不适合您的偏好并且您很高兴,则根据您的需要调整配置。自述文件应解释您需要了解的所有内容,但这里有一个 sn-p:

旧式:

/**
 * @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 }) }}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 2020-06-16
    • 1970-01-01
    • 2020-12-16
    • 2020-02-15
    • 1970-01-01
    相关资源
    最近更新 更多