The Symfony container graph
We may sometimes forget about the fact that we have classes all over the place in our PHP/Symfony projects.
The most important thing is to be able to correctly represent ourselves the hierarchy of the classes themselves.
I created a small dumper that uses the native GraphvizDumper
from the Symfony DependencyInjection component, because
I have been curious about finding a way to make a graph about all the classes I use.
Fortunately, this dumper has been built-in for a while, it’s just not widely used, but it’s really interesting to see what becomes of our container in terms of graphs.
First, let’s use the GraphvizDumper
If you want to use this dumper, it’s easy! (I know we shouldn’t say “easy” in such posts, but, well, I really think it’s easy…)
I’m considering you use Symfony with the Flex architecture (so 3.3+ or 4.0+).
In src/Kernel.php
, add these lines at the bottom of the configureContainer()
method:
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
// ...
// Execute this pass after ALL other passes, so the container can be dumped when asked.
$container->setParameter('container.dumper.graphivz.enable', 'dev' === $this->environment && $this->debug);
$container->addCompilerPass(new DumpGraphContainerPass(), 'removing', -2048);
}
And create the DumpGraphContainerPass
in the src/
directory (don’t need to put it anywhere else, after all, you
shouldn’t probably use this very often).
<?php
namespace App;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper;
class DumpGraphContainerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$parameterEnable = 'container.dumper.graphivz.enable';
$parameterFile = 'container.dumper.graphivz.file';
if (!$container->hasParameter($parameterEnable)) {
$container->setParameter($parameterEnable, false);
}
if (!$container->hasParameter($parameterFile)) {
$container->setParameter($parameterFile, $container->getParameter('kernel.cache_dir').'/container.dot');
}
if (!$container->getParameter($parameterEnable)) {
return;
}
\file_put_contents($container->getParameter($parameterFile), (new GraphvizDumper($container))->dump());
}
}
And it’s done!
Just run your application anytime and anyhow (just running php bin/console
should do the trick).
See the final graph
When you have dumped the container thanks to the above classes, you can now view it with Graphviz.
Ensure you have the dot
binary available in your environment by installing Graphviz executables
for your environment (I tested this on Windows, so you can use it anywhere).
Once installed, use it like this:
$ dot -Tsvg var\cache\dev\container.dot > container.svg
Open container.svg
with your favourite software and enjoy!
The Symfony container graph
I used this to dump the container after a raw composer create
with the different skeletons, enjoy:
Container from symfony/skeleton
Container from symfony/website-skeleton
But… why?
I did this at first because I’m curious.
Of course this graph is quite unreadable, but it’s really interesting to navigate through it.
Just imagine now using this on a way bigger application (I did this on Studio Agate’s one, it’s reaaaally bigger), astonishing, isn’t it?
I published this on this blog to maybe remind everyone that our applications are not a pile of code.
It’s also the result of hundreds and thousands of hours of work, thoughts, brainstorming, knowledge, sharing, discussions and debate from tons of developers, and this is what makes our application so nice.