从服务生成链接

Maë*_*son 23 url service symfony

如何从服务生成链接?我在我的服务中注入了"router",但是生成的链接/view/42代替了/app_dev.php/view/42.我怎么解决这个问题?

我的代码是这样的:

services.yml

services:
    myservice:
        class: My\MyBundle\MyService
        arguments: [ @router ]
Run Code Online (Sandbox Code Playgroud)

MyService.php

<?php

namespace My\MyBundle;

class MyService {

    public function __construct($router) {

        // of course, the die is an example
        die($router->generate('BackoffUserBundle.Profile.edit'));
    }
}
Run Code Online (Sandbox Code Playgroud)

Maë*_*son 31

所以:你需要两件事.

首先,您必须依赖@router(以获取generate()).

其次,您必须将服务范围设置为"请求"(我已经错过了). http://symfony.com/doc/current/cookbook/service_container/scopes.html

services.yml成了:

services:
    myservice:
        class: My\MyBundle\MyService
        arguments: [ @router ]
        scope: request
Run Code Online (Sandbox Code Playgroud)

现在您可以使用@router服务的生成器功能!


关于Symfony 3.x的重要说明:正如文档所说,

本文中解释的"容器范围"概念已在Symfony 2.8中弃用,它将在Symfony 3.0中删除.

使用request_stack服务(在Symfony 2.4中引入)而不是request服务/范围,并使用shared设置(在Symfony 2.8中引入)而不是prototype范围(阅读有关共享服务的更多信息).

  • 我按照你的建议做了这样的错误:`ScopeCrossingInjectionException:检测到Scope Crossing Injection:定义"myservice"引用属于另一个范围层次结构的服务"router.default".此服务可能无法始终可用.通常,将定义"myservice"移动到范围"container"或将"router"声明为"容器"的子范围更安全.如果您可以确定其他范围始终处于活动状态,则可以将引用设置为strict = false以消除此错误 (2认同)

MAZ*_*Zux 13

对于Symfony 4.x,按照此链接中的说明在服务中生成 URL会容易得多

您只需要注入UrlGeneratorInterface您的服务,然后调用generate('route_name')即可检索链接。

// src/Service/SomeService.php
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class SomeService
{
    private $router;

    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }
    public function someMethod()
    {
        // ...

        // generate a URL with no route arguments
        $signUpPage = $this->router->generate('sign_up');
    }

    // ...
}

Run Code Online (Sandbox Code Playgroud)


Jay*_*ayd 5

我有一个类似的问题,但是使用 Symfony 3。虽然在上一个答案中回避了,但要找出到底如何使用 Symfony 3 来request_stack实现与scope: request.

在这个问题的情况下,它看起来像这样:

services.yml 配置

services:
    myservice:
        class: My\MyBundle\MyService
        arguments:
            - '@request_stack'
            - '@router'
Run Code Online (Sandbox Code Playgroud)

和 MyService 类

<?php

    namespace My\MyBundle;

    use Symfony\Component\Routing\RequestContext;

    class MyService {

        private $requestStack;
        private $router;

        public function __construct($requestStack, $router) {
            $this->requestStack = $requestStack;
            $this->router = $router;
        }

        public doThing() {
            $context = new RequestContext();
            $context->fromRequest($this->requestStack->getCurrentRequest());
            $this->router->setContext($context);
            // of course, the die is an example
            die($this->router->generate('BackoffUserBundle.Profile.edit'));
        }
    }
Run Code Online (Sandbox Code Playgroud)

注意:建议不要在构造函数中访问 RequestStack ,因为它可能会在内核处理请求之前尝试访问它。因此,当尝试从 RequestStack 中获取请求对象时,可能会返回 null。