Ultimate Guide to Symfony Components (2021)
When you should use them in your projects, even if you’re not creating a complete Symfony project
Symfony components are pieces of the framework that you can install individually, and especially independently of the framework. Your project doesn’t need to be written in Symfony to use these components. They offer a lot of solutions that could meet your daily needs. Let’s have a look at these components and their use. Who knows, you might find here the solution to one of your problems that you’ve been holding for so long?
There are two ways to approach this guide. Either you want to have a quick overview of all the components offered by Symfony, or more like a dictionary. Just below this paragraph, you will find the list of components. You can look at the name of a component to see if it speaks to you or not and only look at this one!
Here are the components we’re going to cover in this article:
- Asset ;
- BrowserKit ;
- Cache ;
- Config ;
- Console ;
- Contracts ;
- CssSelector ;
- DependencyInjection ;
- DomCrawler ;
- DotEnv ;
- ErrorHandler ;
- EventDispatcher ;
- ExpressionLanguage ;
- Filesystem ;
- Finder ;
- Form ;
- HttpClient ;
- HttpFoundation ;
- HttpKernel ;
- Intl ;
- Ldap ;
- Lock ;
- Mailer ;
- Messenger ;
- Mime ;
- Notifier ;
- OptionsResolver ;
- PHPUnit Bridge ;
- PasswordHasher ;
- Process ;
- PropertyPath ;
- PropertyInfo ;
- RateLimiter ;
- Routing ;
- Runtime ;
- Security ;
- Semaphore ;
- Serializer ;
- Stopwatch ;
- String ;
- Twig ;
- Translation ;
- UID ;
- Validator ;
- VarDumper ;
- VarExporter ;
- WebLink ;
- Webpack Encore ;
- Workflow ;
- And finally, Yaml.
No code, only vulgarization. Let’s dive into it!
“Speed up your website loading time!”
There is a complete and clear documentation of HTTP cache management by browsers on the Mozilla technical documentation. What you just need to know is that this component can automatically add a unique hash to the names of your assets, which will allow them to be refreshed quickly when a user visits your site, and ensure that it is using the latest version of your front-end assets.
In addition, this component helps you manage the paths to your assets. Normally you would have to replace the entire path of the assets in all pages. This can be a huge source of bugs. By using this component and simply changing some basepaths in the component configuration, all paths will be updated throughout the application.
More at the Asset Component documentation
“Control a web browser programmatically to automate tasks!”
Without breaking our heads too much, we can draw two main interests in using this component: to create a robot to automate a task on any website, and to create end-to-end tests.
Since version 4.3 of the component, BrowserKit is able to be used on any site to click on links, retrieve the content of different pages, submit forms, etc. Everything that a web browser can do in itself.
Whatever your goal, you could link this component to a cron task so that a sequence of tasks is executed on a website regularly, and without your intervention. Used in conjunction with the CssSelector and DomCrawler components, we end up with something extremely powerful with a huge range of possibilities.
About end-to-end testing, with this component you are able to make sure that the website you are developing still works after your developments. When you develop your website, you use a browser to perform tasks such as logging in, clicking buttons, filling out forms, etc. By writing tests using this component, you are able to automate these tasks, running them in your CI. If your tests are good, you will be able to ensure that your developments are non-regressive.
More at the BrowserKit Component documentation
“Speed up your process time!”
What you need to know is that this component follows the guidelines of the PSR-6 standard. This means that this component is compatible with all interfaces that implement PSR-6 correctly. It is always easier when we all speak the same language.
This component offers a very simple key-value cache system. For a given key, you match a value. It also offers options allowing you to manage this in an optimal way, with the possibility for example to set up a timeout system. After a certain time, the key will be automatically considered as invalid.
The power of this component also comes from the adapters it embeds. These allow you to choose your caching technology, or in other words, where you want to store your cache. These adapters are numerous, we can quote in particular the Filesystem cache (files on the hard disk), APCu, Memcached and Redis to put the cache in RAM, or Doctrine to store your cache in a database. They’re coming out of the box and ready to be used instantly. You can also develop your own cache system, as long as it meets the PSR-6 standard.
More at the Cache Component documentation
“Properly configure your application with several files and formats!”
You may know that Symfony and Symfony applications can be configured with XML, YAML or PHP files.
This component will allow you to pool your configuration files, separate them into several files and folders, use several configuration formats according to your preferences and needs, etc.
This component is very simple, yet very powerful. If you have a complex configuration in your application and you need a tool to locate all configuration files and validate their values and contents, then put them in common in one place, this component is for you.
More at the Config Component documentation
“Enhance developer experience with beautiful and easy-to-use CLI: old school is the new school!”
Long gone are the days of monochrome and unattractive command line utilities.
With the Console component, you will be able to create command line interfaces using the power of today’s tools. In addition to giving you a robust solution for creating easily testable commands, this component provides you with a host of display and user interaction tools.
Whether it’s creating a progress bar, coloring your text, displaying structured data in tabular form with headers, or offering choices to the user with autocomplete and suggestions, this component will be your best friend when it comes to developing fun and easy-to-use tools for your project developers.
More at the Console Component documentation
“Ensure the compatibility of your code with third-party tools!”
This component is a little different from the others. The Contracts component “only” provides interfaces.
The interest of using these interfaces is to ensure that your code will be compatible with all implementations of them, whether they are Symfony components or other PHP projects using these contracts.
The main goal is the operability of your code, just like the implementations following the PSR-6 in the Cache component.
If your code works using these interfaces and you want to use a new implementation of those, you are assured that it will work without you having to change anything. This is where the naming of this component makes sense: if the contract is respected, then everything will work without a hitch.
More at the Contracts Component documentation
“Never bother with XPath syntax again!”
There is a second way to select elements in an XML file (and therefore HTML), it is the XPath syntax. Generally much less used partially because the first syntax is intensively used for front-end development, it can be quite confusing at first.
Although XPath syntax is more powerful, it is still very complex to understand and this power will not be truly useful most of the time. The vast majority of the problems you will encounter in your life as a developer can be solved with CSS Selector syntax.
Why use this CssSelector component? As we will see later, the DomCrawler component, which allows you to browse XML files, uses the XPath syntax. By installing the CssSelector component, you will be able to use the DomCrawler component with the CSS Selector syntax. This will save you a lot of headaches if your use case remains classical.
More at the CssSelector Component documentation
“Manage dependencies between your classes the clean way!”
The return of the standards! For your information, the dependency injection component follows the PSR-11 standard.
If your code is modular (I hope for your sake it is), you most likely have classes that depend on others. A service that depends on a class managing the database connection for example.
The small problem with this is that you need to create all the links in this dependency chain each time you need to use it.
In addition to “centralizing the way objects are instantiated”, as specified in the Symfony documentation, the dependency injection component takes care of solving each link of your dependency chain.
In concrete terms, this means that you just have to tell your service container that you want to use such and such a service, and the container will take care of creating all the necessary elements (dependencies) for your service to work properly without you having to worry about it.
As a bonus, you can describe all this in configuration files. Thanks to the Config component!
More at the DependencyInjection Component documentation
“Navigate and manipulate DOM elements smoothly!”
If you have the need to navigate through XML files, HTML pages and extract information from them, this component is for you.
Using the XPath syntax (or CSS selector syntax, I invite you to read the section about the CssSelector component if you haven’t done so!), you will be able to select any element of the DOM of your file very precisely.
From there, you can do just about anything you want: extract the attributes of an element, read its content, retrieve the neighboring nodes of a given node, its ancestors, its children, etc.
We can easily see two major interests in this component. The first one is the extraction of information. You could very well want to create a robot that fetches information from a public site, Reddit for example. The creation of a web scraper is extremely simplified with this component.
The second interest is… testing of course, again! Thanks to this component, you can very simply check the information and structure of an XML document generated by your application for example. Does your application offer an XML export system? You can write non-regression tests very easily with this tool.
“Access your infrastructure dependant variables with ease!”
In PHP we often need to access variables that depend on the environment we are in (that’s why they’re called environment variables, or “env vars”). It can be simply the address of the database for production or staging environment, or the SMTP server that will allow us to send emails. So, one of the best practices is to put these values in environment variables.
The DotEnv component answers this problem. Indeed, this component will search for a
.env file in your project. This file simply contains variable assignments in the form
KEY=VALUE. The component will then fill in these environment variables in your system, and you will have access to them in PHP with the classics
The interest of such a file is that each developer of the project can have a different configuration on his own machine: different IPs from another developer, ports already taken or not in its computer, etc. He will then simply have to put the right settings for him in this file when setting up the project. If the source code properly uses these environment variables, there will be no line of source code to modify.
More at Configuring Symfony
“Better debugging, less deprecations!”
Introduced in 4.4, ErrorHandler is the worthy successor of the now deprecated Debug component.
Like it, it is this component that takes care of making your exceptions pretty with clear messages such as “Attempted to load class “MyClass” from the global namespace. Did you forget a “use” statement?”. This component also takes care of retrieving exceptions that are not caught (and potentially display them on the Symfony error page).
In short, you will have understood that this component is very interesting for debugging. However, there is no documentation for it, and anyway, it is very unlikely that you will have to use it yourself.
More at the ErrorHandler Component announcement
“Make your application extensible and ready for its future features!”
This component implements both the Mediator and Observer design patterns. To make it simple:
- Mediator describes an object that manages the way several objects interact with each other ;
- Observer is a behavioral pattern. Its role is to maintain a list of third parties to be notified when a change in its state is noted.
We have just described the EventDispatcher through these two design-patterns. Its operation is simple: services, that we will call listeners, let the EventDispatcher know that they want to be notified if a certain event occurs. The EventDispatcher then stores a list of parties to be notified.
When the subscribed event occurs, the EventDispatcher will call each of the listeners, according to their order of registration or priority, if specified.
Thanks to this, you end up with a very scalable application. Let’s imagine that you dispatch an event (the EventDispatcher component allows you to dispatch events, and listeners are called depending on the event type), when a user is created on your application. You define several listeners that will each have a role: one to notify the administrators, one to send a confirmation email to the user, one to send an account activation email, etc.
If in the future, you need to add a step (a new email, a new person to notify when a registration is done for example), you will just have to add a new listener to the list of existing ones. You can even set its priority, if it matters.
By extending this event system to different places in your application, you will be able to plug in almost everywhere, and propose clean evolutions.
Many bundles in the Symfony ecosystem rely on this event mechanism. It’s extremely powerful, in the sense that you’re able to plug directly into the bundle code and adapt its behavior exactly to your needs.
More at the EventDispatcher Component documentation
“Evaluate expressions safely and on the go, without PHP!”
If you have already developed projects with the Symfony framework, you may have already used the ExpressionLanguage component, in some advanced situations.
Whether it is to evaluate security rules with the
@Security annotation, to perform advanced dependency injection or validation, we use this component more often than we think.
According to the documentation, this component can be used outside these specific cases to perform business validation. What’s so special about this? Expressions are simple strings, evaluated dynamically at runtime. You can therefore store these expressions in a database, making them customizable by the users of your site. You don’t need to know PHP to write expressions.
Your website administrators, perhaps far from knowing PHP or even computer programming, could submit expressions themselves according to their business needs, and you would just have to call the ExpressionLanguage engine to evaluate these expressions when needed. Think of it as giving your users the opportunity to add source code to your site in some way, but in a secure way. On top of that, this component can cache the expressions you use.
If you take it a step further, you could even offer a “no-code” user interface to your users, with some kind of blocks to link together (like IFTTT or Apple’s Shortcuts if you know them), creating an expression that can be interpreted by the ExpressionLanguage engine. Imagine the power of giving this kind of tool to curious users!
More at the ExpressionLanguage Component documentation
“Portable files management made easy and complete!”
This component is rather simple. It offers solutions to manage your files and folders stored on your file system.
Whether it’s file creation, renaming, managing user and group rights, deleting folders or reading symbolic links, all basic operations are available in this component.
Also, it will allow you to write portable code. This means that you won’t have to change a single line of code if you run your script on Windows or Linux. The component takes care of handling the differences between the platforms, including the handling of slashes and backslashes in the file paths. Basic, but very efficient!
More at the Filesystem Component documentation
“Never get lost in your filesystem again!”
Like the Filesystem component, this component is linked to the management of files and folders.
Where Filesystem allows you to manage them by creating, moving, copying and other operations, Finder will simply allow you to find them. Here is a non-exhaustive list of the possibilities offered in the search for files and folders:
- Include specific directories to search in ;
- Exclude directories to search in ;
- Use wildcards
- Ignore directories you have not the right to read into ;
- Find files by their content ;
- Search files in remote FTPs ;
- Sort search results by name, size, etc.
You’re also able to filter files easily by saying things like “only take files that are more than 100 KB in size, and their last modification date is yesterday between 9:00 and 10:00”.
In short, you can do just about anything with this component. So much so that if, for example, you need a very special filter or a very special sort, you can specify your own method of sorting results, which the component will use to give you the results in the order you want, no matter how twisted it is.
As a bonus, this component returns the results as an iterator. Perfect for performance.
More at the Finder Component documentation
“Manage forms, their validation, processing and testing with ease!”
Although it is in my humble opinion one of the most famous components of Symfony, there is not much to say about it. It does only one thing, but it does it well: the ability to manage HTML forms. It makes them reusable, easily testable and makes the processing clear.
There are dozens of different inputs, hundreds of options. Each type also has its own back-end validation rules.
This component speaks for itself, no need to add any. This component is very big, but very powerful and flexible. You can even customize how forms are rendered thanks to form themes.
If your project is not using Symfony but you want a clean management of forms in your application, installing this component in standalone will be an excellent choice.
More at the Form Component documentation
“One simple HTTP request should take one line of code!”
Personally, when I started PHP development, one of the things that struck me the most was the complexity of making a simple HTTP request with PHP code, with the help of cURL.
“Complexity”, I may be going a bit too far. But that said, having to make several procedural calls for that is a bit of a pain, and introduce a bit of legacy-style code.
The HttpClient component solves this. It exposes services that allow you to make these requests in about one line. Moreover, it allows you to manage the HTTP response with an object model, which makes it very pleasant to use.
This component offers a lot of features: cookie management, authentication, certificate, file upload, proxies, redirection, etc.
Whether you want to do functional tests or a web-scraper, this component will surely find a place in your projects!
More at the HttpClient Component documentation
“Manage requests and response the modern and object-oriented way!”
The HttpFoundation component does not offer you any particular functionality. What it does offer is to “replace” the classic $_GET, $_POST and others for an object model. In 2021, it is still more modern and pleasant to manipulate objects, interfaces and classes rather than associative arrays and procedural calls. Moreover, this model is used in several places in the framework, which offers a common base and thus a better code robustness, whether your project is based on Symfony or not.
As a bonus, this component offers you tools to manage HTTP headers (which have, as you know, a rather particular syntax) as well as a tool to anonymize IPv4 and IPv6 (pretty important now with privacy concerns).
More at the HttpFoundation Component documentation
“The very heart of Symfony framework… or yours!”
Let’s quote the official documentation of this component to introduce the subject:
The HttpKernel component provides a structured process for converting a
You understand now why I’m calling it the very heart of Symfony. In a simple case, everything begins by the HttpKernel analyzing and processing the request, and everything finishes with HttpKernel sending back the response.
It is cleverly written taking advantage of the EventDispatcher component. This makes it an ultra-flexible component, and you are able to plug in at just about any stage of the request lifecycle:
- Resolving and injecting arguments into controllers ;
- Intervention of an exception ;
- Just before the process handling the request terminates ;
- At the moment when the kernel resolves which controller to call according to the given route ;
- And more, available in the documentation.
Moreover, if you dream of writing your own web framework, you can very well use this component to facilitate the first step, which will probably be the processing of a request.
Again, by making heavy use of the event system, we end up with something very flexible, which is sure to meet your expectations.
More at the HttpKernel Component documentation
“Display information with the format your user is the most comfortable with!”
Intl for internationalization, one could think that this component allows us to manage the translations of an application. This is not the case (there is another component for that, Translation, that we’ll see later).
However, this component will still be very useful! It offers almost indispensable features for modern applications: management of locales, conversion of the alpha code of a country into the full name of the country (for example, fr becomes France), management of time zones and time difference calculations, management of currencies, etc.
This component is very useful when you use certain types of inputs from the Form component. Indeed, the country, language, locale, currency and time zone inputs all use the functionalities of the Intl component.
On a side-note, PHP 8.1 introduces the
IntlDatePatternGenerator which used with this component can truly ease your developpements regarding dates management! Learn more on this article I wrote about PHP 8.1.
More at the Intl Component documentation
“Manage your LDAP server right in your Symfony application!”
We will quickly go over this component.
You may know LDAP authentication. It is simply a user server using the protocol called LDAP. This protocol is widely used by companies around the world. Being very powerful and flexible, it allows you to define user hierarchies and advanced rights management in one shared place. This component simply offers you a ready-to-use solution to exchange with LDAP servers.
It is possible to log in with an LDAP server in a Symfony project, but this is not the role of this component. This component really focuses on managing LDAP users: creating, deleting, modifying, and retrieving their information.
More at the Ldap Component documentation
“Take control over shared resources across PHP processes!”
Mutual exclusion and locks are absolutely necessary when dealing with some sort of parallelism. They allow you to control resources access. You may (probably will?) be confronted with concerns about shared resources. When several PHP processes need to access the same resource (a file, a port, whatever), it may be necessary to control the accesses in order to avoid data loss for example, or to ensure everybody will have access to the resource at a moment.
That’s exactly what this component is for. It gives you tools that allow you to create and store locks in many places (shared or not): in memory, using Redis, using PostgreSQL, etc. To put it very simply, a lock is a blocking point (or not, but usually, it is) in your code. When PHP tries to acquire the lock, if it is already taken, then PHP will wait until the lock is released. This is a very powerful tool, but be careful how you use it, or you may have a catastrophic effect on performance (and be careful of deadlocks too!).
If you want to learn more and go deeper in this subject, I wrote an article especially about this component, with code examples.
More at the Lock Component documentation
“Send templated emails from your application, with the help of high availability and load-balancing mechanics!”
With this component, you will have a whole set of tools to help you send emails from your application. In addition to supporting the most popular mailing services such as Mailchimp, Gmail, Mailjet or Mailgun while giving us access to a common interface, some “bonus” features are welcome and really make life easier. Here are the 3 I selected:
- Load-balancing. You may have thousands of emails to send every day. To do so, it might be a good idea to separate the load of sending emails on several machines, or even several mailing services (also called “transports”). The load-balancing will tell Symfony to randomly select the transport to use to send an email. This way, your load is spread over several services and you can get something very efficient ;
- High availability. Symfony can simply select a different transport than the first one among those configured if this one is in error and doesn’t allow to send the mail immediately ;
- Integration with the Mime component. As we will see, the Mime component allows you to use an object model to create your mails. The Mailer component is able to use this object model. We end up with a very fluid creation and sending of mail for the developer, whether for simple mails or complex mails with headers, attachments, etc.
More at the Mailer Component documentation
“Chat and send messages to other applications!”
The purpose of this component is to allow you to easily communicate with other applications, APIs for example. But not only.
This component is based on a queue system, namely a “First In, First Out” data structure. Again, we have a very flexible system. The Messenger component is based on sending buses, envelopes, middleware, a sender and a receiver. So many places that you can customize to your liking and to best suit your needs.
This component also offers you a lot of options regarding the message delivery. Priority, retry policy, AMQP transport, TLS security, dispatched events to connect to any point in the sending process, etc.
I will not go into much detail because the subject is very complex and comprehensive. It would take a whole article to talk about this component, at least! Don’t hesitate to have a look at the official documentation, it is very complete, with many examples and diagrams explaining the precise functioning.
More at the Messenger Component documentation
“Take your emails content and metadata further!”
Obviously very used by the Mailer component, this component offers you a ready to use template for advanced email creation.
MIME for Multipurpose Internet Mail Extensions, brought about the existence of MIME file types, which you may know. The two have completely something to do with each other: the MIME Type (or Media Type) has been described in the Multipurpose Internet Mail Extensions RFC. This allows, among other things, email clients to distinguish between an attachment and the body of the mail.
This component offers you an object representation of an email. The MIME extension allows the support of non-textual attachments, the support of charset different from ASCII, the addition of email headers to specify for example the email format (like HTML, plain text, etc). Headers like in HTTP requests and responses if that speaks to you more.
This component also gives you some tools to work with MIME Types. In particular, there is a tool that allows you to switch from a file extension to a MIME Type, or vice versa.
More at the Mime Component Documentation
“Be alerted right in your favorite chat application!”
Like the Mailer component, the Notifier component offers you an abstraction layer. Only this time, it is for chat software. However, they are still quite similar. That is to say: there is a Mail transport in Notifier, and this one simply uses the Mailer component.
This component supports transports such as Discord, SMS, LinkedIn, Google Chat, Microsoft Teams, Slack, Telegram, and many more.
High availability and load balancing support are also included. If you haven’t already done so, I invite you to read the section of the Mailer component that details this.
You can even set the transport to use depending on the urgency of the message! For example, if your application is completely down, you might be interested in receiving the alert by SMS, so that it works even if your phone is not in an area with good mobile data coverage.
More at the Notifier Component documentation
“Quickly and properly validate options you’re passing through arrays!”
If in your code, you pass a lot of options to your methods through associative arrays, this component should interest you.
The OptionsResolver allows you to define a “format” in which your values must be in your associative array. The OptionsResolver makes sure that the required values are present, if the data format matches, if such option is an object of such type or such class, define optional options, is the value of such option contained in a defined set, etc. You can even use the Validator component to define your rules with the
createIsValidCallable method (see this)! It’s an array_replace on steroids.
You can of course define rules on nested options, if your array is deeper than one dimension.
More at the OptionsResolver Component documentation
“Push your unit tests to the next step!”
This is a kind of overlay to PHPUnit. The same tool, but with more features. Besides the possibility to run parallel tests with a disconcerting simplicity, other very interesting features are embedded. We can note the possibility to trigger deprecations and make sure that they are triggered. Speaking of deprecations, the PHPUnit Bridge can display the ones present in your code when you launch the test suite. There are also various tools and mocks for time-critical tests.
Finally, you can also find ready-to-use mocks for some native PHP methods concerning calls to third-party services. For example the mock of gethostbyname, which normally should make a network call to be executed. Network calls during tests are complicated to handle: the conditions are not always stable, the call can be long, and you add an external dependency to the success of your test. With the tools provided by the PHPUnit Bridge component, no more concerns about that.
More at the PHPUnit Bridge documentation
“Hash functions at your fingertips!”
The typical example of a simple but very useful component. Basically, you have two possibilities with this component: create a hash of a string, and check if a hash matches a given string. Of course you can choose the hash algorithm.
That’s all. It is simple. And that’s fine.
“Execute system commands and processes, and monitor them!”
This component allows you to launch any executable on the machine running this PHP script. What’s the point? Let’s say you use a tool to generate a PDF file. This external tool will need command line arguments. Thanks to the Process component, you will be able to launch this tool, wait for the end of its execution, its return code, retrieve information and error messages separately.
Keep in mind that launching executables on your server from PHP can be truly dangerous, especially if you let the user choose the string that will be sent to the Process component (even if you try to filter the string for any malicious content!). Use this with caution.
The Process component is even more advanced than that. Sending interrupt signals to processes (SIGINT, SIGKILL and alikes), retrieving the PID, searching for executables, streaming strings to standard input, and much more. The field of possibilities is absolutely enormous.
More at the Process Component documentation
“Access to objects and arrays internals with simple strings!”
The PropertyAccess allows writing and reading the properties of an object with a simple string. This component is able to automatically find the getters and setters of a property, but also to perform simple operations like converting the property name in the string from snake_case to camelCase if needed. I’ll be honest, at first I had a little trouble to understand the interest. Then I went to look in the Symfony source code to see the use cases. I found a very interesting use case! It’s about forms and the Form component.
As you may know, when creating forms with Symfony, each field is usually mapped to a property of our model object. To do so, we specify in the first argument of the FormBuilder
add method the name of the property to map, as a simple string. Well, that’s it! When transforming an array of data from the user request to the model object, the PropertyAccess component is used. It will use the name of the field to map that you have specified in a string to automatically update the value in the model object. Loop over each field of the form, and your object is filled.
More at the PropertyAccess Component documentation
“Extract all the little secrets of any object property!”
You can, thanks to this component, retrieve a bunch of information about the properties of your classes. The purpose of the PropertyInfo is to return the metadata of your properties. Among these meta-data, we can count:
- Annotations ;
- Type ;
- PHPDoc blocks ;
- Is the value nullable ;
- For collections: keys type and values type ;
- Is the value readable (does it have a getter, isser, hasser?) ;
- Is the value writable (does it have a setter?) ;
And many more. Think of this component if you want to create a tool that directly interacts with some PHP source code!
More at the PropertyInfo Component documentation
“Take control over calls made to your website!”
A rate limiter is simply a mechanism that allows you to limit the number of calls that can be make in a given time. This mechanism is often used for several reasons:
- Limit a user to performing a heavy operation too often ;
- Prevent attacks such as brute force by limiting for example 1 login attempt per second per user ;
- Create an API with 10000 free calls, then charge for the next ones.
You can choose what to base this limitation on: by username? By email? By IP? The choice is up to you as this component is, again, flexible! Also, this component allows you to get the limiter state. This way, you can send everything back to the user, so he knows when to make requests again.
More at the RateLimiter Component documentation
“It’s not just about pretty URLs and SEO!”
We are back to one of the most famous components! It is thanks to him that you routes are nice like “/account/me” rather than “/account_me.php” for example.
Of course, this component allows you to do much more than just route matching for the front controller. Check predicates on the route such as the HTTP verb used and the browser sending the request (thanks to the ExpressionLanguage component!), validate the parameters of a route, manage localized routes, etc.
Used in conjunction with expressions, from the ExpressionLanguage component again, makes it an extremely powerful and flexible tool for your most particular needs.
More at the Routing Component documentation
“A code that works everywhere!”
As the use of this component is extremely advanced, we won’t go into details.
Your PHP code is interpreted by runtimes (or execution environment) like PHP-FPM, Swoole and others. This component makes sure that your front controller will be the same no matter what runtime you choose and that you don’t have to make any code changes.
This component is still in the experimental stage. There is very little chance that you will have to manipulate it directly.
More at the Runtime Component documentation
“Setup simple or advanced access control to your application!”
This is a huge component, perhaps the most critical.
The Security component offers you a ready-to-use solution to manage your application’s login forms, as well as authentication by X.509 certificate or HTTP Basic. It is precisely this component that is able to grant or deny access to a part of a site to a user according to the rights he has.
Whether it is a simple application with two or three roles, or a very complex industrial application with hundreds of roles and inheritance between roles, this component can literally do it all. A Voters system is implemented to help you. Voters are classes that can decide, depending on a user, his rights and the type of resources, whether he can apply a specific operation, whether it is consultation, deletion or modification. This allows you to manage user rights very finely.
It is also this component that allows the use of CSRF tokens in forms to counter XSS attacks, or to manage the “Remember me” functionality when logging in.
You can also create your own authentication methods thanks to the flexibility (but robust!) of this component, and develop for example an authentication solution by API key.
More at the Security Component documentation
“Manage access to shared resources!”
For this component, I refer you directly to the section about the Lock component. The thing you need to know is that the difference between a semaphore and a Lock is that the semaphore allows the acquisition of it by several processes at the same time, while the Lock does not.
More at the Semaphore Component documentation
“A simple and powerful way to convert objects to specified format… and back!”
Thanks to the Serializer component, you are able to convert your object to JSON or even XML. What’s cool is that the reverse operation is also possible!
Of course, this component is used a lot when developing APIs. Most of the time, these return a response in JSON or XML. So you have a ready-to-use way to retrieve your entities from the database and return them in these popular formats. These tools to transform your data into these formats are called Encoders. There are several of them like JSON, XML, YAML or CSV. You can of course create yours.
So the Serializer component is based on three parts: Normalizers, Encoders and a Serializer.
The role of the Normalizer is to transform your object, whatever its type, into an associative array of data. Once this is done, an Encoder is used to format this array into a specific format. Finally, the Serializer, encompasses all of this. When you pass an object to the Serializer, it will call a Normalizer and then an Encoder. This component already offers a lot of ready-to-use Normalizers.
Finally, you can even use serialization groups, to automatically retrieve only the data you need in a given context.
More at the Serializer Component documentation
“No more use of microtime()!”
This component lives up to its name. It offers you a stopwatch. Well, when you say it like that, it’s true that it doesn’t make you dream.
But it’s actually a rather special stopwatch. It allows you to follow the memory consumption of your PHP process. You can create several timers by naming them. Very useful when you want to have information to profile your code!
More at the Stopwatch Component documentation
“That’s how we should manipulate strings in the 3rd millennium!”
This component offers an object approach to string management.
Thanks to the String component, the management of UTF-8 strings and complex characters such as Asian characters is greatly improved. Moreover, you have a lot of tools to manipulate strings whatever they are. There are text search functions, truncate functions, integration of the old Inflector component and more.
The principle of Inflector is to provide you with the correct singular and plural of certain exceptions. For example, “woman” in plural is not “womans” but “women”. The reverse operation is also possible, by singularizing a word. For instance, “data” becomes “datum” and “radius” becomes “radii”. This allows the automation of certain tasks. Doctrine for example, when it manages collections, to add or remove elements from it, will look if it has methods starting with “add” or “remove” followed by the name of the property in singular. That’s the all point of Inflector!
But for me, the killer-feature of the component is the integration of a Slugger. This tool allows you to convert strings like “My super Slugger” to “my-super-slugger”. Perfect for URLs and SEO!
More at the String Component documentation
“Easy and clean integration with Twig!”
Twig is a bit of an inception. When you think about it, PHP is basically a templating language to generate HTML. So we end up with a template language rendered by a template language. Rendering templates with PHP is deprecated by Symfony since version 5.0.
That said, let’s go to the component. Quite simply, this one proposes the templating language Twig and all the tools to fully use it. Together with the Asset component (and Webpack Encore component if you wish), you end up with a perfect combo to render your front-end.
But Twig is not limited to the frontend. Twig can render any type of file. Do you want to export XML, CSV, just text or PDF? Even if for some of these formats it is not the most suitable, there is nothing to stop you from doing it. You can use Twig from anywhere where you basically have to render content into a file. There are even third party libraries to add custom tags to Twig for rendering Excel. Once you’ve had a taste of it, it’s hard to go back. Even if more and more front-end frameworks like React or Vue.js are becoming popular, Twig will always have a place for this kind of cases.
Thanks to this component and the power of Twig, you will be able to cleanly organize your templates into different pieces and reusable fragments, even for the most complex applications.
More at the Twig Component documentation
“Everyone deserves to use the Internet in their native language!”
Not to be confused with the Intl component which does not have the same role, the Translation component helps you manage the translation of your website.
This component is compatible with several translation file formats such as YAML, CSV, JSON, Qt or XLIFF (the latter offering the most features but being admittedly much more verbose).
Some of the features include the pluralization of your translations, variable parameters in the translated strings and full compatibility with Twig.
Even better, since version 5.3, the component integrates the possibility to plug with an external translation provider. In international companies, it is not uncommon to hire an external company to take care of translations in all the languages supported by the application in question (I may be wrong, but I doubt that Apple’s developers take care of iOS translation themselves…). So this component offers the automated sending of translations to the translators in charge, but also the retrieval and merge of translations in the project without you really having to worry about anything. If you are interested, you will find all the information in this section of the documentation.
More at the Translations Component documentation
“Ensure your identifiers are unique in the galaxy!”
UIDs, for Unique Identifier, are strings that are globally unique when generated by their algorithm.
You will often find the notation UUID, for Universally Unique Identifiers, which is a UID standard. This one comes in several versions. The difference between each of these versions is the way the UID is generated.
Let’s take the example of the UUID Version 1, which is generated from the current date and time, as well as the MAC address of the machine. If you didn’t know, a MAC address is unique in the world. Every network device has its own and is unique when manufactured (which is also why it can be dangerous to share yours). The documentation of the component will explain you how are generated other versions of UUIDs.
The component also allows you to generate ULIDs, for Universally Unique Lexicographically Sortable Identifier.
UIDs are widely used. You could for example use them to identify a database resource rather than a simple integer, and incorporate this UID in your URLs that have a slug for example. This way, your SEO is optimized, and you ensure the uniqueness of your URL (because your slug is most likely not unique).
“Be sure of the data you receive from your users!”
The component is capable of validating dates, checking that a string matches credit card number algorithms, emails, that a field is not null or empty and many other checks. This ranges from simple checks like the length of a string to checking a set of rules on collections or nested objects.
You are also able to use validation groups, which allow you to validate a specific set of rules according to your context.
There are far too many ready-made validation rules to detail here. The complete list is available in the documentation. Of course and once again, you can create your own custom ones!
Never use a user’s data without validating it in the back-end in some way!
More at the Validation Component documentation
“Get a beautiful insight of what’s going on in your variables!”
Whatever your level in PHP, you’re likely to use the native var_dump function from time to time. As we know, this method returns a complete textual representation of the content of a variable, an object, an array, etc. The problem is that the text is raw and not formatted (unless you have installed Xdebug, in which case there is indentation and a little bit of color). You could very well use a tool like vardumpformatter.io, or use the VarDumper component of Symfony.
Indeed, instead of displaying plain text, the VarDumper component will display the entire content of your variables with syntax highlighting, but also collapsed sections. This way, even if your object or table contains others on several levels of depth, you’ll be able to easily navigate through it.
An integration with Twig is available, as well as the possibility to launch a dump server. The interest is not to interfere with other data. In fact, when you use this component, the HTML output of VarDumper will be displayed in your browser with the rest. Having this server allows to send the dump output in a separate place and not to mix the real data with the VarDumper one.
More at the VarDumper Component documentation
“Export your data structures to PHP code!”
This component allows you to export variables (objects, arrays, scalar types, etc) in PHP code. You can then call “require” on this PHP file to instantiate your variable again later, when you need it.
This component is used in several places in the Symfony framework, such as in secrets management. If you want all these details, I invite you to read the article I wrote about it.
But to make it simple, it is possible to add sensitive environment variables to Symfony projects. A list of these variables is kept in a PHP file in the project configuration folder, which returns an array. When a secret is added or removed thanks to the Symfony commands provided for this purpose, the array is retrieved, the change in the list is made and the VarExporter is used to generate the new file containing the array of available secrets.
More at the VarExporter Component documentation
“Tell user’s browser how to efficiently load your application!”
Rather unknown, this component offers you beautiful optimizations of the loadings of your pages with HTTP 2. This component takes advantage of the features of the version 2 of the protocol.
For example, you can indicate to your application that CSS is to be sent, before the browser requests it. This results in more optimal page loads. It is also possible to prioritize your assets, if for example you absolutely need one to be loaded as quickly as possible.
It is also possible to tell the browser on which DNS domain particular resources will be located. It will then be able to resolve the IP of the domain in parallel with the loading of the other elements for a faster loading of the resource.
More at the WebLink Component documentation
“Time to be friend with front-end developers!”
Webpack takes care of managing your asset versions (so that there are no caching problems on the browser side in particular!), but it can also minify your assets and obfuscate them.
Finally, with the integration to Twig, you will not have to worry about the path of your assets in your files using them.
So if you want to manage assets or simply install a front-end framework, Webpack will be the perfect tool. Moreover, it integrates perfectly with Symfony projects.
More at the Webpack Encore Component documentation
“Avoid invalid and inconsistent states of your application!”
You will be able to create state machines and workflows. Behind this barbaric name lies a rather simple principle.
Imagine a blog post represented by an entity. It can be in 3 different states: draft, in review, published. A state machine simply describes the transitions between each state. For example, a draft article cannot be published without being reviewed. Similarly, a published article cannot return to the draft state.
This is exactly what Workflow is for: to keep track of the state of an entity, and to make sure that its state change is allowed and respects all conditions.
These conditions can be customized thanks to the fact that the component uses the EventDispatcher (if you don’t know what it is, I invite you to read the section dedicated to the EventDispatcher component), which allows us to write code at the moment when a state change is requested, and to block the transition if needed. Obviously, the first condition to respect is that this change of state to another is possible, and that it is not an invalid transition (to take the example, going from published to draft is a invalid transition).
You can create workflows as complex as you want, with as many states and transitions as you need. It is also possible to create workflows with simultaneous states. But then it starts to get a lot more complex all of a sudden. All this to say that this component fits all needs, even the most complicated ones.
More at the Workflow Component documentation
“Using YAML files has never been easier!”
The Yaml file format (for Yet Another Markup Language) is today ultra-popular because of its flexibility and simplistic notation. It is multi-purpose. In Symfony alone, it can be used to configure everything, for translations, for mapping Doctrine entities… In short, very practical!
The Yaml component is intensively used in the core of the Symfony framework source code. This component simply offers to read Yaml and retrieve it in PHP to manipulate it easily, or to write the content of a data structure in a Yaml file.
There are many options available for the parse of a file. You can tell the parser to interpret the dates and convert them to DateTime or to see them as simple strings. You can also tell it to throw an exception if an error in the Yaml is detected. As a bonus, you can even ask to detect the special tag “!php/const” so that the parser interprets it as a PHP constant, and thus directly return its value when parsing the file.
More at the Yaml Component documentation
That’s it, we’re done! That’s a lot of knowledge. Chances are you didn’t read this article in one sitting, and that’s okay. As said in the introduction, you should see this as a dictionary rather than a tutorial to follow from A to Z.
Symfony components are great tools for any PHP project. Don’t hesitate to use them, they could make your life much easier!
Big thanks to @stof for the review!