[英]Redirecting in service - symfony2
May I perform redirection to another controller within service?我可以重定向到服务中的另一个控制器吗?
I have implemented a service based on example provided by @Artamiel .我已经基于@Artamiel提供的示例实现了一项服务。
My function code which is executed by controller looks like this:我的由控制器执行的功能代码如下所示:
public function verifyanddispatch() {
$session = $this->request->getSession();
if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->router->generate('app_listbooks'));
}
I have checked and !$session->get("App_Books_Chosen_Lp")
is true.我已经检查过
!$session->get("App_Books_Chosen_Lp")
是真的。 Nonetheless I am not redirected to app_listbooks
controller.尽管如此,我并没有被重定向到
app_listbooks
控制器。
I think that this is because I return redirect response not directly in controller rather than in a service.我认为这是因为我不直接在控制器中而不是在服务中返回重定向响应。
I don't know how you defined your service but example below works fine.我不知道你是如何定义你的服务的,但下面的例子工作正常。 Assuming that you're calling service from your controller.
假设您正在从控制器调用服务。
services.yml服务.yml
services:
application_backend.service.user:
class: Application\BackendBundle\Service\UserService
arguments:
- @router
Service class服务类
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'));
}
}
Controller控制器
public function createAction(Request $request)
{
//.........
return $this->userService->create();
}
UPDATE更新
Although original answer above answers original question, it is not the best practise so do the following if you want a better way.尽管上面的原始答案回答了原始问题,但这不是最佳做法,因此如果您想要更好的方法,请执行以下操作。 First of all do not inject
@router
into service and do the following changes.首先不要将
@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(.....);
}
}
From an architecture point of view one should not create a RedirectResponse
in a service.从架构的角度来看,不应在服务中创建
RedirectResponse
。 One way could be to throw an exception in the service, which is caught in the controller's action where you can easily create a RedirectResponse
.一种方法可能是在服务中抛出异常,该异常在控制器的操作中被捕获,您可以在其中轻松创建
RedirectResponse
。
An example can be found here: Redirect from a Service in Symfony2可以在此处找到示例: 从 Symfony2 中的服务重定向
It seems to make the redirection from service you have to pass to controller either RedirectResponse
object or value that will tell controller that everything within service went fine and no redirection is needed (in example below: "true" value).它似乎使从服务的重定向您必须传递给控制器
RedirectResponse
对象或值,它将告诉控制器服务中的一切正常并且不需要重定向(在下面的示例中:“true”值)。 Then you have to verify in controller which value was provided (whether it is "true" or RedirectResponse
) and either return RedirectResponse
again within controller or do nothing.然后您必须在控制器中验证提供了哪个值(无论是“true”还是
RedirectResponse
),然后在控制器中再次返回RedirectResponse
或什么都不做。
Example below should tell everything.下面的例子应该说明一切。
Service:服务:
<?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;
}
}
Controller:控制器:
$checker = $this->get('nobookchoosen_service')->verifyanddispatch();
if($checker != "true") return $checker;
I am agree with @Moritz that redirections must be done inside controllers.我同意@Moritz 的观点,即重定向必须在控制器内部完成。
But sometimes happens that some redirection would be useful if done from a local function inside a controller.但有时会发生,如果从控制器内的本地函数完成某些重定向会很有用。
In this case a solution could be to create a custom Exception Class (RedirectException).在这种情况下,解决方案可能是创建自定义异常类 (RedirectException)。
Here you are a link to an interesting post: https://www.trisoft.ro/blog/56-symfony-redirecting-from-outside-the-controller .这是一个有趣帖子的链接: https : //www.trisoft.ro/blog/56-symfony-redirecting-from-outside-the-controller 。
I know it's debatable, but has sense if it's used within a local function inside its Controller.我知道这是有争议的,但如果在其控制器内的本地函数中使用它是有意义的。
To summarize, the steps would be:总结一下,步骤是:
1) Create a RedirectException class
1)创建一个RedirectException类
2) Create a Kernel Listener
2) 创建内核监听器
3) Set Up the Service in the configuration service file (service.yml)
3)在配置服务文件(service.yml)中设置Service
4) Throw an exception with the url to redirect when necessary.
4)在必要时使用url抛出异常以进行重定向。
This is possible but I would not recommend it.这是可能的,但我不推荐它。 To redirect from service you should provide proper
API
for you event for example like in: FOSUserBundle
where you are receiving instance of FilterUserResponseEvent
and you can set response on that event object:要从服务重定向,您应该为您的事件提供适当的
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));
}
}
This is possible thanks to controller:这要归功于控制器:
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
if (null === $response = $event->getResponse()) {
// create response
}
// return response from event
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.