Убираем повторяющиеся и крайние слеши в Nginx/Apache2 на сайте под управлением PHP

Заголовок тупо кликбейтный, сразу говорю — такие реврайты не задача для веб сервера. Почему — потому что кейсов здесь — овер до хрена. И все их предусматривать и засерать конфиги хреново читаемыми реврайт правилами… (которые потом ещё вылезут в самом неожиданном месте в виде 500 ошибки). Ну например варианты запросов:

  • //// => /
  • /path/// => /path
  • ///path/ => /path
  • /path////path => /path/path
  • ////path/////path///// => /path/path
  • и т.д.

а зачем это всё «причёсывать» реврайтами? На фига козе баян? Есть php — гибкий язык в отличии от директив Nginx/Apache2, позволяющий это же реализовать 1 раз без ошибок и забыть. Вот так:

$request = strtok($_SERVER['REQUEST_URI'], '?');

if (preg_match('#//#', $request)) { // убираем 2 и более слешей в url
    $uri = preg_replace('#[/]+$#', '', $request);
    $uri = preg_replace('#[/]{2,}#', '/', $uri);
    $uri = $uri ?: '/';
    if ($QUERY_STRING = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY)) {
        $uri .= '?' . $QUERY_STRING;
    }
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: $uri");
    exit;
}

if ($request != '/' && preg_match('#/$#', $request)) { // убираем крайний слеш если это не главная
    $uri = preg_replace('#[/]+$#', '', $request);
    $uri = $uri ?: '/';
    if ($QUERY_STRING = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY)) {
        $uri .= '?' . $QUERY_STRING;
    }
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: $uri");
    exit;
}

if (preg_match('#index\.(php|html)$#', $request)) {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: " . dirname($request));
    exit;
}

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *