【问题标题】:How to remove route prefix from route actions in Laravel如何从 Laravel 中的路由操作中删除路由前缀
【发布时间】:2017-06-12 12:35:36
【问题描述】:

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

  1. 如果路由路径包含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 时,我在操作函数中获得了一个额外的第一个参数,该参数源自语言环境前缀。

我可以隐藏这个参数吗?或者有没有办法以更架构正确的方式实现我想要的?

【问题讨论】:

    标签: php laravel localization laravel-routing


    【解决方案1】:

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

    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 ()      {
      ...
      

    希望有帮助

    【讨论】:

    • 感谢您的回复,正是我想要的。实际上,我在 Mcamara/LaravelLocalization 发现了这一点
    【解决方案2】:

    我为 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 中的其他一些数组中。该文件中的注释非常有用。

    【讨论】:

      猜你喜欢
      • 2020-04-16
      • 2016-12-26
      • 2022-11-01
      • 2021-07-26
      • 2013-01-05
      • 1970-01-01
      • 2016-06-19
      • 2018-04-27
      • 2015-11-17
      相关资源
      最近更新 更多