For the update to Symfony 4.0, I added "_default" and "AppBundle" to services.yml and verified the operation, but the following error occurred.
I have two bundles and want to achieve automatic wiring for each.
Is there anything wrong with it?
https://symfony.com/doc/4.0/service_container/3.3-di-changes.html
ErrorCode
The autoloader expected class "App\Sp\AppBundle\AppBundle" to
be defined in file "/home/vagrant/Symfony2/vendor/composer/../../src/App/Sp/AppBundle/AppBundle.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
services.yml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
AppBundle\:
resource: '../../src/App/Sp/AppBundle/*'
exclude: '../../src/App/Sp/AppBundle/{Entity,Repository,AppBundle.php}'
CommonBundle\:
resource: '../../src/App/Sp/CommonBundle/*'
exclude: '../../src/App/Sp/CommonBundle/{Entity,Repository}'
AppBundle.php
<?php
namespace App\Sp\AppBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AhiSpAdminBundle extends Bundle
{
}
The composer.json PSR-4 autoloader in Symfony Flex by default applies a namespace for App
from the /src
path. The App
namespace will apply to all of the subdirectories and files within the src/
directory.
composer.json
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
Symfony naming conventions also require the *Bundle.php
file to reside in a namespace of the same name [sic] and [sic]. This is comprised of the vendor or category name (Sp) and the namespace (AhiSpAdminBundle) to make SpAhiSpAdminBundle
.
| Namespace Bundle | Class Name |
|------------------------|----------------|
| Acme\Bundle\BlogBundle | AcmeBlogBundle |
| Acme\BlogBundle | AcmeBlogBundle |
// src/Acme/BlogBundle/AcmeBlogBundle.php
namespace App\Acme\BlogBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeBlogBundle extends Bundle
{
}
Since the namespace is App\Sp\AhiSpAdminBundle
, the filename and directory needs to be changed to match the namespace and Symfony bundle class name conventions respectively to src/Sp/AhiSpAdminBundle/SpAhiSpAdminBundle.php
.
Rename the file to match the class name for the PSR-4 autoloader.
mv src/Sp/AppBundle/AppBundle.php src/Sp/AppBundle/SpAhiSpAdminBundle.php
Rename directory to match the namespace for the PSR-4 autoloader.
mv src/Sp/AppBundle src/Sp/AhiSpAdminBundle
Fix the namespace and class name of your bundle to adhere to the Symfony naming conventions.
// src/Sp/AhiSpAdminBundle/SpAhiSpAdminBundle.php
namespace App\Sp\AhiSpAdminBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class SpAhiSpAdminBundle extends Bundle
{
//...
}
Then update your services definitions to match the PSR-4 pathing that is compatible with Symfony.
# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\Sp\AhiSpAdminBundle\:
resource: '../src/Sp/AhiSpAdminBundle/*'
exclude: '../src/Sp/AhiSpAdminBundle/{Entity,Repository,SpAhiSpAdminBundle.php}'
App\Sp\CommonBundle\:
resource: '../src/Sp/CommonBundle/*'
exclude: '../src/Sp/CommonBundle/{Entity,Repository}'
Generate the autoloader files.
composer dump-autoload
Clear and Warmup the Syfmony Cache.
rm -rf var/cache/dev
bin/console --env=dev cache:warmup
If needed repeat the process for the CommonBundle
namespace, class name, and filename of src/Sp/CommonBundle/SpCommonBundle.php
or restructure following the naming conventions to achieve the desired end-results.
// src/Sp/CommonBundle/SpCommonBundle.php
namespace App\Sp\CommonBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class SpCommonBundle extends Bundle
{
//...
}
While the vendor/category name (Sp) is optional in the bundle class name, with non-descriptive names like
AdminBundle
andCommonBundle
, it is best-practice to include the category in the bundle name, as to ensure there are no naming conflicts and to better differentiate between them when debugging and unit-testing.