Controllers using Container Resolution

Hi Folks,

I recently started experimenting around with Slim and it looked fun to start with. To be honest, I haven’t worked a lot with php. Now I was reading about the routing mechanisms and liked this particular feature of container resolution described here: http://www.slimframework.com/docs/objects/router.html#container-resolution

Before moving further with question, here is what I have got in my project folder:

-- public
-- | -- index.php
-- | -- .htaccess
-- src
-- | -- controllers
-- | -- | -- HomeController.php
-- | -- dependencies.php
-- | -- middleware.php
-- | -- routes.php
-- | -- settings.php
-- vendor

So what I wanted to achieve was:

  1. Keep all my routes in routes.php like this:
    $app->get('/home', '\HomeController:home');

  2. Keep all controllers in my controllers folder and autoload them using an iterator which goes through the folder and includes what ever php files are there in folder.

  3. My container object is defined in dependencies.php.

Now I tried calling the home method of HomeController, but couldn’t find any way. Can someone please help me out. I don’t need the entire code, just an approach as to how this can be achieved.

Thanks,

What is the problem? Does it output any errors?

Can you show your code?

– routes.php
<?php $app->get('/groups', '\GroupsController:index');

– GroupsController.php

class GroupsController {
protected $ci;
//Constructor
public function __construct(ContainerInterface $ci) {
    $this->ci = $ci;
}
public function index($request, $response, $args) {
    $response->getBody()->write("Hello, brother");
    return $response;
    //your code
    //to access items in the container... $this->ci->get('');
}
}

I also tried the following in dependencies.php

//$container['GroupsController'] =function ($c){ // return './controllers/GroupsController.php'; //};

and in my index.php I am including all my controllers using the following code.

$controllers = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(DIR . ‘/…/src/controllers’), RecursiveIteratorIterator::SELF_FIRST
);

$iterator = new AppendIterator();
$iterator->append($controllers);
foreach ($iterator as $controller) {
$filetype = strtolower(pathinfo($controller, PATHINFO_EXTENSION));
if ($controller->isDir() || $filetype != “php”) {
continue;
}
require_once $controller;
}

I am not sure if the above was helpful for you, but I am stuck at how my controllers and routes and services will interact with each other. Coming from laravel, where everything is defined on its own and you just need to work on app logic, this looks a bit confusing to me.

Well, on your place I would go from easiest to hardest. I my opinion your index.php on your first steps should look like:

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';

// includes your controller for testing!!!!!!!!!!!!!!
require "../src/controllers/GroupsController";

$app = new \Slim\App;

$app->get('/groups', '\GroupsController:index');

$app->run();
?>

Also, you may want to add

ini_set(‘display_errors’, ‘On’);

in the start of your index file to see errors outputted.

So, if this simple “index.php” code will work for your (did not test it myself), than next you can introduce your iterator system :slight_smile:

BTW, in my project I have this code at the begining of index.php

spl_autoload_register(function ($classname) {
	$classname = str_replace('\\', '/', $classname);
    require ("../app/" . $classname . ".php");
});

my “app” folder is yours “src”,

and if need some class to call, I simply do like this:

$c = new \EPA\Controllers\Main()

So, I do not have this problem with to require each my class… it is done dynamically by my autoloader definition))

Of Course, I use namespaces, so in your class file at the beginning you must specify “namespace \EPA\Controllers”;

hope this helps…

I ended up adding the autoload function for my classes and removed unnecessary codes from my contructs. Its not fully functional right now, but I can atleast get to that function.

If you properly namespace your code, there is no need to use a custom autoload function. Keep it simple!