Laravel Функция карты RouteServiceProvider не вызывается - PullRequest
4 голосов
/ 02 августа 2020

Я использую функцию map в RouteServiceProvider, чтобы управлять некоторыми маршрутами, прежде чем они будут обрабатываться дальше. Когда я запускаю на своем локальном компьютере, все работает нормально, но на производственном сервере по какой-то причине не вызываются функции карты. Чтобы убедиться, что ошибка по какой-то причине не возникла в моем собственном коде, я использовал оригинальный 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, но все остальное работает нормально, поэтому я предполагаю, что проблема не в этом.

Ответы [ 2 ]

2 голосов
/ 02 августа 2020

Если вы посмотрите на 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->routesAreCached()) {, тогда маршруты загружаются из кеша, и $this->loadRoutes(); - это то, что в конечном итоге вызывает функцию map вашего RouteServiceProvider.

Если вы сделаете php artisan route:clear, это остановит загрузку маршрутов из кеша, и ваши методы карты будут вызываться при каждом запросе .

2 голосов
/ 02 августа 2020

Когда вы используете кэширование маршрутов в производстве, 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']);
        }
    }
...