如何从 Laravel 中的路由操作中删除路由前缀

How to remove route prefix from route actions in Laravel

我正在 Laravel 5.3 应用程序中创建本地化。它必须遵循这样的要求:

  1. 如果route路径有locale前缀,locale要根据这个前缀设置

  2. 如果没有路由前缀,应该设置成英文

例如:

A) mysite.org/pl/blog/133 将语言环境设置为 pl 并使用参数 113

调用 BlogController

B) mysite.org/en/blog/133 将语言环境设置为 en 并使用参数 113

调用 BlogController

C) mysite.org/blog/133 与之前的方式相同。

为了实现这一点,我使用了以下代码:

#routes/web.php

require base_path('routes/common.php');
// TODO set default locale to en

Route::group(['prefix' => '{locale}'], function($group) {

    require base_path('routes/common.php');
    // TODO set locale to $locale

    foreach ($group -> getRoutes() as $route) {
        $route->where('locale', 'en|ru|pl|ua|de');
    }

});


#routes/common.php

Route::get('/blog/{id}', function($id) {
    // Return view of respective blogpost
});

问题是,当我使用路径 A 或 B 时,我在我的操作函数中获得了一个额外的第一个参数,该参数派生自语言环境前缀。

我能以某种方式隐藏这个参数吗?或者有没有一种方法可以在架构上更正确地实现我想要的?

我不确定我的解决方案是否最好 但你可以试试这个

  1. 在 app/Http/Middileware/Language 中创建新文件。php

...

namespace App\Http\Middleware;

use Closure;
use Illuminate\Routing\Redirector;
use Illuminate\Http\Request;

class Language {

    public function __construct(Redirector $redirector) {
        // $this->app = $app;
        $this->redirector = $redirector;
        // $this->request = $request;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Make sure current locale exists.
        $segments = $request->segments();
        $locale = $segments[0];

        $languages = ['en','ru','pl','ua','de'];
        if (!in_array($locale, $languages)) {
            $segments = array_merge(['en'], $segments);
            return $this->redirector->to(implode('/', $segments));
        }

        return $next($request);
    }

}
  1. 在app/Http/Kernel.php和这一行

    protected $middleware = [
        \App\Http\Middleware\Language::class,
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    ];
    
  2. 在文件路径(route/web.php)中添加组前缀

    Route::group(['middleware' => ['web'], 'prefix' => '{locale}'],
    function ()      {
    ...
    

希望对您有所帮助

我为 Laravel 6.

找到了这个问题的更优雅的答案

创建中间件:

namespace App\Http\Middleware;

use Closure;

    class LocaleMiddleware
    {

        public function handle($request, Closure $next)
        {
            $locale = $request->segment(1); // one based index!

        if(empty($locale)) { // redirect '/' to default locale
            return redirect()->to('/' . app()->getLocale());
        }

        if(in_array($locale, ['en','ru','pl','ua','de'])) {
            \App::setLocale($locale);
            $request->except(0); // handle request without locale further
        }

        return $next($request);
    }
}

添加到 app/Http/Kernel.php 中的中间件数组以将其应用于所有路由:

protected $middleware = [
    ...
    \App\Http\Middleware\LocaleMiddleware::class,
    ...
];

如果您想在特定路线或路线组上使用它,请将它放在 app/Http/Kernel.php 中的其他一些数组中。该文件中的评论很有帮助。