Skip to content

[HttpKernel] Added support for registering Bundle dependencies #5610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions cookbook/bundles/dependencies.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
.. index::
single: Bundle; Dependencies

How to Use Bundle Dependencies to Load other Bundles
====================================================

.. versionadded:: 2.8
Support for bundle dependencies was introduced in Symfony 2.8.

When working on your own bundle(s), you'll sometimes have the need to reuse
other bundles, either by just requiring, overriding or inheriting from them.

While Composer takes care about making sure these dependencies are loaded,
you'll also need to enable these bundles in the kernel.

If your bundle is meant to be reused, bundle dependencies will complicate
your installation documentation. This makes installation and upgrading your
bundle more tedious for your users.

You can avoid this by specifying your dependencies. This will make sure that
they are loaded in the kernel. It'll also make sure they are loaded *before*
your own bundle, to make sure you can extend them.

Additional use case for this is for distribution bundles, where one
bundle is in fact bundling several others.

Specifying Dependencies
-----------------------

Dependencies are specified using FQN_ (`Fully Qualified Name`) for the bundle class in
same format as PHP uses for :phpfunction:`get_class`, and for class_ constant introduced in PHP 5.5.

This implies you can only specify bundles that does not take arguments in it's constructor.
This is in-line with Symfony best practice, avoids same bundle being loaded several times,
and allows this information to be easily cached in future versions of Symfony.

Specifying dependencies is accomplished by implementing the
:class:`Symfony\\Component\\HttpKernel\\Bundle\\BundleDependenciesInterface`::

// src/CacheBundle/CacheBundle.php
namespace CacheBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\Bundle\BundleDependenciesInterface;

class CacheBundle extends Bundle implements BundleDependenciesInterface
{
public function getBundleDependencies($environment, $debug)
{
return array('FOS\HttpCacheBundle\FOSHttpCacheBundle' => self::DEP_REQUIRED);
}
}

.. tip::

If your bundle requires PHP 5.5 or higher, you can also take advantage of
the ``class`` constant::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only for required dependencies though, as the usage of the class constant makes the class required

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left that out as review by @Pierstoval on code PR suggested that PHP actually will not throw error when referring to non existing class, I was expecting the same thing as you, so had added it there earlier.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm indeed. This is nice. I did not know about it (but it seems logical as the class name on which the constant is accessed is known and so it can be optimized at compile time to replace it by a string)
http://3v4l.org/b7aeh

The question then is whether this always work or it is an optimization brought by OpCache

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be engine, at least the comment @Pierstoval pointed to indicates that; just like use statements, it doesn't do lookup before actual use of the class name.

Also your link shows it works like this in hhvm as well, so guess we're safe :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it indeed works without opcache.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should add it as tip on optional dep as well to make this feature more commonly known. By explaining that PHP does not do lookup on class name so this is safe way to have code completion if you use PHP 5.5+, even if class might not be there.


use FOS\HttpCacheBundle\FOSHttpCacheBundle;

// ...
public function getBundleDependencies($environment, $debug)
{
return array(FOSHttpCacheBundle::class => self::DEP_REQUIRED);
}

.. tip::

If your dependency is only to be loaded in ``dev`` or when debugging, use the provided arguments::

use Egulias\SecurityDebugCommandBundle\EguliasSecurityDebugCommandBundle;

// ...
public function getBundleDependencies($environment, $debug)
{
if ($environment !== 'dev') {
return array();
}

return array('Egulias\SecurityDebugCommandBundle\EguliasSecurityDebugCommandBundle' => self::DEP_REQUIRED);
}


Specifying Optional Dependencies
--------------------------------

Specifying a optional dependency follows the same format but with a different constant::

// ...
public function getBundleDependencies($environment, $debug)
{
return array('Oneup\FlysystemBundle\OneupFlysystemBundle' => self::DEP_OPTIONAL);
}


.. _FQN: https://en.wikipedia.org/wiki/Fully_qualified_name
.. _class: http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class
1 change: 1 addition & 0 deletions cookbook/bundles/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Bundles
installation
best_practices
inheritance
dependencies
override
remove
extension
Expand Down
1 change: 1 addition & 0 deletions cookbook/map.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* :doc:`/cookbook/bundles/installation`
* :doc:`/cookbook/bundles/best_practices`
* :doc:`/cookbook/bundles/inheritance`
* :doc:`/cookbook/bundles/dependencies`
* :doc:`/cookbook/bundles/override`
* :doc:`/cookbook/bundles/remove`
* :doc:`/cookbook/bundles/extension`
Expand Down