Symfony2:重定向到最后一条路由并闪烁消息?

时间:2012-08-09 21:17:05

标签: php symfony

尝试刷新消息并将用户重定向回 Symfony 2 中的上一页时,我遇到了一个小问题。

我有一个非常简单的CRUD。当新的或编辑时,我想在相应的创建/更新方法中出现问题时闪烁消息:

  1. User --GET--> new
  2. new --POST--> create (fails)
  3. --REDIRECT--> new (with flash message)
  4. 我正在做以下事情:

      $this->container->get('session')->setFlash('error', 'myerror');
      $referer = $this->getRequest()->headers->get('referer');   
      return new RedirectResponse($referer);
    

    但是,它没有重定向到正确的推荐人!即使引用者的值是正确的(例如:http://localhost/demo/2/edit/),它也会重定向到索引。为什么呢?

8 个答案:

答案 0 :(得分:36)

这是Naitsirch和Santi的替代版本代码。我意识到一个特性对于这个功能来说是完美的。还有点优化了代码。我倾向于回馈所有参数,包括slug,因为在生成路径时可能需要这些参数。

此代码在PHP 5.4.0及更高版本上运行。当然,您可以将特性用于多个控制器。如果将特征放在单独的文件中,请确保在PSR-0之后将其命名为特征。

<?php
trait Referer {
    private function getRefererParams() {
        $request = $this->getRequest();
        $referer = $request->headers->get('referer');
        $baseUrl = $request->getBaseUrl();
        $lastPath = substr($referer, strpos($referer, $baseUrl) + strlen($baseUrl));
        return $this->get('router')->getMatcher()->match($lastPath);
    }
}

class MyController extends Controller {
    use Referer;

    public function MyAction() {
        $params = $this->getRefererParams();

        return $this->redirect($this->generateUrl(
            $params['_route'],
            [
                'slug' => $params['slug']
            ]
        ));
    }
}

答案 1 :(得分:9)

来自Naitsirch的消息在下一个网址中提供: https://github.com/symfony/symfony/issues/2951

似乎是您需要的一个很好的解决方案:

public function getRefererRoute()
{
    $request = $this->getRequest();

    //look for the referer route
    $referer = $request->headers->get('referer');
    $lastPath = substr($referer, strpos($referer, $request->getBaseUrl()));
    $lastPath = str_replace($request->getBaseUrl(), '', $lastPath);

    $matcher = $this->get('router')->getMatcher();
    $parameters = $matcher->match($lastPath);
    $route = $parameters['_route'];

    return $route;
}

然后重定向:

public function yourFunctionAction()
{
    $ruta = $this->getRefererRoute();

    $locale = $request->get('_locale');
    $url = $this->get('router')->generate($ruta, array('_locale' => $locale));

    $this->getRequest()->getSession()->setFlash('notice', "your_message");   

    return $this->redirect($url);
}

答案 2 :(得分:9)

对于symfony 3.0,flash消息重定向回到上一页,这可以在控制器中完成。

           $request->getSession()
                ->getFlashBag()
                ->add('notice', 'success');
            $referer = $request->headers->get('referer');
            return $this->redirect($referer);

答案 3 :(得分:5)

这对我有用:

$this->redirect($request->server->get('HTTP_REFERER'));

答案 4 :(得分:4)

我的网站上有类似的功能。这是多语言的。文章仅存在于单个区域设置中。当用户尝试切换到其他语言环境时,它应该重定向回上一页并闪烁消息,表明该页面/文章在请求的语言环境中不存在。

/en/article/3 -> /fr/article/3 (404) -> Redirect(/en/article/3)

以下是我在devprod环境中运行良好的脚本版本:

$referer = $request->headers->get('referer')

// 'https://your-domain.com' or 'https://your-domain.com/app_dev.php'
$base = $request->getSchemeAndHttpHost() . $request->getBaseUrl();

// '/en/article/3'
$path = preg_replace('/^'. preg_quote($base, '/') .'/', '', $referer);

if ($path === $referer) {
    // nothing was replaced. referer is an external site
} elseif ($path === $request->getPathInfo()) {
    // current page and referer are the same (prevent redirect loop)
} else {
    try {
        // if this will throw an exception then the route doesn't exist
        $this->container->get('router')->match(
            // '/en/hello?foo=bar' -> '/en/hello'
            preg_replace('/\?.*$/', '', $path)
        );

        // '/app_dev.php' . '/en/article/3'
        $redirectUrl = $request->getBaseUrl() . $path;

        return new RedirectResponse($redirectUrl);
    } catch (\Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {}
}

答案 5 :(得分:3)

我只是设置了一个简单的应用程序,它似乎工作正常。我的createAction()看起来像这样:

public function createAction()
{
    $entity  = new Pokemon();
    $request = $this->getRequest();
    $form    = $this->createForm(new PokemonType(), $entity);
    $form->bindRequest($request);

    if ($entity->getName() == "pikachu")
    {
        $this->container->get("session")->setFlash("error", "Pikachu is not allowed");
        $url = $this->getRequest()->headers->get("referer");
        return new RedirectResponse($url);
    }

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getEntityManager();
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('pokemon_show', array('id' => $entity->getId())));

    }

    return $this->render('BulbasaurBundle:Pokemon:new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView()
    ));
}

流程如下:

  • 用户导航至/ new
  • 用户输入“pikachu”的无效选项
  • 用户点击提交(POST到/创建)
  • 应用程序拒绝该条目,添加Flash消息,并重定向回/ new
  • 用户通过Flash消息看到/ new

要检查的一些事项:

  • /demo/{entityId}/edit的路线确实有效吗? (即如果你在浏览器中输入它,它实际上是否会到达你期望的位置?)

  • 您是否将不同的重定向/转发链接在一起?当我有一个重定向到URL的控制器时,我注意到我得到了意外(但正确)的行为,并且负责该URL的控制器也重定向到其他地方。我已经通过使用转发修复了这个问题。

也就是说,如果所有其他方法都失败了,您可以使用控制器的redirect()方法来管理重定向:

public function createAction()
{
    ...
    return $this->redirect($this->generateUrl("pokemon_new"));
    ...
}

答案 6 :(得分:1)

在这里,您将此声明为服务,无论何时何地需要,它都会将引用返回给您。没有特质,没有奇怪的依赖。

The+provided+value+for+the+input+parameter+'redirect_uri'+is+not+valid.+The+expected+value+is+'https://login.live.com/oauth20_desktop.srf'+or+a+URL+which+matches+the+redirect+URI+registered+for+this+client+application

答案 7 :(得分:0)

您似乎需要为重定向指定有效负载。对我来说,这似乎是一个模糊的概念代码。我还建议您确保配置文件指向正确的重定向代码段。检查您的服务器访问文件,确保它也已启用重定向。