【问题标题】:Laravel RouteServiceProvider map function not calledLaravel RouteServiceProvider 地图功能未调用
【发布时间】:2020-11-22 15:15:49
【问题描述】:

我正在使用RouteServiceProvider 中的map 函数来操作一些路由,然后再进行进一步处理。 当我在本地机器上运行时,一切都运行良好,但由于某种原因在生产服务器上没有调用地图函数。 为了确保错误不是出于某种原因在我自己的代码中,我使用了原始的 RouteServiceProvider.php,只添加了一些回声用于测试目的:

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * The path to the "home" route for your application.
     *
     * @var string
     */
    public const HOME = '/home';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        //

        echo 'RouteServiceProvider boot';
        parent::boot();
    }

    /**
     * Define the routes for the application.
     *
     * @return void
     */
    public function map()
    {
        echo 'RouteServiceProvider map';
        $this->mapApiRoutes();

        $this->mapWebRoutes();

        //
    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        echo 'RouteServiceProvider mapWebRoutes';
        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        echo 'RouteServiceProvider mapApiRoutes';
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));
    }
}

在生产服务器上运行时,我得到:

RouteServiceProvider boot

在本地机器上运行时:

RouteServiceProvider bootRouteServiceProvider mapRouteServiceProvider mapApiRoutesRouteServiceProvider mapWebRoutes

因此,在生产服务器上,该类似乎已完美加载,并且boot 函数也被调用,但map 函数均未调用。 我尝试清除每种类型的缓存,但结果保持不变。但是在缓存清除期间,它确实调用了所有地图函数:

php artisan route:cache
RouteServiceProvider bootRoute cache cleared!
RouteServiceProvider bootRouteServiceProvider mapRouteServiceProvider mapApiRoutesRouteServiceProvider mapWebRoutesRoutes cached successfully!

知道是什么原因造成的或如何解决?

PS 在生产服务器上,一切都是使用 PHP Deployer 部署的,但其他一切都运行良好,所以我认为这不是问题。

【问题讨论】:

  • 产品和本地机器上的 php 版本是否相同?
  • @kresimir-pendic 是的,都是 7.4
  • php artisan route:list 在 prod 上的输出是什么?
  • 您是否再次清除并缓存了路由?因为如果路线是从缓存中加载的,我相信不应该调用地图函数。 php artisan route:clearphp artisan route:cache
  • @KurtFriars a lot ;) 它显示了 web.php 和 api.php 中指定的所有路由,就像它应该显示的那样

标签: php laravel caching laravel-artisan


【解决方案1】:

当你在生产中使用路由缓存时,map 不再被调用,因为它的目标是生成路由,并且这些路由被缓存。如果你检查Illuminate\Foundation\Support\Providers\RouteServiceProvider,你会看到:

/**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->setRootControllerNamespace();

        if ($this->routesAreCached()) {
            $this->loadCachedRoutes();
        } else {
            $this->loadRoutes();

            $this->app->booted(function () {
                $this->app['router']->getRoutes()->refreshNameLookups();
                $this->app['router']->getRoutes()->refreshActionLookups();
            });
        }
    }

    /**
     * Load the application routes.
     *
     * @return void
     */
    protected function loadRoutes()
    {
        if (method_exists($this, 'map')) {
            $this->app->call([$this, 'map']);
        }
    }

【讨论】:

    【解决方案2】:

    如果您查看框架默认的 RouteServiceProvider,(不是您的应用程序扩展的那个),您会看到:

    /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
            $this->setRootControllerNamespace();
    
            if ($this->routesAreCached()) {
                $this->loadCachedRoutes();
            } else {
                $this->loadRoutes();
    
                $this->app->booted(function () {
                    $this->app['router']->getRoutes()->refreshNameLookups();
                    $this->app['router']->getRoutes()->refreshActionLookups();
                });
            }
        }
    

    如您所见,if ($this-&gt;routesAreCached()) { 然后从缓存中加载路由,$this-&gt;loadRoutes(); 最终调用了 RouteServiceProvider 的 map 函数。

    如果您执行php artisan route:clear,它将停止从缓存加载路线,并且您的地图方法将在每个请求上被调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 2013-12-31
      • 1970-01-01
      相关资源
      最近更新 更多