Defining a namespace for Laravel 8 routes
Instead, I would simply uncomment this line in app/Providers/RouteServiceProvider.php
which will revert back to the Laravel <8 behavior of automatically prefixing route declarations in 'routes/web.php'
'routes/api.php'
with the App\Http\Controllers
namespace.
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
protected $namespace = 'App\\Http\\Controllers';
This commented out property might not be in your app/Providers/RouteServiceProvider.php
if you created the project when v8 was first released, (seems it was removed then added back) if not, just add it and uncommnet, and make sure its used in the boot
method the prop and it'll work.
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace) // make sure this is present
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace) // make sure this is present
->group(base_path('routes/web.php'));
});
}
Route group namespace in Laravel 8
I think laravel drop the feature, because in laravel 8, controller will be Object oriented class
Laravel Routing 7.* Docs.
Laravel Routing 8.* Docs.
How to use old Laravel routing style in Laravel 8
You can still use it to some extend (e.g. grouping and prefixing a route) but because you're using a FQCN the namespace is redundant. The major advantage using the "new" routing over of the "old" one is refactoring. When you move or rename your controller with an IDE that supports refactoring like PhpStorm you wouldn't need to manually change the name and group namespace of your controller.
In Laravel 5 you were able to use this route notation too but it wasn't outlined in the documentation.
To achieve a similar feeling, import the namespace and use just your class names and get rid of the namespace-group in the definition.
use App\Http\Controllers\Admin\PanelController;
Route::prefix('admin')->group(function () {
Route::get('panel', [PanelController::class, 'index']);
});
If you just cannot live with the new way of defining routes, uncomment the $namespace
property in app/Providers/RouteServiceProvider.php
and you're back to the old way.
Error “Target class controller does not exist” when using Laravel 8
You are using Laravel 8. In a fresh install of Laravel 8, there is no namespace prefix being applied to your route groups that your routes are loaded into.
"In previous releases of Laravel, the
RouteServiceProvider
contained a$namespace
property. This property's value would automatically be prefixed onto controller route definitions and calls to theaction
helper /URL::action
method. In Laravel 8.x, this property isnull
by default. This means that no automatic namespace prefixing will be done by Laravel." Laravel 8.x Docs - Release Notes
You would have to use the Fully Qualified Class Name for your Controllers when referring to them in your routes when not using the namespace prefixing.
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
// or
Route::get('/users', 'App\Http\Controllers\UserController@index');
If you prefer the old way:
App\Providers\RouteServiceProvider
:
public function boot()
{
...
Route::prefix('api')
->middleware('api')
->namespace('App\Http\Controllers') // <---------
->group(base_path('routes/api.php'));
...
}
Do this for any route groups you want a declared namespace for.
The $namespace
property:
Though there is a mention of a $namespace
property to be set on your RouteServiceProvider
in the Release notes and commented in your RouteServiceProvider
this does not have any effect on your routes. It is currently only for adding a namespace prefix for generating URLs to actions. So you can set this variable, but it by itself won't add these namespace prefixes, you would still have to make sure you would be using this variable when adding the namespace to the route groups.
This information is now in the Upgrade Guide
Laravel 8.x Docs - Upgrade Guide - Routing
With what the Upgrade Guide is showing the important part is that you are defining a namespace on your routes groups. Setting the $namespace
variable by itself only helps in generating URLs to actions.
Again, and I can't stress this enough, the important part is setting the namespace for the route groups, which they just happen to be doing by referencing the member variable $namespace
directly in the example.
Update:
If you have installed a fresh copy of Laravel 8 since version 8.0.2 of laravel/laravel
you can uncomment the protected $namespace
member variable in the RouteServiceProvider
to go back to the old way, as the route groups are setup to use this member variable for the namespace for the groups.
// protected $namespace = 'App\\Http\\Controllers';
The only reason uncommenting that would add the namespace prefix to the Controllers assigned to the routes is because the route groups are setup to use this variable as the namespace:
...
->namespace($this->namespace)
...
Laravel 8 Controller does not exist, namespace is in routes and problem only exists on an apache webserver but works locally
Namespaces seem to be case sensitive for the webserver, and I didn't manage to catch the typo. Local artisan and xampp seem to be able to handle it even though it's not correct. The apache webserver had a problem with it. It's supposed to be
use App\Http\Controllers\KnowledgeController;
Route to controller in Laravel 8
TL;DR
Do it like so:
use App\Http\Controllers\PortfolioController;
Route::get('/portfolio', PortfolioController::class)->name('portfolio');
^^^^^^^^^^^^^^^^^^^^^^^^^^
Explanation
Before Laravel 8, routes were namespaced in RouteServiceProvider.php
:
protected $namespace = 'App\Http\Controllers';
// ...
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace) // <----
->group(base_path('routes/web.php'));
}
So, when you defined routes, like in your example:
Route::get('/portfolio', 'PortfolioController')->name('portfolio');
^^^^^^^^^^^^^^^^^^^^^
The PortfolioController
string was namespaced with App\Http\Controllers
.
However, since Laravel 8 this behaviour has been modified. From the v8 release note:
In Laravel 8.x, this property is
null
by default. This means that no
automatic namespace prefixing will be done by Laravel. Therefore, in
new Laravel 8.x applications, controller route definitions should be
defined using standard PHP callable syntax:use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Now, for the particular case you mentioned, __invoke()
methods, this is how you should handle them according to the docs:
When registering routes for single action controllers, you do not need
to specify a method:use App\Http\Controllers\ShowProfile;
Route::get('user/{id}', ShowProfile::class);
Using namespace method in RouteServiceProvder in Laravel package
loadRoutesFrom
is a helper that checks to see if the routes are cached or not before registering the routes.
You can start defining a group of routes then call loadRoutesFrom
in that group in your provider's boot
method:
Route::group([
'domain' => 'api'. config('app.url'), // don't call `env` outside of configs
'namespace' => $this->namespace,
'middleware' => 'api',
], function () {
$this->loadRoutesFrom(__DIR__.'/../../routes/api.php');
});
Or if you prefer the method style of setting the attributes:
Route::domain('api'. config('app.url'))
->namespace($this->namespace)
->middleware('api')
->group(function () {
$this->loadRoutesFrom(__DIR__.'/../../routes/api.php');
});
This is how Laravel Cashier is doing it:
https://github.com/laravel/cashier/blob/10.0/src/CashierServiceProvider.php#L86
Related Topics
Alternative for $_Server['Http_Referer'] PHP Variable in Msie
Clear Data in MySQL Table with PHP
Soapclient: How to Pass Multiple Elements with Same Name
Error 1366 (Hy000): Incorrect String Value: '\Xf0\X9F\X98\X9C' for Column 'Comment' at Row 1
Woocommerce: Display Also Product Variation Description on Cart Items
Php: Check If Xml Node Exists with Attribute
Connect to Azure Active Directory from PHP Web Application
How to Add Rel="Nofollow" to Links with Preg_Replace()
No Mail Received in Inbox with Xampp 1.8.0, Mercurymail and Mail()
PHP Undefined Variable in a Closure
How to Detect If a User Has Logged Out, in PHP
Url Encoded Forward Slashes Breaking My Codeigniter App
Select Statement with Fetch_Array in MySQLi Prepared Statements
PHP - Hide Url (Get) Parameters
How to Check If the Request Came from Mobile or Computer in PHP