PHP 8.5 came out yesterday. Symfony 7.4 LTS and 8.0 land at the end of the month, same as every year. November is upgrade month now. First the cargo, then the timetable.

From 8.5 I care about three things. The pipe operator makes transformation chains read left to right:

$slug = $title
    |> trim(...)
    |> strtolower(...)
    |> (fn ($s) => preg_replace('/\s+/', '-', $s));

The new URI extension puts standards-correct URL parsing in core. parse_url had opinions instead of a specification, I will not miss it. And #[\NoDiscard] lets a method declare that ignoring its return value is a bug. Made for result-style APIs, where a dropped return is a swallowed error.

On the Symfony side, the usual two steps. Go to 7.4 now: it is the LTS and it runs the same code. Turn on deprecation logging, clean the list. Then 8.0 is the same framework with the dead weight removed. Teams that treat x.0 as a separate mountain have usually skipped the deprecation homework.

Now the timetable. Twelve years ago upgrades were events. Unplanned, feared, postponed until something forced them. Today PHP releases every November, Symfony minors land every May and November, LTS boundaries are published years ahead. Infrastructure with a schedule. It goes into the engineering calendar like a fire drill: one compatibility window a year, a few days of work.

The teams in trouble are not the ones on old versions. They are the ones with no rhythm. A yearly upgrade costs days. A five-year jump costs a quarter, and the same people sign both budgets.

We skipped last November on one project. Too busy, I said. I signed that one.