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

Publié le 31/10/2018 • Actualisé 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 referrer 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. Si vous voulez juste récupérer le referrer, veuillez jeter un coup d'œil à ce snippet.


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

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

use function Symfony\Component\String\u;

/**
 * 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 = (string) $request->headers->get('referer'); // get the referer, it can be empty!
        $refererStr = u($referer);
        if ($refererStr->isEmpty()) {
            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

  Travaillez avec moi !

<?php

declare(strict_types=1);

namespace App\Tests\Integration\Controller\Snippets;

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

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

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

    /**
     * @see Snippet7Trait::snippet7
     */
    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);
        self::assertSame($referer.'?foo=bar', $newUrl);
    }
}