[Symfony] Récupérer les informations de routing du referer

Publié le 31/10/2018 • Mis à jour le 03/11/2018


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧

Il est parfois utile de récupérer les informations de la route du referer quand vous avez une page ayant de multiples points d'accès. Connaître précisément le contexte peut vous aider à personnaliser la sortie utilisateur selon cette route de provenance ou même de certains paramètres de celle-ci.


<?php declare(strict_types=1);

namespace App\Controller\Snippet;

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

/**
 * J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
 * Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
 * ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Les services sont injectés dans le constructeur du contrôleur principal.
 *
 * @property RouterInterface $router
 */
trait Snippet7Trait
{
    public function snippet7(Request $request): void
    {
        $referer = $request->headers->get('referer'); // get the referer, it can be empty!
        if (!\is_string($referer) || !$referer) {
            echo 'Referer is invalid or empty.';

            return;
        }

        $refererPathInfo = Request::create($referer)->getPathInfo();

        // Remove the scriptname if using a dev controller like app_dev.php (Symfony 3.x only)
        $refererPathInfo = str_replace($request->getScriptName(), '', $refererPathInfo);

        // try to match the path with the application routing
        $routeInfos = $this->router->match($refererPathInfo);

        // get the Symfony route name
        $refererRoute = $routeInfos['_route'] ?? '';

        // No route found (external URL for example)
        if (!$refererRoute) {
            echo sprintf('No route found for the "%s" referer.', $referer);

            return;
        }

        // get the parameters, remove useless ones and add a parameter to test
        unset($routeInfos['_route'], $routeInfos['_controller']);
        $routeInfos['foo'] = 'bar';

        // Ok, now we can generate a new URL for this referer with new parameters
        try {
            $newUrl = $this->router->generate($refererRoute, $routeInfos); // new URL with foo bar
        } catch (\Exception $e) {
            $newUrl = 'Error when generating the new URL from the referer.';
        }

        echo $referer.PHP_EOL;
        echo $newUrl;

        // That's it! 😁
    }
}

 Exécuter le snippet  ≪ showUnitTestButtonLabel ≫  Plus sur Stackoverflow  Snippet aléatoire

<?php declare(strict_types=1);

namespace App\Tests\Controller\Snippets;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;

/**
 * @covers Snippet7Trait
 */
final class Snippet7Test extends KernelTestCase
{
    /**
     * @var RouterInterface
     */
    private $router;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->router = self::$container->get('router');
    }

    /**
     * @covers Snippet7Trait::snippet7
     *
     * @see https://www.strangebuzz.com/en/snippets/get-the-routing-information-of-the-referer
     */
    public function testSnippet7(): void
    {
        $referer = '/en/snippets/get-the-routing-information-of-the-referer';
        $refererPathInfo = Request::create($referer)->getPathInfo();
        $routeInfos = $this->router->match($refererPathInfo);
        $refererRoute = $routeInfos['_route'] ?? '';
        unset($routeInfos['_route'], $routeInfos['_controller']);
        $routeInfos['foo'] = 'bar';
        $newUrl = $this->router->generate($refererRoute, $routeInfos);
        $this->assertSame($referer.'?foo=bar', $newUrl);
    }
}