Reputation: 9976
I am working on a Slim Framework based API. Following the mvc pattern, I want my routes to be controller driven with logger and renderer injected to every controller.
As a start point I checked out a number of example mvc slim skeletons, and decided to base my structor on one particular tutorial and sample project ( http://jgrundner.com/slim-oo-004-controller-classes/ )
In this setup, injection is done by adding the router controllers to the app container like this:
$container = $app->getContainer();
$container['\App\Controllers\DefaultController'] = function($c){
return new \App\Controllers\DefaultController(
$c->get('logger'),
$c->get('renderer')
);
};
This then allow for a nice clean route and controller:
route e.g.:
$app->get('/[{name}]', '\App\Controllers\DefaultController:index');
controller e.g.:
namespace App\Controllers;
use Psr\Log\LoggerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class DefaultController{
private $logger;
private $renderer;
public function __construct(LoggerInterface $logger, $renderer){
$this->logger = $logger;
$this->renderer = $renderer;
}
public function index(RequestInterface $request, ResponseInterface $response, $args){
// Log message
$this->logger->info("Slim-Skeleton '/' route");
// Render index view
return $this->renderer->render($response, 'index.phtml', $args);
}
public function throwException(RequestInterface $request, ResponseInterface $response, array $args){
$this->logger->info("Slim-Skeleton '/throw' route");
throw new \Exception('testing errors 1.2.3..');
}
}
Extending the default controller keeps the controllers neat, but requires adding every new controller object to the app container first, which seems inefficient and messy when you have a lot of classes.
Is there a better way?
Upvotes: 2
Views: 6346
Reputation: 427
You can make basecontroller that contain the acontainer.
<?php
namespace App\Controller;
use Slim\Container;
class Controller
{
var $container;
public function __construct(Container $container)
{
$this->container = $container;
}
public function __get($var)
{
return $this->container->{$var};
}
}
and the container:
<?php
$container['App\Controller\Controller'] = function ($c) {
return new App\Controller\Controller($c);
};
And the controller
<?php
namespace App\Controllers;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use App\Controller\Controller;
class DefaultController extends Controller{
}
Upvotes: 1