New in Symfony 4.2: Important deprecations

Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Symfony's Backward Compatibility Promise ensures smooth upgrades in your projects because it forbids backward compatibility breaks in minor releases. Instead of changing or removing existing features, we mark them as deprecated and change them in the next major Symfony version.
The UPGRADE-4.2.md document explains all deprecations in details and you'll see them too in the Web Debug Toolbar, the profiler and when running tests. This article summarizes the most important deprecations so you can start upgrading your Symfony 4 apps.
Deprecated a template directory
Contributed by
Yonel Ceruto
in #28891.
Storing the app templates in src/Resources/views/
is now deprecated. You
must store them in the directory defined in the twig.default_path
config
option in config/packages/twig.yaml
, which is templates/
by default.
Deprecated the Kernel name and the root dir
Contributed by
Fabien Potencier
in #28809 and
#28810.
The KernelInterface::getName()
method and the kernel.name
parameter have
been deprecated. There's no alternative to them because this is a concept that
no longer makes sense in Symfony applications.
If you need a distinctive ID for the kernel of the application, you can use the
KernelInterface::getContainerClass()
method and the kernel.container_class
parameter.
Similarly, the getRootDir()
method and the kernel.root_dir
parameter
have been deprecated too. The alternative is to use the getProjectdir()
and
kernel.project_dir
method introduced in Symfony 3.3:
1 2 3 4 5 6 7 8 9
# 'root_dir' is where the Kernel class is stored (src/ by default) and
# 'project_dir' is the main project directory
services:
_defaults:
bind:
# Before
$dataDir: '%kernel.root_dir%/../var/data/'
# After
$dataDir: '%kernel.project_dir%/var/data/'
Deprecated some console options
We've removed the original content of this blog post section because the related change was reverted before the Symfony 4.2 release. You can keep using both the console options and the environment variables:
1 2 3 4 5
# Using options to control the environment and the debug behavior
$ php bin/console command_name --env=test --no-debug
# Using env vars to control the environment and the debug behavior
$ APP_ENV=test APP_DEBUG=0 php bin/console command_name
Deprecated ContainerAwareCommand
Contributed by
Robin Chalas
in #28415.
The ContainerAwareCommand
class has been deprecated. It was used in the past
to create commands extending from it so they had direct access to the app
service container. The alternative is to extend commands from the Command
class and use proper service injection in the command constructor, as explained
in the main article about the Symfony Console.
TIP: use the make:command
utility provided by the MakerBundle to
generate commands quickly and following the Symfony recommendations.
Deprecated the base Controller
class
Contributed by
Samuel Roze
in #28243.
The base Controller
class is the optional class your controllers can extend
from to get access to some useful shortcut methods (such us $this->render()
).
This Controller
class has been deprecated in favor of AbstractController
.
The new AbstractController
base class has the same shortcuts but it's more
restrictive about services. You cannot use the $this->get()
shortcut to get
services. You must follow the modern practices of injecting services in your
controller constructor or in the controller action.
TIP: use the make:controller
utility provided by the MakerBundle to
generate controllers quickly and following the Symfony recommendations.
Deprecated process commands as strings
Contributed by
Nicolas Grekas
in #27821.
Passing commands as strings to the Process
class has been deprecated. The
alternative is to pass an array of the command parts (name, arguments, options):
1 2 3 4 5 6 7
use Symfony\Component\Process\Process;
// Before
$process = new Process('ls -l');
// After
$process = new Process(['ls', '-l']);
Deprecated tree builders without root nodes
Contributed by
Christian Flothmann
in #27476.
This deprecation won't affect directly to most developers because it's related to the configuration classes of dependency injection. However, you'll see lots of these deprecation messages because of the bundles used in your application.
Fixing this deprecation will be simple in most cases, so you may contribute a fix to your favorite third-party bundle:
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
// Before
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_root');
$rootNode->...()->...()->...();
// After
$treeBuilder = new TreeBuilder('acme_root');
$treeBuilder->getRootNode()->...()->...()->...();
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
This makes no sense to me. Now we need 3 commands (in Windows) instead of 1.
Let's move forward!
I get the environment variables for web requests, as with PHP-FPM / FastCGI you can easily set additional variables and there is no "isolated" command / cron job there, and no command line options. But with console commands, and shell commands in general, I don't think setting environment variables for overriding options is a use case anybody else is following, so this does not seem like best practices to me.
Doing it any of these ways means that you don't have to include debug or env overrides in your commands at all.
I personally don't see an issue with keeping the --env and --no-debug switches as options for those people who have a use case for them but I don't think I'd be affected at all if they're eventually removed.
I don't see the gains of removing this feature in sf5: maybe someone can explain the intention behind it?
But, most of the time, I only use the options when I'm running a command on production and I want --env=prod. But, on production, I will already have all of my configuration (including APP_ENV) stored as environment variables (either as real environment variables or the .env file). So, when I run "php bin/console", it will just use the proper environment that the rest of my app is using.
So, maybe it's not really a big deal? I think the focus should not be on the fact that you will need to set the env vars before calling the command. But rather, that your env vars will already be properly set, so you can just run the command with no variables.
Cheers!
As Ryan said, this is not a big deal in practice. You either have the ".env" file properly configured (both in local and remote machines) or you have the "APP_ENV" environment variable already defined in your remote machines.
You only need to deal with these env vars when you want to override the values set in ".env" or the "APP_ENV" vars, which is a very rare use case.
If you want to do things like cache:clear, cache:warmup or similar additional things in your application, it makes sense to always specify an environment, just to make sure you are not using an unknown default one. Because if by some chance somebody changes the environment variable suddenly all scripts could work differently.
Maybe this would also be something to ask the Symfony users in some kind of survey. I have noticed that Symfony has strongly been transformed to be simpler in its recommendations, like not using bundles, or in this case not using many environments and basically just having "one" production environment for an application. But this might not reflect how people are using Symfony.
Though, now that I think about it. I guess I shouldn't have been using the `--env` option. I'll have to implement a custom option/argument.
For example, when using Symfony with nginx if an application parameter contains a dollar sign then you are in trouble. Nginx provides no method of escaping a dollar sign in a fastcgi_param directive. You could just use dotenv in production, but that comes with a performance hit. And due to the nature of this issue you very likely won’t find out about that until you deploy your application to prod.
Environmental variables are handled differently in different shells and servers. Moving to them means going from a custom system that works the same everywhere to one that works differently depending on where it is. And the documentation doesn’t really mention of any of this - which makes sense. Environmental variables come with too many circumstantial escaping/quoting edge cases to try to document, and mostly they aren’t Symfony specific issues. But they are still things you might run into while using Symfony. It’s a nice little minefield for users to run into at some point.
deprecating the --env and the --no-debug is really a bad decision, it makes the use on windows much more complicated. this is really a very bad DX.
```
php bin/console --env=dev
Symfony 3.4.12 (kernel: src, env: dev, debug: true)
(fully working symfony console with no errors)
```
vs
```
APP_ENV=dev php bin\console
'APP_ENV' is not recognized as an internal or external command,
operable program or batch file.
```
vs
```
λ cmd /V /C "set APP_ENV=dev&& php bin\console"
[WARNING] Some commands could not be registered:
In EnvVarProcessor.php line 76:
Environment variable not found: "DATABASE_URL_LEGACY".
Symfony 3.4.12 (kernel: src, env: dev, debug: true)
---snip---
In EnvVarProcessor.php line 76:
Environment variable not found: "APP_SECRET".
```
also the handy autocomplete possibility with clink on windows and bash-completion on linux is gone with this change. environment variables are cool but not the holy grail for everything. there is a reason for having flags on commands. imagine you have to call all commands like this:
URL=http://example.com RECURSIVE=true OUTPUT_FILE=foo.html wget
please revert this.
\end of github PR comment
this is too much pain for no real gain. i often compare software to houses, for a house you have to decide if you want a flat roof OR a pitched roof but for software you can have both. why removing a handy feature?
And I'm worried about launch backgroud process now since the string constructor is deprecated. How are we suppose to launch such command now:
> new Process('nohup very-long-command &');
If you look at a modern hosting solution, the env approach is way easier and natural, when it comes to an older solution, the vhost env variables approach can be a solution (not for every project for sure).
If you really look at the configuration aspect, only Symfony > 3.4 support env variables so that's not linked to 99% of actual applications (which run mostly in < 3.4)
Then use different entry points. Create an environment-specific console and index.php files. It's really not that big of a deal.
>new Process(['sh', '-c', 'nohup very-long-command &'])