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

时间:2017-01-26 21:52:02

标签: php laravel localization laravel-routing

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

  1. 如果路径路径包含区域设置前缀,则应根据此前缀设置区域设置

  2. 如果没有路由前缀,则应将其设置为英语。

  3. 例如:

    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时,我在我的动作函数中获得了额外的第一个参数,该参数派生自区域设置前缀。

    我可以以某种方式隐藏此参数吗?或者有没有办法以更加架构正确的方式实现我想要的东西?

2 个答案:

答案 0 :(得分:1)

对于 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中的其他一些数组中。该文件中的注释很有帮助。

答案 1 :(得分:0)

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

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

    ...

    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 \中间件\语言::类,     \照亮\基金会\ HTTP \中间件\ CheckForMaintenanceMode ::类,

      ];

    2. 在文件路由(route / web.php)中,在组

      中添加前缀

      路由::群组(['中间件' => ['网络'],'前缀' =>' {locale}& #39;],function(){

    3. .....

      希望这个帮助