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

1.6k views Asked by At

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/'
    App\Controller\:
        resource: '../src/EndPoints/*'
        tags: ['controller.service_arguments']

Controller:

namespace App\Controller;
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 App\Controller\RegisterController, 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?

3

There are 3 answers

3
yivi On BEST 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

    App\Controller\:
        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/'
    App\Controller\:
        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.

0
Ihor Kostrov On

From your services.yaml looks like you need to change the controller part.

From

App\Controller\:
    resource: '../src/EndPoints/'
    tags: ['controller.service_arguments']

To

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

But if you want to put controllers into the EndPoints folder, you need also change the alias in your config.

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

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

And don't forget to change the routing config

0
Ridouan Rodwinax On

you just forget the namespace in the class that you have been created an use it