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.
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;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With