Перенаправление URL с замыкающим слешем

Перенаправление URL с замыкающим слешем

Целью этой статьи является демонстрация того, как перенаправить URL с замыкающим слешем на тот же URL но без замыкающего слеша (например, /en/blog/ на /en/blog).

Создайте контроллер, который будет соответствовать любому URL с замыкающим слешем, удалите замыкающий слеш (сохраяя параметры запроса, если они есть) и перенаправьте на новый URL с ответом статус-кода 308 (Постоянное перенаправление HTTP):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/Controller/RedirectingController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class RedirectingController extends Controller
{
    public function removeTrailingSlash(Request $request)
    {
        $pathInfo = $request->getPathInfo();
        $requestUri = $request->getRequestUri();

        $url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri);

        // 308 (Постоянное перенаправление) схоже с 301 (Перманентно перемещено), только
        // он не позволяет изменения метода запроса (например, с POST на GET)
        return $this->redirect($url, 308);
    }
}

После этого, создайте маршрут к этомуконтроллеру, который соответствует каждый раз, когда запрашивается URL с замыкающим слешем. Убедитесь, что этот маршрут будет определён в вашей системе последним, как объясняется ниже:

  • Annotations
  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Controller/RedirectingController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class RedirectingController extends Controller
{
    /**
     * @Route("/{url}", name="remove_trailing_slash",
     *     requirements={"url" = ".*\/$"})
     */
    public function removeTrailingSlash(Request $request)
    {
        // ...
    }
}

Caution

Убедитесь в том, что вы включите этот маршрут в вашу конфигурацию маршрутизации в самом конце вашего списка маршрутов. Иначе вы рискуете перенаправить настоящие маршруты (включая базовые маршруты Symfony), которые действительно имеют замыкающий слеш в своём пути.