🗡
Laravel トレイリングスラッシュを扱う方法まとめ
Laravel はトレイリングスラッシュなしがデフォルトのため、ありにするにはいくつかの設定が必要になります。
ネットには Apache、Laravel でそれぞれ情報が散らばっており、結局どれを設定すればいいんだっけ…? となることがあるので備忘録です。
また Apache へのアクセス時の挙動と合わせて、Laravel で自動生成される URL に対してもトレイリングスラッシュが付くようにします。
Web サーバー (Apache) 側の設定
public/.htaccess
に以下の内容を追記してください。
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Laravel 側の設定
1. サービスの設定
app/Services/Route/UrlGenerator.php
を新規作成し、Illuminate\Routing\UrlGenerator
を継承して format()
メソッドをオーバーライドします。
以下の内容を記述してください。
<?php
namespace App\Services\Route;
use Illuminate\Routing\UrlGenerator as BaseUrlGenerator;
class UrlGenerator extends BaseUrlGenerator
{
/**
* Create a new manager instance.
*
* @param Illuminate\Routing\UrlGenerator $url
*/
public function __construct(BaseUrlGenerator $url)
{
parent::__construct($url->routes, $url->request);
}
/**
* Format the given URL segments into a single URL.
*
* @param string $root
* @param string $path
* @return string
*/
public function format($root, $path, $route = null)
{
$path = parent::format($root, $path, $route);
$matches = null;
preg_match("/([^\/]+?)?$/", $path, $matches);
$last = $matches[0] ?? '';
if (strpos($last, ".") === false) {
return $path . "/";
}
return $path;
}
}
2. サービスプロバイダーへの登録
app/Providers/AppServiceProvider.php
に、1. で作成したサービスを登録します。
以下の内容を追記してください。
// 一部を抜粋
use App\Services\Route\UrlGenerator;
public function register(): void
{
// トレイリングスラッシュ付与
$url = $this->app['url'];
$this->app->singleton('url', function () use ($url) {
return new UrlGenerator($url);
});
}
Discussion