Autoload for controller classes in slim framework

I’m trying to build a site with slim and autoloading my controller classes for the routes. I’m currently setting up the base structure and testing with a single route with nothing more than a simple “Test” output.

I prevously did this stuff with defining a spl_autoload_register function, but as this approach isn’t recommended by slim and composer I want to do it right and I’m not trying to autoload my classes.

My Project is set up as this:

The class BlockController inside the file with the same Name under Controller is inside a namespace defined with namespace MyAPI/Controller;

app/Controller/BlockController.php

namespace MyAPI/Controller;

use Psr/Http/Message/ResponseInterface as Response;
use Psr/Http/Message/ServerRequestInterface as Request;

class BlockController
{
    public function getList(Request $request, Response $response, $args)
    {
        return $response->withStatus(200)
            ->withHeader('Content-Type', 'text/html')
            ->write("Test");
    }
}

I’m loading the dependencies and settings and after that all my routes (which contains currently only some small ones for testing my architecture):

public/index.php:

require __DIR__ . '/../vendor/autoload.php';
$settings = require __DIR__ . '/../app/settings.php';

$app = new /Slim/App($settings);

require __DIR__ . '/../app/dependencies.php';
require __DIR__ . '/../app/routes.php';

$app->run();

app/routes.php (is very simple, will be extended with more Route-files):

require 'Routes/BlockRoute.php';

app/Routes/BlockRoute.php:

use MyAPI/Controller/BlockController;

$container["BlockController"] = function ($container) {
    return new BlockController($container);
};

$app->group('/block', function() use ($container) {
    $this->get('[/]', 'BlockController::getList');
});

So the first command inside BlockRoute.php is the use of the BlockController-namespace. Everything under app/ should have the Base-Namespace MyAPI.
As described in the slim-documentation I planned to do that with to autoload feature of composer, so I modified my composer.json and added the following:

{
  "require": { .. },
  "autoload": {
    "psr-4": {
      "MyAPI//": "app"
    }
  }
}

Edit: updated path to app-folder after the answer from Adam Lavin

After that I ran composer update. Is that the right command for those changes? Or should I use composer install? Couldn’t find any more information what I have to do after making those additions in the autoload-section.

When I run the site now with the php webserver and navigate to this route /block I get the following RuntimeException:
Callable BlockController::getList does not exist

File: C:/Prog/src/vendor/slim/slim/Slim/CallableResolver.php

So the problem is that BlockController doesn’t get included/autoloaded correctly but I don’t understand why or what exactly the problem is. I tried to find some examples of working configurations with slim+composer+autoloading of classes but couldn’t find something related.

Any input appreciated.

Since you’re pointing MyApp// to ../src (the same directory as composer), the autoloader is going to try and find the controller in src/Controllers/BlockController.php.

It should be pointing to ../src/app, though since composer.json is in the src folder it can be simplified to app in the resulting composer.json file.

{
  "require": { .. },
  "autoload": {
    "psr-4": {
      "MyAPI//": "app"
    }
  }
}

Additionally, In your example, the namespace of the BlockController is MoinAPI/Controllers, and should be MyAPI/Controllers.

And finally, in slim, you use a single colon instead of a double to refer to a callable route. BlockController::getList should be BlockController:getList