2015-06-28 40 views
2

我可以在服務內執行重定向到另一個控制器嗎?重定向服務 - symfony2

我已經實施了基於@Artamiel提供的示例的服務。這是由控制器執行

我的功能代碼如下所示:

public function verifyanddispatch() { 
     $session = $this->request->getSession(); 
     if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->router->generate('app_listbooks')); 
    } 

我已經確認並!$session->get("App_Books_Chosen_Lp")是真實的。儘管如此,我並沒有重定向到app_listbooks控制器。

我認爲這是因爲我不直接在控制器中而是在服務中返回重定向響應。

回答

8

我不知道你是怎麼定義你的服務,但是下面的示例工作正常。假設你正在從你的控制器調用服務。

services.yml

services: 
    application_backend.service.user: 
     class: Application\BackendBundle\Service\UserService 
     arguments: 
      - @router 

Service類

namespace Application\BackendBundle\Service; 

use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\Routing\RouterInterface; 

class UserService 
{ 
    private $router; 

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

    public function create() 
    { 
     $user = new User(); 
     $user->setUsername('hello'); 
     $this->entityManager->persist($user); 
     $this->entityManager->flush(); 

     return new RedirectResponse($this->router->generate('application_frontend_default_index')); 
    } 
} 

控制器

public function createAction(Request $request) 
{ 
    //......... 

    return $this->userService->create(); 
} 

UPDATE


雖然原來的答案上面的答案原來的問題,這是不是最好的做法,如果你想有一個更好的辦法,以便執行以下操作。首先不要將@router注入服務並進行以下更改。

// Service 
public function create() 
{ 
    ..... 
    $user = new User(); 
    $user->setUsername('hello'); 
    $this->entityManager->persist($user); 
    $this->entityManager->flush(); 
    ..... 
} 

// Controller 
public function createAction(Request $request) 
{ 
    try { 
     $this->userService->create(); 

     return new RedirectResponse($this->router->generate(........); 
    } catch (......) { 
     throw new BadRequestHttpException(.....);  
    } 
} 
+0

謝謝,我沒有在控制器中執行「返回」。 – Abdel5

+1

控制器A調用服務。服務返回'RedirectResponse'返回到控制器A.控制器A返回'RedirectResponse'作爲結果,這觸發了實際重定向到控制器B.上面的示例以這種方式工作。 – BentCoder

+0

有人很勇敢地回答了這個問題,但並不足以解釋爲什麼我們都可以知道它出了什麼問題! – BentCoder

3

從架構的角度來看,不應在服務中創建redirectResponse。一種方法是,在服務中拋出一個異常,並在控制器操作中捕獲,您可以輕鬆創建RedirectResponse。

一個例子可以在這裏找到:Redirect from a Service in Symfony2

+0

這肯定是做清潔的方式。 –

0

這似乎讓從你必須通過服務重定向到控制器要麼RedirectResponse對象或值會告訴控制器服務中一切正常,不需要重定向(例如在下面:「真」 )。然後,您必須在控制器中驗證提供了哪個值(無論是「true」還是RedirectResponse),並在控制器內再次返回RedirectResponse或者什麼都不做。

下面的例子應該告訴一切。

服務:

<?php 
namespace AppBundle\Service; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\RequestStack; 
use Symfony\Component\Routing\RouterInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 

class nobookchoosenService { 

    /* @var $request Request */ 
    private $request; 

    /* @var $router RouterInterface */ 
    private $router; 

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

    public function verifyanddispatch() { 
     $session = $this->request->getSession(); 
     if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->router->generate('app_listbooks')); 
     else return true; 
    } 

} 

控制器:

$checker = $this->get('nobookchoosen_service')->verifyanddispatch(); 
     if($checker != "true") return $checker; 
0

我與@Moritz同意重定向必須內部控制器來完成。

但有時會發生,如果從控制器內的本地函數完成某些重定向會很有用。

在這種情況下,解決方案可能是創建自定義的Exception類(RedirectException)。

在這裏,你是一個有趣的帖子的鏈接:https://www.trisoft.ro/blog/56-symfony-redirecting-from-outside-the-controller

我知道這是值得商榷的,但是如果它在控制器內的本地函數中使用,則有意義。

總而言之,這些步驟是:

1)創建設置服務在配置服務文件RedirectException類

2)創建一個內核監聽

3)( service.yml)

4)在必要時拋出一個帶有url的異常來重定向。

0

這是可能的,但我不會推薦它。要從服務重定向你應該爲你的示例事件提供適當的API像:FOSUserBundle你在哪裏接收的FilterUserResponseEvent實例,您可以設置事件對象響應:

class RegistrationListener implements EventSubscriberInterface 
{ 
    // dependencies 
    // ... 

    public static function getSubscribedEvents() 
    { 
     return array(
      FOSUserEvents::REGISTRATION_SUCCESS  => 'onSuccess', 
     ); 
    } 

    public function onSuccess(FilterUserResponseEvent $event) 
    { 
     $url = $this->router->generate('some_url'); 

     $event->setResponse(new RedirectResponse($url)); 
    } 
} 

這可能是由於控制器:

$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event); 

if (null === $response = $event->getResponse()) { 
    // create response 
} 
// return response from event