Laravel 5: HTTP Layer – Controllers

Laravel 5: HTTP Layer – Controllers


Controllers can group related request handling logic into a single class.
This is a place, where all functionality residing elsewhere is pulled into to serve incoming request.

Shortcuts:

  1. Define and Route to Controller
  2. Controller Middleware
  3. Dependency Injection & Controllers
  4. Route Caching
  5. Resource Controllers
  6. Spoofing Form Methods
  7. Partial Resource Routes
  8. Naming Resource Routes
  9. Naming Resource Route Parameters
  10. Supplementing Resource Controllers

 

Define and Route to Controller
create scaffolding

To define, or – in other words – scaffold controller, we have handy Artisan command:

Controllers are stored in directory: app\Http\Controllers

You can store controllers inside of any number of sub-directories inside route shown above.
Also, you can create controllers to reside there directly from Artisan:

If sub-directory does not exist, it will be auto-created.

route to controller

Incoming request can be routed to controller like this:

‘@index’ is name of method inside of controller you are routing to.

If controller resides in sub-directory, you can route to that controller using namespace, like this:

If you have bunch of controllers inside of one sub-directory, you can group them right inside of route file.
See here how to … look for: “Grouping Routes: Prefix And Namespace”.

single action controller:

This kind of controller has only one method __invoke().
It is like a poor man’s __construct().
Once you use it, you cannot add anymore methods to such controller.

Also, routing to it is slightly different.
You just call it by class name, o namespace – no need to mention landing method, e.g.:

… and this is our full sample ‘single action controller’:

Controller Middleware
attach middleware to route

More in routes section – look for this ‘Protecting Routes By Middleware’.

middleware in controller constructor – keyword

Some middleware is attached to a keyword.
This is defined in: app\Http\Kernel.php .
More, read here.

middleware in controller constructor – closure

Sometimes, if you are lazy and you do not feel like creating separate class for middleware, you can use closure.

Dependency Injection & Controllers
Constructor Injection

You can type hint (inject objects) in constructor.
Then you can append it to object and make it available to all methods.

Method Injection

If you do not need dependency to be available to entire object, but just to given method, you can inject dependency directly in selected method.
Most often used method injection injects Request instance.

Injection with parameters

If your controller method is also expecting input from a route parameter, simply list your route arguments after your other dependencies.

e.g., if you have route like this:

… you can catch it like so:

Route Caching

Does not apply to closure routes.
Can be up to 100 x faster.

To generate cache, use this code:

Use above code also each time, when you changed something in routed.

Sometimes, you may have to clear cache, before you re-apply route cache command.
You can do this like so:

Resource Controllers
explaining resource controller and route access

Resource controller reduces number of routes, since all you have to do, is:

.. and you get all these routes serviced:

Verb URI

Controller Method

Route Name
GET /stuff index photos.index
GET /stuff/create create photos.create
POST / stuff store photos.store
GET /stuff/{stuff} show photos.show
GET /stuff/{stuff}/edit edit photos.edit
PUT/PATCH /stuff/{stuff} update photos.update
DELETE /stuff/{stuff} destroy photos.destroy

 Just to decipher above maze, all you have to do, is to look at column ‘Controller Method’ and compare that to generated resource Controller.

When you do that, you will see, that controller have all these methods.
All you have to do, is to use URIs according to ones in URI column, to get to proper method.

Here is generated resource controller:

Spoofing Form Methods

Since not all HTTP verbs are used by form interface – only GET and POST are, Laravel allows spoofing missing ones.
More about verbs, go here and scroll down to ‘HTTP Verbs’.

It is easy to do spoofing.

You have two ways:

use helper method:

use standard hidden field:

Partial Resource Routes

If you see at resource controller shown a bit above, you can see a lot of methods.
Each of this methods have it’s access route generated – as shown by table above.

If by any chance, you want to use only selected methods and delete rest of them, and prevent errors appearing, when someone tries to access these missing methods, you have to adjust resource route.

Type 1 adjustment

We will use only methods: ‘index’ and ‘show’:

Type 2 adjustment

We will use all methods, except for ‘create’, ‘store’, ‘update’, ‘destroy’:

These methods above are similar, they are just at it from a different end.

Naming Resource Routes

This allows to change auto-naming Laravel uses to construct routes.
Just look at table above, at URI column.

To access resource controller method ‘create’, you have to use this path:
/stuff/create

Lets say you do not like it and you want to access it using path:
/stuff/better

… you have to define it in routes file, like so:

You changed ‘create’ for ‘better’.

Naming Resource Route Parameters

Lets say you have this path:
/stuff/{stuff}

but you do not like {stuff} and you want to change it for e.g. {better}.
This is how you do it:

… and now you can access it like so:
/stuff/{better}

Supplementing Resource Controllers

If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource; otherwise, the routes defined by the resource method may unintentionally take precedence over your supplemental routes: