服务中的重定向-symfony2
我可以重定向到服务中的另一个控制器吗 我已经基于提供的示例实现了一个服务 控制器执行的功能代码如下所示:服务中的重定向-symfony2,symfony,Symfony,我可以重定向到服务中的另一个控制器吗 我已经基于提供的示例实现了一个服务 控制器执行的功能代码如下所示: public function verifyanddispatch() { $session = $this->request->getSession(); if(!$session->get("App_Books_Chosen_Lp")) return new RedirectResponse($this->router->g
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\u Books\u selected\u Lp”)
为true。尽管如此,我没有被重定向到app\u listbooks
controller
我认为这是因为我返回的重定向响应不是直接在控制器中,而是在服务中 从架构的角度来看,不应该在服务中创建
重定向响应。一种方法是在服务中抛出异常,该异常在控制器的操作中被捕获,您可以轻松创建重定向响应
这里可以找到一个例子:我不知道您是如何定义服务的,但下面的例子很好。假设您正在从控制器调用服务
services.yml
services:
application_backend.service.user:
class: Application\BackendBundle\Service\UserService
arguments:
- @router
服务等级
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();
}
更新
虽然上面的原始答案回答了原始问题,但这并不是最好的做法,所以如果您想要更好的方法,请执行以下操作。首先,不要将@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(.....);
}
}
它似乎使您必须将服务的重定向传递给控制器RedirectResponse
对象或值,该对象或值将告诉控制器服务中的一切正常,不需要重定向(在下面的示例中为:“true”值)。然后,您必须在控制器中验证提供了哪个值(它是“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;
}
}
我同意@Moritz的观点,重定向必须在控制器内部完成
但有时,如果从控制器内的本地函数执行某些重定向,则会很有用
在这种情况下,解决方案可以是创建自定义异常类(RedirectException)
这里是一个有趣帖子的链接:
我知道这是有争议的,但如果在控制器内部的本地函数中使用它,这是有意义的
总而言之,这些步骤将是:
1) 创建重定向异常类
2) 创建内核侦听器
3) 在配置服务文件(Service.yml)中设置服务
4) 在必要时引发url异常以重定向
这是可能的,但我不建议这样做。要从服务重定向,您应该为您的事件提供适当的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));
}
}
这是可能的,因为控制器:
$checker = $this->get('nobookchoosen_service')->verifyanddispatch();
if($checker != "true") return $checker;
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
if (null === $response = $event->getResponse()) {
// create response
}
// return response from event
这绝对是清洁的方式。完全同意这是清洁的方式谢谢,我没有在控制器中执行“返回”。控制器a呼叫服务。服务将RedirectResponse
返回控制器A。控制器A返回RedirectResponse
,这就是触发实际重定向到控制器B的原因。上面的示例就是这样工作的。有人勇敢地否决了这个答案,但没有足够的人解释原因,以便我们都能知道什么是错的用它!虽然这是可行的,但它可能不是最干净的解决方案。通过返回服务中的重定向响应,您正在创建与SyfOff-HTTP基金会紧密耦合。按照Moritz的建议,最好抛出一个异常,并在控制器甚至异常侦听器中捕获它。这非常有效,但您返回的是一个布尔值,因此您应该检查:if($checker!==true)return$checker;