Quantcast
Channel: Slim Framework – Rob Allen's DevNotes
Viewing all articles
Browse latest Browse all 38

Routing to a controller with Slim 2

$
0
0

In a couple of projects that I've written using Slim Framework 2, I've found it beneficial to organise my code into controllers with injected dependencies; probably because that's how I'm used to working with ZF2.

To make this easier, I've written an extension to the main Slim class and packaged it into rka-slim-controller which will dynamically instantiate controllers for you for each route.

Defining routes is exactly the same as normal for a Slim controller, except that instead of a closure, you set a string containing the controller's classname and method that you want to be called, separated by a colon:

$app = new \RKA\Slim();
$app->get('/hello/:name', 'App\IndexController:hello');
$app->map('/contact', 'App\ContactController:contact')->via('GET', 'POST');

Behind the scenes, this will create a closure for you that will lazily instantiate the controller class only if this route is matched. It will also try to retrieve the controller via Slim's DI container which allows me to inject relevant dependencies into my controller class.

For example, you could group the functionality for authentication:

$app->get('/login', 'User\AuthController:login')->name('login');
$app->post('/login', 'User\AuthController:postLogin');
$app->get('/logout', 'User\AuthController:logout')->name('logout');

The controller needs to interact with a service class, say UserService, which is injected into the controller:

namespace User;

final class AuthController extends \RKA\AbstractController
{
    private $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function login()
    {
        // display login form
    }

    public function postLogin()
    {
        // authentication & redirect
    }

    public function logout()
    {
        // logout functionality
    }
}

In order to inject the service, we define a factory for the DI container and we're done:

$app->container->singleton('User\AuthController', function ($container) {
    return new \User\AuthController($container['UserService']);
});

The nice thing about this approach is that I can group functionality that requires the same dependencies into a single class and be sure that I only instantiate the classes that I need in order to service the request.


Viewing all articles
Browse latest Browse all 38

Trending Articles