Symfony Flex is a modern replacement for the Symfony Installer, and not the name of the next Symfony version. As the intro text says:
Internally, Symfony Flex is a Composer plugin that modifies the behavior of the require and update commands. When installing or updating dependencies in a Flex-enabled application, Symfony can perform tasks before and after the execution of Composer tasks.
The new Symfony will be called just Symfony 4, and while this tutorial will deal only with the Flex tool, it will mention some Symfony 4 upgrades as well.
Key Takeaways
- Symfony Flex is a modern replacement for the Symfony Installer that modifies the behavior of the require and update commands, providing additional options during installation and configuration of your Symfony project. It is not a new version of Symfony, but a tool to enhance it.
- Symfony Flex respects the upcoming Symfony 4 updates which include: requirement of PHP 7+, optional folders for simpler directory trees, removal of web folder replaced with a public folder, temporary files under /var in the root of the project folder, source code under /src, configuration in /config, and templates in /templates.
- Flex will have its own Symfony-verified list of packages known as recipes. These official packages can be found in Flex’s configuration. By endorsing some packages, Symfony is becoming as opinionated as Laravel, aiming to consolidate the way to build Symfony apps.
- Symfony Flex simplifies the process of adding bundles to your project. It automatically activates the bundle and sets up a folder with a base layout view, as well as a configuration file. It also allows for the addition of unofficial bundles and third party tools, although these will not be auto-configurable by Flex and will need to be registered manually.
Still Under Development
Symfony Flex can be considered a Composer wrapper, in that it provides your Symfony project with additional options during installation and configuration. It was developed with simplicity in mind, and obviously heavily influenced by the user-friendliness of Laravel. Remember, Laravel got to its current level of popularity due to its ease of use and the low entry barrier it provides newcomers with, and Symfony wanted to emulate this.
It should be noted that both Flex and Symfony 4 are still under development, slated for release somewhere at the end of November this year (2017). As such, some of the features mentioned in this post may have changed by the time you read it, but we’ll do our best to keep it up to date.
Most notably, the use of a makefile and the make tool to build a project if Symfony/Console is unavailable is still up in the air, as it seems to not be working properly on some operating systems. Fabien recently held a survey around this, asking for the community’s suggestions to a replacement, and overwhelmingly, the community voted in favor of just making Symfony/Console required.
What’s Different?
Most notably, Flex respects the coming Symfony 4 updates which boil down to the following major changes:
- PHP 7+ is required
- all folders are optional. If your project isn’t using one, it doesn’t have to be there. This makes the directory tree much simpler and more readable. Additionally, often useless files like
.htaccess
,LICENSE
, andREADME
have been removed as well – a project which needs those can easily add them. - there is no more
web
folder. Instead, there is thepublic
folder, like in all other major frameworks. This consolidates user experience across ecosystems. - temporary files go under
/var
in the root of the project folder, with the/var/cache
subfolder reserved for long term cache, like merged class files for deploying apps as read-only artifacts - source code goes under
/src
. No/app
. - configuration goes into
/config
. - templates go into
/templates
. - Flex will have its own Symfony-verified list of packages that are referenced by one and one alias alone. So executing
composer require cli
will actually trigger Flex, which will look in its list of packages, find the one tagged ascli
(in this case, Symfony Console), and install it. These “official” packages are called recipes, and can be found here. To accept user-submitted recipes, a flag exists in Flex’s configuration which needs to be set to true:composer config extra.symfony.allow-contrib true
. Those recipes can be found here. By officially endorsing some packages, Symfony is in many ways becoming as opinionated as Laravel. While this is bad in some ways, it’s very good in many more ways: a consolidated, opinionated way to build Symfony apps used by most people so that everyone is on the same page. - bundle fragments no longer need to be custom-activated and added into a ton of files. Flex automates this, as well as their removal.
- instead of parameters in config files, Symfony 4 will be using environment variables like Laravel
Bootstrapping
As usual, we’ll assume you’re already running a healthy VM environment like Homestead Improved so you can follow along.
Okay, let’s get our hands dirty with an example app. All Symfony apps can now be started from the bare bones super-minimal Symfony Skeleton app:
composer create-project symfony/skeleton flexy
Notice the created directory structure.
In /public
, we no longer have app.php
and app_dev.php
, only the index.php
file. The type of the environment (test / dev / prod) is now dictated with environment variables, and reads the configuration from the /config
folder.
Notice how the end of the installation process mentions that make cache-warmup
was called, and that you can run make serve
. This is where the new Symfony uses the “controversial” Makefile approach mentioned above. This might change.
Out of the box, opening this skeleton in the browser will throw an error because no routes have been defined yet. Let’s fix this.
index:
path: /
defaults: { _controller: 'App\Controller\DefaultController::index' }
config/routes.yaml
We’ll need to create this controller and its index
action:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController
{
public function index()
{
return new Response('Hello');
}
}
This will produce a simple Hello screen, like so:
Execution Permissions
If you try to install a binary like the Symfony/Console with composer req cli
, you might run into the following problem:
~ bin/console
-bash: bin/console: Permission denied
This is a known hiccup when using virtual machines, and can be easily fixed by either:
- running the console with
php bin/console
instead of running it directly, or - adding the “execute” permission to the file on the host machine (not from within the virtual machine), by executing:
chmod +x bin/console
. This will allow the direct execution ofbin/console
from within the VM then.
Adding Bundles
That “Hello” view we built is kind of naked. Let’s add some templates into the mix.
composer req template
We can use template
, twig
, templates
, or templating
here, as defined in the Twig recipe’s aliases.
The Symfony 4 / Flex approach will automatically activate this bundle for us and set up a folder (/templates
) with a base
layout view, as well as a configuration file (config/packages/twig.yaml
).
We are now free to define a view for our Hello route:
{% extends '../base.html.twig' %}
{% block body %}
{{ greeting }}
{% endblock %}
/templates/default/index.html.twig
Now we can modify the controller to return this instead of the plain text response:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function index()
{
return $this->render('default/index.html.twig', ['greeting' => 'hello']);
}
}
Notice how we had to extend the FrameworkBundle
‘s controller to get access to the render
method, but that was about all the added configuration we had to do. Our hello route is now way cooler.
Big Bundles
Now let’s try adding in a big bundle – one that includes several others. The admin
bundle for creating backends is a good option. Besides, it’s one the Symfony team decided to officially endorse, and it pulls in the orm
recipe, which refers to Doctrine – another Symfony recommendation (can you see the opinionatedness in action?)
composer req admin
We’ll need to create an entity before we can use the admin bundle. For that, we need a database. Create a new database and user. This process should be fine:
mysql -u homestead -psecret
create database flexy character set utf8mb4 collate utf8mb4_unicode_ci;
Feel free to create a database specific user too if you feel it’s necessary. Then, modify the .env
file to respect this:
DATABASE_URL="mysql://homestead:secret@127.0.0.1:3306/flexy?charset=utf8mb4&serverVersion=5.7"
Finally, let’s create an entity. Suppose we’re making a site that lets users make submissions to the site – like Reddit, links to submit for example. We’ll have an entity called “Submission”, like so:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Submission
* @package App\Entity
*
* @ORM\Entity
* @ORM\Table(name="submission")
*/
class Submission
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @ORM\Column(type="string", length=255)
*/
public $name;
/**
* @ORM\Column(type="string", length=255)
*/
public $url;
/**
* @ORM\Column(type="text")
*/
public $description;
}
The entity needs to be registered in the config/packages/easy_admin.yml
file:
easy_admin:
entities:
- App\Entity\Submission
Now we’ll have Doctrine create this table for us.
bin/console doctrine:schema:update --force
Note that you can also have Doctrine create the database as well if it doesn’t exist. Look into doctrine:database:create
for that functionality.
If we now visit the /admin
URL of our app, we should see something like this:
Adding submissions should now work like a charm:
Unofficial Bundles
What about bundles that aren’t officially backed by Symfony?
For that, we need to flip a Composer flag’s switch.
composer config extra.symfony.allow-contrib true
This will allow for pulling of recipes from this repository as well. Let’s say we want to make our submissions have uuid
for ID instead of a simple auto-incrementing integer. We can use Ramsey’s UUID-Doctrine bundle for that. When requesting contrib recipes, they typically don’t have aliases and have to be referenced in full, like regular packages.
composer req ramsey/uuid-doctrine
Since this is a community contributed package, Symfony will throw a warning at you once it’s done downloading it.
Note: The contrib repo is a great filter of dead bundles and packages – every bundle/package developer who cares about their work will have moved it there, so you can be sure that the development on the missing ones has stagnated.
Once the package has been installed, we can use it in our project.
First, we need to tell Doctrine that it’s now available (something the recipe should do by itself, in my opinion – not automated enough just yet!):
doctrine:
dbal:
url: '%env(DATABASE_URL)%'
types:
uuid: Ramsey\Uuid\Doctrine\UuidType
orm:
...
config/packages/doctrine.yaml
Next, we change the Submission entity to use this type on its id
attribute:
...
class Submission
{
/**
* @var \Ramsey\Uuid\Uuid
*
* @ORM\Id
* @ORM\Column(type="uuid", unique=true)
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
*/
public $id;
...
Now let’s update the database and clear current entities:
bin/console doctrine:schema:drop --force
bin/console doctrine:schema:update --force
Finally, let’s try re-visiting /admin
and adding a new entity.
Sure enough, our new entity has a UUID for a primary key.
Note: it is recommended to use another type when using UUID for primary keys in InnoDB type databases, but for the sake of brevity we used the default. Full instructions here.
Adding Third Party Tools
Other third party tools can be used just like before – only they won’t be auto-configurable by Flex. You’ll have to register them manually and remove them in the same way. It is therefore recommended you move any package that needs extra configuration to work smoothly with Symfony into the contrib
recipes repo, so that others may benefit from the smoother Flex workflow.
Conclusion
Symfony Flex is the modern way to install and manage Symfony apps, and it’s the red carpet towards the door of Symfony 4. Needless to say, we’re very excited about Symfony’s most recent foray into modern development and the field of high-DX, and we’ll be keeping a close eye on it. We hope you found this introduction useful!
We didn’t benchmark this final result with another framework purely because it makes no sense when you consider the possible optimizations you can do, but also because we’ve got a performance month coming up (all of November) during which we’ll devour all sorts of performance related issues and go through a whole set of techniques you’ll be able to apply to your projects – no matter the framework or app type. Stay tuned!
Frequently Asked Questions about Symfony Flex
What is the main purpose of Symfony Flex?
Symfony Flex is a modern replacement for the Symfony Installer, and not the replacement for the existing Symfony framework. It is a tool that manages Symfony recipes on your applications. It automates the most common tasks of Symfony applications, such as installing and removing bundles. It’s designed to simplify and accelerate the process of building a Symfony application, making it more efficient and user-friendly.
How does Symfony Flex differ from the Symfony framework?
While the Symfony framework is a full-stack web framework, Symfony Flex is a tool that helps in managing Symfony applications. It’s not a replacement for the Symfony framework, but rather a tool that enhances it. Flex makes it easier to install, configure, and manage Symfony applications, thus improving the overall development experience.
How do I install Symfony Flex?
Symfony Flex is installed by default when you create a new Symfony project. However, if you want to add it to an existing project, you can do so by running the command composer require symfony/flex
. This will install Flex and enable it automatically.
What are Symfony Flex recipes?
Symfony Flex recipes are a set of automated instructions that tell Flex how to install and configure Symfony bundles. They can be official recipes, contributed by the Symfony core team, or community recipes, contributed by the Symfony community. They make it easier to install and manage bundles in your Symfony applications.
How do I use Symfony Flex to manage bundles?
With Symfony Flex, managing bundles is as simple as running a command. To install a bundle, you would run composer require <bundle-name>
. To remove a bundle, you would run composer remove <bundle-name>
. Flex will automatically handle the installation, configuration, and removal of the bundle.
Can I use Symfony Flex with older versions of Symfony?
Symfony Flex is compatible with Symfony 3.3 and higher. However, it is most effective with Symfony 4 and higher, as these versions were designed with Flex in mind.
Can I contribute to Symfony Flex?
Yes, you can contribute to Symfony Flex. You can contribute by creating and sharing your own recipes, or by contributing to the Flex codebase on GitHub.
What are the benefits of using Symfony Flex?
Symfony Flex simplifies and accelerates the process of building Symfony applications. It automates common tasks, such as installing and configuring bundles, and makes it easier to manage your applications. It also encourages best practices and standardization, making your code more maintainable and scalable.
How does Symfony Flex handle environment variables?
Symfony Flex uses environment variables to manage application configuration. When you install a bundle, Flex will automatically update your environment variables with the necessary configuration. You can then manage these variables in your .env
file.
Can I use Symfony Flex without the recipes?
Yes, you can use Symfony Flex without the recipes. However, the recipes provide a lot of value by automating common tasks and encouraging best practices. Without the recipes, you would need to manually handle the installation and configuration of bundles.
Bruno is a blockchain developer and technical educator at the Web3 Foundation, the foundation that's building the next generation of the free people's internet. He runs two newsletters you should subscribe to if you're interested in Web3.0: Dot Leap covers ecosystem and tech development of Web3, and NFT Review covers the evolution of the non-fungible token (digital collectibles) ecosystem inside this emerging new web. His current passion project is RMRK.app, the most advanced NFT system in the world, which allows NFTs to own other NFTs, NFTs to react to emotion, NFTs to be governed democratically, and NFTs to be multiple things at once.