0

Many of Laravel's build-in framework libraries use closures as arguments. What is the primary purpose of this coding style? Is it just to gain more control over the configuration of the function, to use "functional style", or does it provide dependency inversion of some sort?

I'm curious because I wonder whether I should adopt this style for non-framework development.

For example, wouldn't it be easier just to pass in a second string argument, "site.help" to the function Route::get()?

Route::get('help', function () {
   return View::make('site.help');
});

Note: I am not asking about how closures work or what they do, but rather about style.

2 Answers2

2

The Laravel route directives actually do accept a string as the second parameter:

Route::get('/user', 'UserController@index');

This is parsed by the Laravel router to call the desired action in the desired controller, and then inject whatever the action controller returns into the actual response to the user.

However, action controllers can return quite a few different things: views, redirects, strings, json, and so on.

If you were to just put a simple string intended to be a view name, the router will need to know that the string is a view name (and not a controller@action, or a redirect, or a simple string...).

The closure-style callback provides flexibility - and simpler decision making in the parser.

The closure you provide in your question is rather simple - return the named view. It is possible to write some fairly complex responses:

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) 
{
     // of course, you'd have to write something to get data from your models and inject into a view
});

Or even, better (thanks to implicit binding):

Route::get('posts/{post}/comments/{comment}', function (App\Post $post, App\Comment $comment) 
{
     return View::make('blog.comment', [
         'comment' => $comment
     ]);
});

In order to achieve the same using strings, you'd need a more complex method footprint for the route directive.

HorusKol
  • 4,161
0

The primary reason is so that Route does not have to depend on View. By passing in the function, I am able to reduce dependencies between objects, observe separation of concerns and make each class more testable.