Skip to content
Advertisement

Every modification to class causes error ‘Cannot declare class because the name is already in use’

I’ve started a Symfony project for an API and have created my first controller

# services.yaml
parameters:

services:
    _defaults:
        autowire: true
        autoconfigure: true
    App:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'
    AppController:
        resource: '../src/EndPoints/*'
        tags: ['controller.service_arguments']

Controller:

namespace AppController;
class RegisterController extends AbstractController {
    public function register(Request $request): Response {
         //stuff
    }
}

I run this the first time and get an expected result. I do modifications to RegisterController and it dies with the error

Compile Error: Cannot declare class AppControllerRegisterController, because the name is already in use

If I go into the services.yaml and save it (no modifications) I can run it again with the updated code.

This has only just started happening when I’ve added doctrine-test-bundle and been doing testing however I don’t think the two things are related. I’ve checked my .env.local APP_ENV is dev. What is causing a cache that means I have to resave services.yaml for any change to work?

Advertisement

Answer

You are importing the controllers twice.

Here, you are importing all your classes, but your controllers are not excluded from auto-wiring:

    App:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'

And here you import your controller classes again

    AppController:
        resource: '../src/EndPoints/*'
        tags: ['controller.service_arguments']

When the container gets compiled, you end up with a double definition for these classes.

Just do:

services:
    _defaults:
        autowire: true
        autoconfigure: true
    App:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
            - '../src/Tests/'
            - '../src/EndPoints/'
    AppController:
        resource: '../src/EndPoints/*'
        tags: ['controller.service_arguments']

and you’ll be set.

Additionally, you have a PSR-4 mismatch, where the classes at src/Endpoints belong to the namespace Controller. That’s not problematic per-se, but it will only work if your composer.json is properly set. Better have directories that match the namespaces, do not make it harder than it should be.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement