Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel route cache on custom route files

I'm building a project in Laravel 5.2 which had a big (big as in a lot of lines) routes.php. To make the routes a little cleaner for the eyes, I've split all the route groups intro separated files. In app\Http\Routes\.

I require all the files in the RouteServiceProvider which works (correction: worked..) perfectly fine for me. After all this I wanted to cache the routes with php artisan route:cache. Then if you went to a page all you get is a 404 error.

“Long” story short: New route logic is crashing AFTER artisan route cache.

This is my map function in RouteServiceProvider (inspired by this answer):

public function map(Router $router)
{
    $router->group(['namespace' => $this->namespace], function ($router) {
        // Dynamically include all files in the routes directory
        foreach (new \DirectoryIterator(app_path('Http/Routes')) as $file)
        {
            if (!$file->isDot() && !$file->isDir() && $file->getFilename() != '.gitignore')
            {
                require_once app_path('Http/Routes').DS.$file->getFilename();
            }
        }
    });
}

Does someone know what the problem is? Or do I just need to put everything back in routes.php if I want to use route caching. Thanks in advance.

like image 906
Dees Oomens Avatar asked Feb 07 '23 23:02

Dees Oomens


1 Answers

TL;DR: Use require instead of require_once and you should be ok.

So, for starters, let's take a look at Illuminate\Foundation\Console\RouteCacheCommand.
You'll notice that it uses getFreshApplicationRoutes method which bootstraps application and fetches routes from router.

I've used this code to create a command that'll do the routes counting:

$app = require $this->laravel->bootstrapPath().'/app.php';

$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();

$routesCnt = $app['router']->getRoutes()->count();

$this->info($routesCnt);

This allows us to have more understanding on how many routes are fetched.

With your code, no matter how many files I've added in Http\Routes folder, none of them got registered. So I've decided to try using "require" instead of "require_once". And voila!

Count of routes increased appropriately.

As to why is this happening, I'm guessing it's because of composer autoloading (this is just an educated guess). Take a look at composer.json:

    "psr-4": {
        "App\\": "app/"
    }

This means that files in app/ folder are auto-loaded. Which means that these files are already loaded, just not in place that you want them. Which means that they won't get loaded again if you're using *_once inclusion functions.

Code in RouteServiceProvider.php, method map that worked for me is:

$router->group(['namespace' => $this->namespace], function ($router) {
        // Dynamically include all files in the routes directory
        foreach (new \DirectoryIterator(app_path('Http/Routes')) as $file)
        {
            $path = app_path('Http/Routes').DIRECTORY_SEPARATOR.$file->getFilename();
            if ($file->isDot() || $file->isDir() || $file->getFilename() == '.gitignore')
                continue;

            require $path;
            $included[] = $path;
        }
    });
like image 127
Jezdimir Lončar Avatar answered Feb 10 '23 11:02

Jezdimir Lončar