I have a number of private, custom bundles that I use in my Symfony projects. Under Symfony 3, they lived in a sub-directory of src:
src/
DSL/
DSLLibraryBundle/
DSLTelnetBundle/
...
SiteBundle/ # (or AppBundle)
Under Symfony 4, the application-specific bundle is gone and it's unclear to me where my custom bundles should live.
The documentation on bundles (https://symfony.com/doc/current/bundles/best_practices.html#bundles-naming-conventions) provide no specific recommendations for placing custom bundles.
I have tried placing my DSL directory directly under the project directory and under src/. I end up with undefined class errors either way.
I currently have:
src/
DSL/
LibraryBundle/
DSLLibraryBundle.php
The bundle file:
// src/DSL/DSLLibrary/DSLLibraryBundle.php:
namespace DSL\LibraryBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class DSLLibraryBundle extends Bundle
{
}
The entry in bundles.php:
DSL\LibraryBundle\DSLLibraryBundle::class => ['all' => true],
Current error when running a console command:
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "DSLLibraryBundle" from namespace "DSL\LibraryBundle".
A couple of notes:
- My custom bundles are not installed via Composer
- The actual DSL/ directory will be a symlink once I get this working
A Symfony bundle is a collection of files and folders organized in a specific structure. The bundles are modeled in such a way that it can be reused in multiple applications. The main application itself is packaged as a bundle and it is generally called AppBundle.
So, without further ado, here are the most useful bundles according to you, the Symfony community (in parenthesis, the percent of survey answers that noted each bundle): FOSUserBundle (60%) FOSRestBundle (30%) KnpMenuBundle (25%)
Fabien Potencier said in the Symfony 4 best practices blog post "Bundle-less applications is just one of the best practices changes for Symfony 4". You must not generate new bundles, you can use default "App" bundle for your whole project. Show activity on this post. Show activity on this post.
The directory structure of a bundle is meant to help to keep code consistent between all Symfony bundles. It follows a set of conventions, but is flexible to be adjusted if needed.
The new bundle is called AcmeTestBundle, where the Acme portion is an example name that should be replaced by some "vendor" name that represents you or your organization (e.g. AbcTestBundle for some company named Abc ). Start by adding creating a new class called AcmeTestBundle: The AbstractBundle was introduced in Symfony 6.1.
Bundles used in your applications must be enabled per environment in the config/bundles.php file: In a default Symfony application that uses Symfony Flex , bundles are enabled/disabled automatically for you when installing/removing them, so you don't need to look at or edit this bundles.php file.
Update April 12, 2019:
In the end, I took a completely different approach than my initial attempts.
In a nutshell, I now use composer to include my custom bundles.
My custom bundles live in their own directory tree.
Each bundle must have a valid composer.json file defining the bundle. For example:
{
"name": "dsl/base-bundle",
"description": "Base bundle required by all other DSL bundles",
"type": "symfony-bundle",
"version": "2.1.0",
"license": "proprietary",
"authors": [{"name": "David M. Patterson", "email": "[email protected]"}],
"minimum-stability": "stable",
"require": {
},
"require-dev": {
},
"autoload": {
"psr-4": {
"Dsl\\BaseBundle\\": "src/"
}
}
}
Then define a custom repository in the project's composer.json file:
"repositories":[
{
"type": "path",
"url": "/full/path/to/DslBaseBundle"
},
], ...
Then do a composer require dsl/base-bundle
Composer will create a symlink in vendor/ to the bundle and everything works as expected from there on.
My personal library is a regular Symfony project with a lib sub-directory that contains my bundles, each in its own sub-directory below lib/.
The Symfony application provides me with a convenient test bed. Note that the custom bundles must be included in it the same as for any other Symfony project.
@Stnaire, hope that helps.
It's actually not as bad as it's painted in other comments - you can still have your private bundles inside src/
, you just have to explicitly exclude them from autowiring, so they don't get accidentally loaded with an incorrect namespace.
Lets say you have a PrivateBundle
in src/PrivateBundle
.
You set up it's autoloading in composer.json
like so:
"autoload": {
"psr-4": {
"App\\": "src/",
"SomeNamespace\\PrivateBundle\\": "src/PrivateBundle/"
}
}
and in your services configuration (I usually use config/services.yaml
) do this:
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/PrivateBundle'
If you don't add this exclude, your SomeNamespace\PrivateBundle\*
classes get automatically loaded by Symfony as App\PrivateBundle\*
, but contain namespace SomeNamespace\PrivateBundle;
, so when PHP detects a usage of SomeNamespace\PrivateBundle
it autoloads them again through Composer, resulting in Cannot declare class *, because the name is already in use
errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With