Symfony 4: the framework as recipes

A kernel, an index.php, a config folder with almost nothing in it. That is a Symfony 4 project on day one, and 4.0 came out today together with 3.4 LTS. The code changes are the smaller story. How a project starts is the bigger one. The Standard Edition is gone. You start from the empty skeleton and ask for what you need. composer require orm pulls Doctrine, and the recipe writes the config files, registers the bundle in bundles.php, adds the variables to .env. You watch your own repo grow file by file as you add dependencies. ...

November 30, 2017 · 2 min · Murat Useinov

Private services: the container steps back

$container->get('app.mailer') stopped working this week. Symfony 3.3 is out, and in the new configuration services are private by default. The container refuses the call. Everyone is writing about autowiring. This is the change I like more. That call was always a smell. A class that pulls dependencies from the container by string id is a class with secrets. Its constructor says nothing, and to test it you boot half the framework, because it may ask for anything at any moment. ...

May 30, 2017 · 2 min · Murat Useinov

Autowiring is coming to Symfony 3.3

Our services file repeats every class name three times. Once as the id, once as the class, and again in the arguments of every service that needs it. Add a constructor parameter, edit YAML, clear cache, repeat. Symfony 3.3 lands in May and promises to delete most of that file: services: _defaults: autowire: true autoconfigure: true AppBundle\: resource: '../../src/AppBundle/*' Autowiring and autoconfiguration on by default, the whole source folder registered in five lines. I have mixed feelings. Sorted, they look like this. ...

March 8, 2017 · 2 min · Murat Useinov

Order status is a graph

if ($order->status == 'paid') in the shipping module. Another one in the refund module. A slightly different one in the admin panel. Then someone cancels a shipped order from an admin button, because the button just writes the string, and the warehouse learns about it a week later. Symfony 3.2 is out this week and ships a Workflow component. Finally a framework says out loud what every order table has been whispering for years: status is a state machine, not a string column you assign wherever convenient. ...

November 30, 2016 · 2 min · Murat Useinov

Symfony by the piece

A folder of cron scripts, each one a .php file with hand-parsed $argv. That is what CLI looked like on our legacy Kohana application until last month. One line fixed it: composer require symfony/console Now each script is a small Command class with named options, --help for free, and exit codes that cron can actually check. The framework around it did not notice anything. Console does not care who serves your HTTP. ...

May 10, 2016 · 2 min · Murat Useinov

Symfony 3.0 is not a rewrite

Symfony 2.8 and 3.0, released today, both at once, on purpose. The pairing is the whole message. 2.8 is the last of the 2.x line and an LTS. 3.0 is roughly 2.8 with the deprecated code deleted. Same features, cleaner body. This turns a scary major upgrade into two steps. Step one, move to 2.8. Minor upgrade, low risk. Then make the deprecation log empty. The phpunit bridge prints every deprecated call your code and tests touch. Burn the list down during normal sprints, item by item, each fix small and releasable on its own. ...

November 30, 2015 · 2 min · Murat Useinov

Symfony 2.7: LTS is the feature

Three years of bug fixes. Four years of security fixes. Symfony 2.7 came out this weekend, and that is the line from the announcement I care about. The changelog has new things in it, but the important word is on the label: LTS. For a pet project this is boring. For a product with paying users and a team, this is the actual feature. A big application does not upgrade for fun. Every framework upgrade is testing time, regression risk, and a sprint that produces nothing visible. Business asks a fair question: what do we get. “Newer version” is not an answer. “We keep receiving security fixes until 2018 without touching anything” is. ...

May 31, 2015 · 2 min · Murat Useinov

Symfony 2.6: dump() and boring upgrades

dump() instead of var_dump(). Symfony 2.6 came out at the end of November, and this is the visible gift: VarDumper. Collapsible output, clickable class names, works inside the toolbar. A small thing, used fifty times a day. Tools like this improve life more than big features do. But the important story in 2.6 is not a feature. The release notes read like a preparation checklist for Symfony 3: deprecations, everywhere. ...

December 18, 2014 · 2 min · Murat Useinov

Symfony best practices: defaults, not laws

One AppBundle. That is the line in the official Symfony Best Practices book I read twice. For years the answer to “how many bundles” was “as many as you have features”, and here the framework’s own book says: one. The book came out this autumn. Worth reading even if you are not on Symfony, because the interesting part is the change of tone. The old Symfony way: everything is a bundle. Your application is bundles, reusable, configurable, with their own extensions and semantic configuration. Very flexible. And for a normal business application, mostly ceremony. You write a configuration class for code that will never leave this one project. I wrote such classes. Three of them. None was ever reused. ...

December 14, 2014 · 2 min · Murat Useinov

Services instead of fat controllers

120 lines in one action. Order confirmation: load the order, charge the card, send the email, render the page. It ran fine for a year. Then a console script needed the same operation, and the action turned out to be glued to SMTP, to the database and to the HTTP request. All at once. Symfony people talk about dependency injection so much it sounds like religion. It is one simple idea: a class receives its dependencies and does not create them. ...

December 2, 2014 · 2 min · Murat Useinov