// composer.json
{
"require": {
"php": "^7.1.3",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/doctrine-bundle": "^1.6", // 1.8.1
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.2
"doctrine/doctrine-migrations-bundle": "^1.1", // v1.3.1
"doctrine/orm": "^2.5", // v2.7.2
"fzaninotto/faker": "^1.7", // v1.7.1
"knplabs/knp-markdown-bundle": "^1.4", // 1.6.0
"sensio/framework-extra-bundle": "^5.0", // v5.1.3
"stof/doctrine-extensions-bundle": "dev-master", // dev-master
"symfony/asset": "^4.0", // v4.0.1
"symfony/console": "^4.0", // v4.0.1
"symfony/flex": "^1.0", // v1.9.10
"symfony/form": "^4.0", // v4.0.1
"symfony/framework-bundle": "^4.0", // v4.0.1
"symfony/lts": "^4@dev", // dev-master
"symfony/maker-bundle": "^1.0", // v1.0.2
"symfony/monolog-bundle": "^3.1", // v3.1.2
"symfony/polyfill-apcu": "^1.0", // v1.6.0
"symfony/profiler-pack": "^1.0", // v1.0.3
"symfony/security-bundle": "^4.0", // v4.0.1
"symfony/security-csrf": "^4.0",
"symfony/swiftmailer-bundle": "^3.1", // v3.1.6
"symfony/translation": "^4.0", // v4.0.1
"symfony/twig-bundle": "^4.0", // v4.0.1
"symfony/validator": "^4.0", // v4.0.1
"symfony/web-server-bundle": "^4.0", // v4.0.1
"symfony/yaml": "^4.0" // v4.0.1
},
"require-dev": {
"symfony/dotenv": "^4.0", // v4.0.1
"symfony/phpunit-bridge": "^4.0", // v4.0.1
"doctrine/doctrine-fixtures-bundle": "^3.0" // 3.0.2
}
}
12 Comments
+1. Apparently we have to wait for a Symfony update https://stackoverflow.com/q...
Hey Trafficmanagertech ,
You're right, if you do not use doctrine/common directly in your project - just upgrade deps in the future and this error will be gone. Thanks for sharing the link btw!
Cheers!
Hello, I would like help or guidance with the following. I currently have the project with symfony 3.4 and I am in the process of migrating it to 4, it is a large project and I have almost eliminated all the deprecations but I have one last one left and I would like guidance on how to approach it. These are the last two deprecations that I have left:
User Deprecated: YAML mapping driver is deprecated and will be removed in Doctrine ORM 3.0, please migrate to annotation or XML driver.
User Deprecated: Creating Doctrine\ORM\Mapping\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0.
I would appreciate any help you can give me in this regard.
Hey @Ansise-S
I recommend you use Rector to upgrade your code, it may save you a bunch of time. About the Doctrine deprecation, you need to migrate your YAML config into something else, I recommend PHP attributes (Rector can do it for you)
About the other deprecation this SO post may give your some ideas of what to do: https://stackoverflow.com/questions/58975182/deprecation-doctrine-orm-mapping-underscorenamingstrategy-without-making-it-num
You can see Ryan using Rector to upgrade an application code https://symfonycasts.com/screencast/symfony6-upgrade/rector
By the way, if you're not planning to upgrade to Doctrine ORM 3 yet, you can ignore the first deprecation
Cheers!
Hey Abdelamine,
Do you use the Doctrine\Common\ClassLoader somewhere in your project? Probably not, I think it's just used somewhere internally. If so - you don't need to do any actions, you just need to wait for updates and upgrade your dependencies. But if you use doctrine/common - see the solution in the stackoverflow post linked by the_nuts.
Cheers!
When upgraded to 3.3 and made all my autowiring changes, I decided that having
$em = $this->getDoctrine()->getManager();
at the start of dozens of functions was tedious and, I thought, could be replaced by dependency injection like so:
public function foo(EntityManager $em, Request $request)
That worked great...until I upgraded to 3.4 and turned on container.autowiring.strict.mode. Now I get a big beautiful error message:
Controller "AppBundle\Controller\Tournaments\TournamentController::tournamentAction()" requires that you provide a value for the "$em" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
I know I could fix this by getting the entity manager from Doctrine with $em = $this->getDoctrine()->getManager(), but I don't really understand why it's a problem in the first place. Can you explain what's going on?
Hey Dan_M!
Great thinking to turn on container.autowiring.strict.mode. So yes, let's demystify what's going on here! It's a few things all at once:
1) Instead of EntityManager $em, use EntityManagerInterface. Each bundle decides which type-hints it wants to "support" for autowiring (in this case, it's DoctrineBundle), and the best-practice is to support interfaces, but not concrete classes (there are exceptions of course, including times when a service has no interface). The idea is to gently "nudge" you into typing against interfaces, not classes. This should fix everything :).
2) The second part - the big beautiful error - well... that's a different issue ;). What I mean is... this error may be big, but it ain't beautiful! When autowiring fails, you normally get a very clear error - something like "Cannot autowire argument $em. Please try using the type-hint EntityManagerInterface" instead. BUT, when autowiring fails for controller *arguments*, you do *not* see this nice message! This was a bug that we couldn't fix in time for Symfony 3.4 & 4.0. But, it HAS been fixed in Symfony 4.1. So, watch out for this - but in the future, you would have gotten a more clear error.
Cheers!
Thanks, Ryan!
I went back to Symfony 3.3 and looked at the deprecation messages, and there it was:
Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for "Doctrine\ORM\EntityManager" in "AppBundle\Controller\Teams\TeamsController" to one of its parents: interface "Doctrine\ORM\EntityManagerInterface", or interface "Doctrine\Common\Persistence\ObjectManager".
Now that's a beautiful error message!
Another question about autowiring: if I need a service only sometimes (if(some_condition) { $this->addFlash($this->get('translator')->...) } isn't it less efficient to always inject the translator with autowiring? Shouldn't I load it only when needed?
Hey Trafficmanagertech
Great question! I think you are right, but the performance boost would be for a few micro-seconds or less (depending on which processor you have). If you are on Symfony4 the Container comes very optimized (so you can autowire easily), and by default all your services are not public, so that's why is better to adopt the habit of injecting dependencies as arguments in your controller's action
If you have an use case where injecting a service is causing a bottle neck, then you may want to code another endpoint, so, that endpoint will always use what it requires.
Cheers!
Hello Ryan,
I have a couple of questions regarding autowiring:
1. how would you autowire an overridden setContainer() method that's part of ContainerAwareInterface? For example, I get the logger from the container there and use it throughout the class, instead of getting it in each action.
2. how do you autowire in methods that aren't actions? For example, in your REST API tutorials, you use methods serialize() and deserialize() in which you call $this->container->get('jms_serializer').
Thank you!
Hey Vlad,
1. Hm, if you do not want to inject services into actions - inject them into the constructor instead, i.e. just typehint LoggerInterface in the __construct() method of your controller and logger service will be injected into the entire controller.
2. The same answer, inject "jms_serializer"'s class into the constructor of your controller, then you'll be able to call it even in private methods.
Cheers!
"Houston: no signs of life"
Start the conversation!