Laravel controller route - php

In Laravel 5.1 I was able to create following route:
Route::controller('posts', 'PostsController');
It was very handy, since I could use methods depending on request type:
public function getCreate()
{
// method for getting
}
public function postCreate()
{
// method for creating
}
In Laravel 5.5 it appears that this functionality (HTTP Controllers) has been removed(?) and replaced by HTTP Requests.
Requests are nice, but not that handy.. and it offers way more methods than I need.
Is there a possibility to keep using request-related method names for controllers in Laravel 5.5?

I think you can use Resource Route
Resource Controllers
Laravel resource routing assigns the typical "CRUD" routes to a controller with a single line of code. For example, you may wish to create a controller that handles all HTTP requests for "photos" stored by your application. Using the make:controller Artisan command, we can quickly create such a controller:
php artisan make:controller PhotoController --resource
This command will generate a controller at app/Http/Controllers/PhotoController.php. The controller will contain a method for each of the available resource operations.
Next, you may register a resourceful route to the controller:
Route::resource('photos', 'PhotoController');
This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions, including notes informing you of the HTTP verbs and URIs they handle.
Actions Handled By Resource Controller
Ref:
https://laravel.com/docs/5.5/controllers#resource-controllers

Route::controller() was eliminated after Laravel 5.3
Route::resource() is very specific to exactly, only create for you and let you access the seven methods to CRUD an object
If you want to create your own views, I believe you have to define all them with Route::get(), Route::post(), etc. in the routes/web file

Related

How to access to laravel routing resource methods?

I am using laravel to have access to my database. I have used the command php artisan make:controller CategoriesController --resource in the terminal to create a class where I can access different methods in one route.
The routing code for the class is: Route::apiResource("categories", CategoriesController::class);. With /categories I can get to the index() method (via get), where I can show my table values. But I do not know how I can use other methods. For example I have created test() with a simple return ["Result"=>"Working"].
I have tried /categories/test /categoriestest /categories%test but I can not show the result from test().
Simple routing works fine when I use specific routes for every method, but I want to make a more clear code so I would like to use the --resource to only have one route.

Do I need to exclude all non-route actions from a Laravel controller middleware?

I'm using controller middlewares in my Laravel 5.2 app. According to the docs, to exclude specific actions from being handled by a middleware, I need to use the except array:
class UserController extends Controller
{
public function __construct() {
// Exclude foo- and barAction from auth middleware
$this->middleware('auth', ['except' => [
'fooAction',
'barAction',
]]);
}
}
Of course, the total number of methods in a controller will almost always be greater than the number of methods linked to specific routes in routes.php. So except for the route-actions there will be others, dealing strictly with the logic - public or private methods.
Do I need to exclude all those non-route actions from a middleware or excluding the route-actions is enough?
EDIT:
I would say that the other, non-route methods - as they are not accessible from outside - don't need to be excluded from a middeware. The question is rather: is the middleware ran for them every time they are accessed? I wouldn't say so but it's nice to make sure.
Your $this->middleware() method is defined in Illuminate\Routing\Controller: it merely saves its arguments in a protected property that is only accessed through a getter.
Other than in tests, that getter is only invoked in two places:
Illuminate\Foundation\Console\RouteListCommand (which handles the route:list Artisan command); and
Illuminate\Routing\ControllerDispatcher (which dispatches routing calls to a controller).

How to set the Laravel middleware order of execution?

The Laravel 5 documentation describes two ways of assigning Middleware:
Assign middleware to the controller's route.
Specify middleware within your controller's constructor.
However, I realised that any code written in the controllers __construct() function will run before the Middleware, even if the Middleware is declared on the first line of the controller's __construct function.
I found a bug report for a similar issue in the Laravel github repository. However a collaborator closed the issue stating "This is the expected behaviour.".
I am thinking that middleware should be "layers" outside the application, while the __construct function is part of the application.
Why is the __construct function executed before the middleware (given it is declared before middleware runs)? and why this is expected?
Another answer to cover another use case to that question
If it's related to the order between middleware it self
You can update the $middlewarePriority in your App\Kernel.
Set Middleware Priority in App\Http\Kernel
For example, here I need my custom auth middleware to run first (before substitute bindings), so I unshift it onto the stack:
public function __construct(Application $app, Router $router)
{
/**
* Because we are using a custom authentication middleware,
* we want to ensure it's executed early in the stack.
*/
array_unshift($this->middlewarePriority, MyCustomApiAuthMiddleware::class);
parent::__construct($app, $router);
}
Alternatively, you could override that entire priority structure if you needed explicit control (not recommended because you'll have to pay closer attention during upgrades to see if the framework changes). Specific to this issue is the SubstituteBindings class that handles route model binding, so just make sure your auth middleware comes sometime before that.
/**
* The priority-sorted list of middleware.
*
* Forces the listed middleware to always be in the given order.
*
* #var array
*/
protected $middlewarePriority = [
\App\Http\Middleware\MyCustomApiAuthMiddleware::class
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Auth\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
The application logic resides in the controller's methods. So basically application lives in the controller's methods, not in the whole controller itself.
Middleware runs BEFORE the request enters the respective controller method. And thus, this is always OUTSIDE the real application. No controller method is executed unless all the Middlewares are passing the request.
The $this->middleware("My\Middleware"); statements that you put in the controller constructor, REGISTERS the My\Middleware for checking before the request enters the application.
If you see the code of a middleware and
if the request is passing, then we send it to the next middleware using the $next($request); statement. This allows multiple middlewares to be executed for a single request. Now, if Laravel run the middleware right at the $this->middleware(...); statement, Laravel would probably not be able to know which middleware should be next checked.
So, Laravel solves this by registering all the middlewares first, then passing the request through all the middlewares one by one.
They updated the order of execution between middlewares, controller and controller's construct.
Previously it was:
1. The global middleware pipeline
2. The route middleware pipeline
3. The controller middleware pipeline
Now its:
1. The global middleware pipeline
2. Controller's Construct
3. The route & controller middlewares
Read more here:
https://laracasts.com/discuss/channels/general-discussion/execution-order-in-controllers-constructor-whit-middleware
https://laravel-news.com/controller-construct-session-changes-in-laravel-5-3

Laravel - controllers without routing

I am newbie to laravel.
I created new controller - book.
This is my code -
class BookController extends BaseController {
public function index()
{
return View::make('book.index');
}
public function insert()
{
return View::make('book.insert');
}
}
My routes.php -
Route::get('book/', 'BookController#index');
//Route::any('book/insert', array('uses' => 'BookController#insert'));
When i uncomment 2nd line, i can access insert page.
Is it possible to access pages without add them to routes.
Now it produce this error
You may read about resource controller.
Execute this on terminal:
php artisan make:controller BookController
This command will generate BookController.php in your app/controllers folder. Read the code for more information.
Define in your routes/web.php file:
Route::resource('book', 'BookController');
Actions Handled By Resource Controller:
Route filters provide a convenient way of limiting access to a given route, which is useful for creating areas of your site which require authentication. So it is better to use route.php as Laravel framework indicates.
you can add filters to there as well, refer documentation

Laravel routes with multiple optional parameters

I am building a RESTful api using Laravel. I am confused on how to do the routing.
I have the following api controller
class APIController extends BaseController{
public function sendMsg($authid, $roomid, $msg){
}
public function getMsg($roomid, $timestamp){
}
}
The URL format I want this to be accessible looks like this:
http://example.com/api/{functionName}/{parameter1}/{parameter2}/.../
Here, in the first parameter, I will have the function name which should map to the function in the controller class and following that the parameters the controller needs.
For example To access the sendMsg() function, the url should look like this:
http://example.com/api/sendMsg/sdf879s8/2/hi+there+whats+up
To access the getMsg() function, the url should look like
http://example.com/api/getMsg/2/1395796678
So... how can I write my routes so that it can handle the dynamic number and different parameters need?
I can write one route for each function name like so:
Route::get('/api/sendmsg/{authid}/{msg}', function($authid, $msg){
//call function...
});
and same for the other function. This if fine but is there a way to combine all function to the APIController in one route?
Yes, you can combine all the function to your APIController in one route by using a resourceful controller which is best suited for building an API:
Route::resource('api' ,'APIController');
But, technically, it's not one route at all, instead Laravel generates multiple routes for each function, to check routes, you may run php artisan routes command from your command prompt/terminal.
To, create a resourceful controller you may run the following command from your command line:
php artisan controller:make APIController
This will create a controller with 6 functions (skeleton/structure only) and each function would be mapped to a HTTP verb. It means, depending on the request type (GET/POST etc) the function will be invoked. For example, if a request is made using http://domain.com/api using GET request then the getIndex method will be invoked.
public function getIndex()
{
// ...
}
You should check the documentation for proper understanding in depth. This is known as RESTful api.

Categories