I just installed Laravel 8 and in this version, I have to type my routes like this:
Route::get('/admin/panel', [App\Http\Controllers\Admin\PanelController::class, 'index']);
But I got used to Laravel 5 routes which looked like this:
Route::namespace('Admin')->prefix('admin')->group(function () {
Route::get('/panel', 'Admin/PanelController#index');
});
So how can I use this Laravel 5 routing inside Laravel 8 version?
If you're wanting to continue using the "older" way of defining a route (i.e. Controller#action) then you can do so but you need to alter the RouteServiceProvider to include the App\Http\Controllers namespace.
This is pretty straight forward and is with the more recent versions of Laravel 8 a simple case of uncommenting the following line:
protected $namespace = 'App\\Http\\Controllers';
If the version of Laravel 8 you're using doesn't have this line in the RouteServiceProvider file, you could upgrade your Laravel version or manually add it. If you manually add the line, you will also need to update the Route definitions in the boot method to use the $namespace property. Again, this is very straight forward, just add the following to the web and api definitions:
->namespace($this->namespace)
So for example:
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Then you should be good to go.
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.
Related
Session driver is set to database currently. Now I want to disable session for some route. I am using laravel 7 in my project. What is the best way to disable the session?
I have tried: in StartSession.php file: \Config::set('session.driver', 'array');
Seems like it doesn't work for me, is there any better way?
Trying to modify code in files within vendor directory is not a good practice as it will get overridden whenever the package is updated.
If you want to remove a middleware from a specific route you can use withoutMiddleware
Route::get('/some-endpoint', function () {
//
})->withoutMiddleware([StartSession::class]);
Laravel Docs - Middleware - Excluding Middleware
I'm working on exposing an API using one base URL (e.g. https://api.domain.com) and having that URL handle all versions of the API (the API consumer will need to send Accept-Version in the request header to indicate which version of the API they're trying to use).
How would I manage this approach in Laravel?
I was thinking that I could put all of my controllers, helpers, models, routes, config, etc. in a, say, 1.0.0 folder and use those for version 1 of my API. When I release a new version, maybe I make copies of the original code, put them in a 1.1.0 folder, and make changes there.
If I were to use this folder approach, what would I need to do in the routes to indicate which folder to use? How would my controllers know what models, helpers, config, etc. to use? Feels like this approach could get very messy and convoluted.
In your RouteServiceProvider.php you can define the routes for the application. Here you can also define the namespace, name prefix, and middleware for the routes. Simply add a new route map for each version of your api. Have the middleware check the version, redirecting if necessary, and set the name prefix/namespace to the correct version directory.
the RouteServiceProvider would look something like:
protected function mapApi-1-0-0-Routes()
{
Route::middleware(['api', 'version'])
->name('1.0.0.')
->namespace('1.0.0')
->group(base_path('routes/api.php'));
}
then your middleware would look something like
public function handle($request, Closure $next)
{
switch ($request->version) {
case "1.0.0":
$route = $request->version.$request->route()->getName();
break;
// more versions
return redirect()->route($route)->with($request);
}
I haven't tested this.
Route group name prefixes:
https://laravel.com/docs/7.x/routing#route-group-name-prefixes
Route namespaces:
https://laravel.com/docs/7.x/routing#route-group-namespaces
Redirecting named routes:
https://laravel.com/docs/7.x/redirects#redirecting-named-routes
Global middleware:
https://laravel.com/docs/7.x/middleware#global-middleware
Writing service providers:
https://laravel.com/docs/7.x/providers#writing-service-providers
I am making a module for Laravel, and for the ease of reusability, I am making it as a separate composer module.
In this module, I have to define a catch-all route, but I dont want it to override any of the manualy added routes, in the project.
Does anyone have a good idea how I can get this behaviour?
I am registering my route in the ServiceProviders boot() method like this:
public function boot()
{
$this->loadMigrationsFrom(__DIR__.'/migrations');
$this->loadRoutesFrom(__DIR__.'/routes/routes.php');
}
and the routes.php is also rather simple:
$regex = ".*";
Route::namespace('Asator\\Runepost\\Controllers')
->middleware(['web', DynamicContent::class])
->group(function($route) use ($regex) {
$route->any('{any}', 'RunepostFrontController')->where('any', $regex);
});
Is it possible to somehow add the route as the last route, after the manually added routes has run?
Just add your module's ServiceProvider after the App's RouteServiceProvider in config/app.php and make sure your catch-all-route is the last route of your module's routes.
I am having problems with autocompletion in PhpStorm using Laravel. I have set up the IDE accordingly from this guide:
https://confluence.jetbrains.com/display/PhpStorm/Laravel+Development+using+PhpStorm
I cannot autocomplete basic functions like Input::only or Input::has. The closest answer I can find is in this thread:
Laravel Intellisense / autocomplete with PhpStorm
However, Input is already added as alias in config/app.php - still not working.
Anyone experienced same problem and/or know a solution to this?
EDIT:
Sorry for not providing code example - it's only been some Laravel trial and error, but here goes:
I have the route:
Route::post('/login', 'LoginController#authenticate');
In the action of the controller I have tried the following:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
class LoginController extends Controller
{
public function authenticate(Request $request) {
Input::get(); // <-- autocompletes
Input::has(); // <-- NO autocomplete
$request->only(); // <-- autocompletes
$request->validate(); // <-- NO autocomplete
}
}
use laravel ide-helper package
it can provide accurate autocompletion. Generation is done based on the files in your project.
phpstrom support auto-complete best thing is that
By default laravel is huge.
Its a way to clean up only needed depencies?
For sample, when i'm installing laravel, some default configs are provided. I dont need the API Routes or other, when i'm using the normal web-routes.
If you want to don't want to load API route you can simply comment out this line in RouteServiceProvider
public function map()
{
$this->mapApiRoutes(); //comment this line
$this->mapWebRoutes();
//
}
Hope this helps.
To make Laravel leaner, another good approach is to have a look on your ServiceProviders, which are loaded in config/app.php. Just deactivate all ServiceProvider you don't need and test your application.
ServiceProviders can also be loaded from packages. So take also attention to loaded packages through your composer.json.