Подтвердить что ты не робот

Symfony2: Перенаправление на последний маршрут и флэш-сообщение?

У меня возникла небольшая проблема при попытке выполнить флэш-сообщение и перенаправить пользователя на предыдущую страницу в Symfony 2.

У меня очень простой CRUD. Когда новое или редактируемое, я хочу выпустить сообщение, если что-то пойдет не так в соответствующих методах создания/обновления:

  • User --GET--> new
  • new --POST--> create (fails)
  • --REDIRECT--> new (with flash message)

Я делаю следующее:

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

Однако он не перенаправляется на правильный реферер! Несмотря на то, что значение referrer верное (например: http://localhost/demo/2/edit/), оно перенаправляется на индекс. Почему?

4b9b3361

Ответ 1

Это альтернативная версия Найцирха и Санти их кода. Я понял, что черта будет идеальной для этой функциональности. Также немного оптимизирован код. Я предпочел вернуть все параметры, включая пули, потому что вам может понадобиться их при создании маршрута.

Этот код работает на 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']
            ]
        ));
    }
}

Ответ 2

Сообщение от Найцирха, представленное в следующем URL: 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);
}

Ответ 3

Для symfony 3.0, флэш-сообщение с перенаправлением на предыдущую страницу, это можно сделать в контроллере.

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

Ответ 4

Это работает для меня:

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

Ответ 5

У меня есть аналогичные функции на моем сайте. Он многоязычный. Статьи существуют только в одном языке. Когда пользователь попытается переключиться на другой язык, он должен перенаправить на предыдущую страницу и флэш-сообщение о том, что эта страница/статья не существует в запрошенной языковой версии.

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

Вот моя версия script, которая хорошо работает в средах dev и prod:

$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) {}
}

Ответ 6

Я просто создал простое приложение, и, похоже, он работает нормально. Мой 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 для создания/создания)
  • Приложение отклоняет запись, добавляет флеш-сообщение и перенаправляет обратно в /new
  • Пользователь видит/новый с флэш-сообщением

Несколько вещей, чтобы проверить:

  • Действительно ли ваш маршрут для /demo/{entityId}/edit работает? (т.е. если вы вводите его в браузере, действительно ли он идет туда, где вы ожидаете?)

  • Вы объединяете разные переадресации/пересылки? Я заметил, что я получаю неожиданное (но правильное) поведение, когда у меня есть контроллер, который перенаправляет URL-адрес, и контроллер, ответственный за этот URL-адрес, также перенаправляет куда-то еще. Я исправил эту проблему, используя вместо нее.

Тем не менее, если все остальное не удается, вы можете просто использовать метод redirect() контроллера для управления перенаправлением:

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

Ответ 7

Здесь вы идете, объявляете это как сервис, и он будет возвращать вам референт где угодно и когда вам это нужно. Нет черт, нет странных зависимостей.

class Referer
{

    /** @var RequestStack */
    private $requestStack;

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

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

    public function getReferer() : string
    {
        $request = $this->requestStack->getMasterRequest();

        if (null === $request)
        {
            return '';
        }

        //if you're happy with URI (and most times you are), just return it
        $uri = (string)$request->headers->get('referer');

        //but if you want to return route, here you go
        try
        {
            $routeMatch = $this->router->match($uri);
        }
        catch (ResourceNotFoundException $e)
        {
            return '';
        }

        $route = $routeMatch['_route'];

        return $route;
    }

}

Ответ 8

похоже, что вам нужно иметь полезную нагрузку для перенаправления. для меня это кажется неясным концептуальным кодом. Я также советую вам убедиться, что ваши файлы конфигурации указывают на правильный фрагмент кода перенаправления. Проверьте файл доступа к серверу, чтобы убедиться, что он также имеет перенаправленные адреса.

Ответ 9

Zero плюс Zéro égale... La Tête à Toto!