Callable does not exist or because it is not a class nor a valid container entry

Im getting an error:

Callable AppName\Auth\TestController::test does not exist

It seems to be related to: Error "not a class nor a valid container entry" but the answers also did not solve my problem.

Im sure its a stupid configuration error. this is the first time im setting up slim.

im on php 8.2

in some very simple code:

directory structure

/repository-name
    /public
        index.php
    /src
        /Auth
            TestController.php
    /vendor
    .htaccess

composer.json

{
    "autoload": {
        "psr-4": {
            "AppName\\": "src/"
        }
    },
    "require": {
        "slim/psr7": "^1.4",
        "slim/slim": "4.*",
        "php-di/slim-bridge": "3.*"
    }
}

index.php

<?php

declare(strict_types=1);

use DI\ContainerBuilder;
use AppName\Auth\TestController;
use Slim\Factory\AppFactory;

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

try {
    $builder = new ContainerBuilder();
    $builder->useAutowiring(true);

    $container = $builder->build();

    AppFactory::setContainer($container);
    $app = AppFactory::create();

    $app->addBodyParsingMiddleware();
    $app->addRoutingMiddleware();

    // This works!
    $app->get('/', function ($request, $response) {
        $response->getBody()->write("Hello world!");
        return $response;
    });

    // This gives an error
    $app->get('/test', [TestController::class, ':test']);
// same goes for     , TestController::class . ':test');
// or with           , TestController::class); // __invoke() in the class

    $app->run();

} catch (Exception $e) {
    echo $e->getMessage();
}

TestController.php

<?php

declare(strict_types=1);

namespace AppName\Auth;

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

class TestController
{
    public function test(Request $request, Response $response): Response
    {
        $response->getBody()->write('Hello World');

        return $response;
    }
}

.htaccess

<IfModule mod_rewrite.c>

RewriteEngine On
# RewriteBase /
# NOT needed unless you're using mod_alias to redirect

RewriteCond %{REQUEST_URI} !/public
RewriteRule ^(.*)$ public/index.php/$1 [L]
# Direct all requests to /public folder
</IfModule>

In desperation I just tried moving my .htaccess to /public, then chanching it to:

RewriteEngine  on
RewriteRule ^(.*)$ index.php?$1 [L]

and telling apache my documentroot is /public

Simple normal routes work, just like before.
Route with class gives the same error:
Callable AppName\Auth\TestController::test does not exist

For good measure, here is the Slim Application Error message:

Slim Application Error

The application could not run because of the following error:

Details

Type: RuntimeException

Code: 0

Message: Callable AppName\Auth\TestController::test() does not exist

File: C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\CallableResolver.php

Line: 138

Trace

#0 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\CallableResolver.php(90): Slim\CallableResolver->resolveSlimNotation(ā€˜AppName\Auth\Teā€¦ā€™) #1 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\CallableResolver.php(63): Slim\CallableResolver->resolveByPredicate(ā€˜AppName\Auth\Teā€¦ā€™, Array, ā€˜handleā€™) #2 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\Routing\Route.php(340): Slim\CallableResolver->resolveRoute(ā€˜AppName\Auth\Teā€¦ā€™) #3 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65): Slim\Routing\Route->handle(Object(Slim\Psr7\Request)) #4 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #5 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\Routing\Route.php(315): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #6 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\Routing\RouteRunner.php(68): Slim\Routing\Route->run(Object(Slim\Psr7\Request)) #7 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\Middleware\ErrorMiddleware.php(76): Slim\Routing\RouteRunner->handle(Object(Slim\Psr7\Request)) #8 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\MiddlewareDispatcher.php(121): Slim\Middleware\ErrorMiddleware->process(Object(Slim\Psr7\Request), Object(Slim\Routing\RouteRunner)) #9 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\MiddlewareDispatcher.php(65): Psr\Http\Server\RequestHandlerInterface@anonymous->handle(Object(Slim\Psr7\Request)) #10 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\App.php(199): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #11 C:\Users\Reinier\PhpstormProjects\appname-api-v2\vendor\slim\slim\Slim\App.php(183): Slim\App->handle(Object(Slim\Psr7\Request)) #12 C:\Users\Reinier\PhpstormProjects\appname-api-v2\public\index.php(28): Slim\App->run() #13 {main}

Hi @reinier Please take a look here.

When you use an array, you donā€™t need to add the ā€œ:ā€ before the method name. Example:

$app->get('/', [\HomeController::class, 'home']);

None of these work for me:

$app->get('/', 'TestController:test');
$app->get('/', TestController::class . ':test');
$app->get('/', [TestController::class, 'test']);

Neither with the \ in front of the class name, but then also the IDE just doesnt resolve the class to anything.

For me, it looks like a composer autoloading issue. This is not directly related to Slim itself.

I would recommend to check out my Slim 4 Tutorial to build a basic structure, step by step.

Then you may try this Slim 4 package to configure the Slim routing for Apache.

1 Like

Thanks for those links! I deleted everything and followed your step-by-step and now it just works :man_shrugging:

1 Like

OlĆ”,
estou tentando seguir seu tutorial, e funcionou, porƩm quando tento adicionar controllers e mapear rotas para mƩtodos recebo erros do tipo:

Type: RuntimeException

Code: 0

Message: Callable AuthController::loginIndex() does not exist

File: C:\projects\slim-base\vendor\slim\slim\Slim\CallableResolver.php

Line: 144

eu simplesmente adicionei um controller:

<?php

namespace Src\Auth\Controller;

class AuthController {

    public function __construct() {}
    
    public function loginIndex(Request $request, Response $response, array $args): Response {
        $response->getBody()->write('Login');
        return $response;
    }
}

meu arquivo em config/container.php:

<?php

use Psr\Container\ContainerInterface;
use Slim\App;
use Slim\Factory\AppFactory;

return [
    'settings' => function () {
        return require __DIR__ . '/settings.php';
    },

    App::class => function (ContainerInterface $container) {
        $app = AppFactory::createFromContainer($container);

        // Register routes
        (require __DIR__ . '/routes.php')($app);

        // Register middleware
        (require __DIR__ . '/middleware.php')($app);

        return $app;
    },
];

meu arquivo de configuraĆ§Ć£o de rotas global (config/routes.php):

<?php

use Slim\App;


return function (App $app) {
    foreach (glob( dirname(__FILE__) . '/../routes/*.php') as $routeFile) {
        require $routeFile;
    }
};

meu arquivo de rotas para auth (routes/auth.php):

<?php

use Src\Auth\Controller\AuthController;

$app->group('/auth/login', function(\Slim\Routing\RouteCollectorProxy $app) {
    $app->get('', 'AuthController:loginIndex');
});