Symfony 4 - The autoloader expected class […] to be defined in file

SlimenTN picture SlimenTN · Feb 18, 2018 · Viewed 9.5k times · Source

I'm trying to add an old Bundle that I have built on Symfony 3.* to Symfony 4 but I get this error:

The autoloader expected class "App\SBC\TiersBundle\Controller\ChantierController" to be defined in file "/Applications/MAMP/htdocs/Projects/HelloSymfony4/vendor/composer/../../src/SBC/TiersBundle/Controller/ChantierController.php". The file was found but the class was not in it, the class name or namespace probably has a typo in /Applications/MAMP/htdocs/Projects/HelloSymfony4/config/services.yaml (which is loaded in resource "/Applications/MAMP/htdocs/Projects/HelloSymfony4/config/services.yaml").

It seems like the framework did not recognise the namespace of the bundle so I did these steps:
In config/bundle.php I added the third line:

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
    \SBC\TiersBundle\TiersBundle::class => ['all' => true], // this one
    Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
];

And in composer.json I added the first line in autoload section:

"autoload": {
        "psr-4": {
            "SBC\\": "src/SBC/",
            "App\\": "src/"

        }
    },

Because the namespace of my Bundle starts with SBC\, and I have launched composer dump-autoload in the console.

<?php

namespace SBC\TiersBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class TiersBundle extends Bundle
{
}

ChantierController.php:

namespace SBC\TiersBundle\Controller;

use SBC\TiersBundle\Entity\Chantier;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;


class ChantierController extends Controller
{
...
}

And this is my Bundle under /src:
enter image description here

Unfortunately still facing the same error, how can I fix it and thanks in advance.

UPDATE: config/services.yaml:

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    SBC\:
        resource: '../src/SBC/*'
        exclude: '../src/SBC/TiersBundle/{Entity,Migrations,Tests}'

    SBC\TiersBundle\Controller\:
        resource: '../src/SBC/TiersBundle/Controller'
        tags: ['controller.service_arguments']

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

Answer

Jakub Krawczyk picture Jakub Krawczyk · Feb 19, 2018

The problem is most likely caused by Symfony configuration and conflict in namespaces. First you need to adjust your config/services.yaml:

SBC\:
    resource: '../src/SBC/*'
    exclude: '../src/SBC/TiersBundle/{Entity,Migrations,Tests,Kernel.php}'

SBC\TiersBundle\Controller\:
    resource: '../src/SBC/TiersBundle/Controller'
    tags: ['controller.service_arguments']

App\:
    resource: '../src/*'
    exclude: '../src/{SBC,Entity,Migrations,Tests,Kernel.php}'

This way you'll define defaults for your namespace and prevent the default namespace App to include your directory when generating autoload classes. Note that if you are using annotation routes, you also need to adjust config/routes/annotations.yaml:

sbc_controllers:
    resource: ../../src/SBC/TiersBundle/Controller/
    type: annotation

so the routes are generated correctly. After performing these steps run composer dump-autoload again and clear Symfony's cache.

This might be helpful in the future if you run into another problems: https://github.com/symfony/symfony/blob/master/UPGRADE-4.0.md