Can't get composer autoload to work

Hi

I’m using Slim to create a simple API. I would like to use a controller class called from the router.
This is the relevant part of my router.php

$app->group('/api/course/v1', function () use ($app) {
	$app->post('', '\Course:handlePost');
});

This is the relevant part of my dependencies.php:

// autoload class and make sure logger is available
$container['\Course'] = function($c) {
	// >> include_once __DIR__ . '/controllers/courseController.php';
	return new App\Controller\Course($c);
};

This is the relevant part of my composer.json:

"autoload": {
    "psr-4": {
        "App\\Controller\\": "src/controllers"
    }
},

This is the relevant part of my controller:

namespace App\Controller;

class Course {
	private $app;
	private $logger;

	public function __construct($app) {
		$this->app = $app;
		$this->logger = $app->logger;
	}

	/**
	 * Handle the Course POST request
	 */
	public function handlePost() {
		$this->logger->info("Coursecontroller::handlePost route called");
		echo "Hello";
	}
}

This works if i use the include in dependencies.php, however i want the controller (and all classes in that namespace) to autoload instead of having to include them. I understand that I can do this by using autoload in composer.json (as shown above) but I still get class not found errors instead
Type: Error
Message: Class ‘App\Controller\Course’ not found
File: /{path to slim root}/src/dependencies.php

I tried using composer dump-autoload but to no avail.

Can anyone point out what I am doing wrong?

Did you require the __DIR__.'/pathToVendor/autoload.php'; on top of your index.php file?

Thanks for your reply Damian. Yes, i have the standard

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

in my index.php. I used the skeleton to start building my application

This is the app structure I’ve been using. Not that it’s a standard by any means but it works well in my apps.

This is the custom autoloader I use: (app/autoload.php)

spl_autoload_register(function($className) {
  $file = str_replace('\\',DIRECTORY_SEPARATOR,$className);
  require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . $file . ".php";
});

My public/index.php:

chdir(dirname(__DIR__));

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

// slim app instance
$app = new Slim\App;

// routes here

$app->run();

My app structure:

www.mysite.com
  app/
	/controllers
	/models
    autoload.php
  public/
	.htaccess
	index.php
  vendor/
  composer.json
  composer.lock

My namespace follows the directory structure:

namespace App\Controllers;

class Home {
}

A better approach is to have the complete application in a namespace (where MainNameSpaceis an example) like this

"autoload" : {
    "psr-4": {
        "MainNameSpace\\": "src/",
        "Tests\\": "tests/"
    }
}

So on top of one of my controllers:

 namespace MainNameSpace\ModuleX\Controllers;

The advantage is, you never have to add anything to the composer again, because everything is relative from src
(except tests)

Thanks for your help guys! But I didn’t want to use the spl_autoload functions, because the Slim framework uses the composer/autoload functions and I’d rather not use two methods in the same project. But I couldn’t get them to work. Now I know why: It’s all about naming conventions.
My class filename is CourseController.php but the class in there is named Course. Therefore the autoload can’t find the class. I changed the classname to CourseController and now everything works, without spl_autoload but using the composer autoload:

"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    }
},
"autoload": {
    "psr-4": {
        "App\\Controller\\": "src/controllers"
    }
},

Extra note: there’s a autoload-dev in your composer.json. You do not need your class loader namespace in there as well.

Did you dump autoload file via command line ?
composer dump-autoload -o

Did you dump autoload file via commnad line?

$ composer dump-autoload -o

Hi @amitkhare, it was a problem related to the psr-4 naming conventions, see my notes above.