0
votes

I'm using the composer to load a simple controller class bu I'm facing a problem with the autoloader. It will give me always this error: Fatal error: Uncaught Error: Class 'Controller' not found.

My composer.json file looks like this:

{
    "require": {
        "nikic/fast-route": "^1.3"
    },
    "autoload": {
      "psr-4": {
        "Controllers\\": "src/Controllers/"
      }
    }
}

and in my project root I have the src folder with the Controllers subfolder inside it.

I'm requiring the autoload and using the Controllers namespace inside my class. On the index where I'm loading the controller using fast route router, I have after the autoloader the use \Controllers\Controller; statement.

What's wrong with my implementation?

here is the full code:

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

use Controllers\Controller;

$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $router) {

    $router->addRoute('GET', '/', 'Controller/index');
    $router->addRoute('GET', '/azienda', 'Controller/about');
    $router->addRoute('GET', '/servizi', 'Controller/services');
    $router->addRoute('GET', '/contatti', 'Controller/contacts');

});

// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];

// Strip query string (?foo=bar) and decode URI
if(false !== $pos = strpos($uri, '?')){
    $uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);

$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
    case FastRoute\Dispatcher::NOT_FOUND:
        // ... 404 Not Found
        break;
    case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
        $allowedMethods = $routeInfo[1];
        // ... 405 Method Not Allowed
        break;
    case FastRoute\Dispatcher::FOUND:
        $handler = $routeInfo[1];
        $vars = $routeInfo[2];
        list($class, $method) = explode("/", $handler, 2);
        call_user_func_array([new $class, $method], $vars);
        break;
}
1

1 Answers

0
votes

When you're using variables as class name (like new $class), they need do contain full qualified name. In your case $class contains Controller while FQN of this class is Controllers\Controller.

One must use the fully qualified name (class name with namespace prefix). Note that because there is no difference between a qualified and a fully qualified Name inside a dynamic class name, function name, or constant name, the leading backslash is not necessary.

https://www.php.net/manual/en/language.namespaces.dynamic.php

You need to put FQN in your dispatcher config:

$router->addRoute('GET', '/', 'Controllers\Controller::index');
$router->addRoute('GET', '/azienda', 'Controllers\Controller::about');
$router->addRoute('GET', '/servizi', 'Controllers\Controller::services');
$router->addRoute('GET', '/contatti', 'Controllers\Controller::contacts');

And handle dispatch results in this way:

case FastRoute\Dispatcher::FOUND:
    $handler = $routeInfo[1];
    $vars = $routeInfo[2];
    list($class, $method) = explode('::', $handler, 2);
    call_user_func_array([new $class, $method], $vars);
    break;