Удаляем index.php из URL

Удаление index.php из адреса в Laravel

Если у вас есть проект на Laravel, то вы удивитесь, обнаружив, что ваши маршруты открываются по разным URL-адресам.

Например, допустим, что у нас такой файл маршрутов:

Route::view('/feature/uptime-monitoring', 'front/feature/uptime-monitoring');

Это создаст, как вы ожидаете, маршрут yourdomain.tld/feature/uptime-monitoring

Но для большинства вебсерверов это означает, что следующие URL-адреса также являются действительными и будут возвращать HTTP/1.1 200 OK с той же страницей:

https://yourdomain.tld/feature/uptime-monitoring
https://yourdomain.tld/index.php/feature/uptime-monitoring

Что там делает index.php? Это необходимо для некоторых хостингов, которые не поддерживают семантические адреса.

Но вам вряд ли это нужно, так что давайте избавимся от него!

Удаляем index.php через код Laravel

Один из способов удаления — проверить маршрут в Laravel и, при необходимости, сделать редирект.

Один из вариантов сделать это в app/Providers/RouteServiceProvider.php.

use Illuminate\Support\Str;

class RouteServiceProvider extends ServiceProvider
{
    public function map(Router $router)
    {
        $this->removeIndexPhpFromUrl();
    }

    protected function removeIndexPhpFromUrl()
    {
        if (Str::contains(request()->getRequestUri(), '/index.php/')) {
            $url = str_replace('index.php/', '', request()->getRequestUri());

            if (strlen($url) > 0) {
                header("Location: $url", true, 301);
                exit;
            }
        }
    }
}

При обнаружении index.php в любом URL будет сделан редирект.

$ curl -I "http://yourdomain.tld/index.php/pricing"
HTTP/1.1 301 Moved Permanently
Location: /pricing

$ curl -i "http://yourdomain.tld/index.php/feature/uptime-monitoring"
HTTP/1.1 301 Moved Permanently
Location: /feature/uptime-monitoring

Есть несколько альтернативных способов получения того же результата на уровне вебсервера.

Редирект index.php в Nginx

Например так:

if ($request_uri ~* "^/index\.php(/?)(.*)") {
    return 301 $1;
}

Возможно, вам придется повторить этот блок для каждого блока location {}, если в вашей конфигурации Nginx их несколько.

Редирект index.php в Apache

Вы можете добавить дополнительную строку в свой .htaccess.

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Redirect if index.php is in the URL
    RewriteRule ^index.php/(.+) /$1 [R=301,L]
</IfModule>

По крайней мере, это простая регулярка/фикс :-)

Редирект index.php в Caddy

Получается немного громоздко, но, главное, работает для Caddy.

$ cat Caddyfile

https:// {

  tls {
    ask https://ohdear.app/caddy/allowed-domain
  }

  rewrite {
   	regexp ^/index.php/(.*)
      	to /{1}
  }

  redir {
      	if {uri} not {rewrite_uri}
      	/ {rewrite_uri}
  }
}

Требуется внутренний rewrite, чтобы найти index.php, а затем redir для редиректа запроса.

Автор: Mattias Geniar
Перевод: Demiurge Ash