Laravel 5.0.* 中间件在处理路由之前从 url 中删除前缀语言环境
Posted
技术标签:
【中文标题】Laravel 5.0.* 中间件在处理路由之前从 url 中删除前缀语言环境【英文标题】:Laravel 5.0.* middleware to remove prefix locale from url before routes are processed 【发布时间】:2016-04-24 06:38:26 【问题描述】:我正在寻找一种方法,使所有应用程序路由具有多个区域设置,而无需使用路由组。这是因为我使用了外部扩展包,这意味着路由在很多地方都注册了。
基本上我希望 /foo/bar 以及 /en/foo/bar、/de/foor/bar、/es/foo/bar 等都被 /foot/bar 路由识别和处理
Route::get('foo/bar', function ()
return App::getLocale() . ' result';
);
所以上面会给我'en result'或'de result'或'es result'。
我已经有基于路径段设置语言环境的中间件。我试过以下没有运气。
...
$newPath = str_replace($locale,'',$request->path());
$request->server->set('REQUEST_URI',$new_path);
return $next($request);
希望这是可能的,或者有其他方法可以实现。
编辑------
根据下面的评论,我通过将以下代码添加到 public/index.php 中快速破解了它。希望这可以更好地了解我通过编辑请求对象想要实现的目标。
$application_url_segments = explode( '/', trim( $_SERVER["REQUEST_URI"], '/' ) );
$application_locale = $application_url_segments[0];
$application_locales = ['en' => 'English', 'de' => 'German'];
if ( array_key_exists( $application_locale, $application_locales ) )
$_SERVER["REQUEST_URI"] = str_replace( '/' . $application_locale,'',$_SERVER["REQUEST_URI"] );
【问题讨论】:
我个人找不到任何可以轻松完成您所追求的事情的方法。虽然我可能错过了一些东西,但我查看了 laravel 和 symfonys 的 Request 类。不幸的是,我没有找到任何有价值的东西。话虽如此,您可以在public文件夹中的index.php文件中拦截请求,然后在创建请求对象之前设置$_SERVER["REQUEST_URI"]
,它将起作用。
我很快在 index.php 文件中尝试了一些东西,这意味着我可以在服务器变量到达 Laravel 之前对其进行编辑。但是我认为我需要更好的东西,因为我将配置用于语言环境等。
我面临同样的问题,我也无法让它工作。 Request
对象似乎是不可变的。我也在 index.php 中设置了一个快速破解,但我也将 URI 用于语言环境等,所以仍在研究中。
【参考方案1】:
这是在调用路由之前编辑 URL 的正确代码。
<?php namespace App\Providers;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Request;
class LanguageServiceProvider extends ServiceProvider
public function register()
Request::instance()->server->set('REQUEST_URI',"/uri/");
请注意,从 Request 实例中获取路径而不首先复制它会由于某种原因导致 REQUEST_URI 不可编辑。我假设当您调用 path() 方法时,代码库 laravel 中的某处正在初始化请求。
【讨论】:
有没有办法在 Lumen 中做到这一点? Tom C,我已经在 Laravel 5.8.36 中尝试过这个,虽然服务器变量中的 REQUEST_URI 发生了变化,但路由器并没有接收到变化的路由。有什么想法吗??【参考方案2】:您可以通过早一点连接到应用程序来轻松实现这一点。创建一个 ServiceProvider 并创建一个 register
方法并将您的逻辑放入其中。
<?php namespace App\Providers;
use Illuminate\Support\ServiceProviders;
use Illuminate\Support\Facades\Request;
class LocaleServiceProvider extends ServiceProvider
// Fires during the registration of this ServiceProvider :)
public function register(Request $request)
// Altar the Request object here
// ...
// ...
【讨论】:
这不起作用。由于以下错误,我收到错误 LocaleServiceProvider::register(Illuminate\Http\Request $request) must be compatible with Illuminate\Support\ServiceProvider::register() 我已使用构造函数传入应用程序实例并使用 $应用程序-> 请求。但是 - 我仍然无法让它真正改变任何东西。路线仍然处理相同 如果有帮助,我已经对上面的原始问题/详细信息进行了编辑【参考方案3】:在 5.5 中,这些都对我不起作用。该方法很好,但对我来说,请求参数没有注入register
方法,同样instance()
不是静态方法,不应该这样调用。
但是,使用服务容器获取Request
的实例使得在ServiceProviders register
方法中解析请求路径之前更改请求路径成为可能:
public function register()
$this->app->make('Illuminate\Http\Request')->instance()->server->set('REQUEST_URI',"/what/ever/");
我希望这对某人有帮助!
干杯
edit:Pastor 的回答在技术上更正确,因为他使用 Facade 而不是实际的 Class。但是,register
的注入都不起作用,但您也可以使用:
use \Illuminate\Support\Facades\Request
//...
public function register()
Request::instance()->server->set('REQUEST_URI',"/what/ever/");
【讨论】:
以上是关于Laravel 5.0.* 中间件在处理路由之前从 url 中删除前缀语言环境的主要内容,如果未能解决你的问题,请参考以下文章
将自定义中间件添加到 Laravel Passport 端点