[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 🇬🇧 Close

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  ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  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);
    }
}