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.