This Week In PHP Internals | July 8, 2026
Deprecations for PHP 8.6
This week's top story is still Gina P. Banyard's Deprecations for PHP 8.6 - the annual bundle where every removal gets its own ballot - and this week it caught fire twice.
First fire: the long-array question. With Seifeddine Gmati's list() deprecation already on the table, Tim Dรผsterhus floated a draft that turns array() into a real cast function - and Michael Morris erupted at where that road leads. He asked, "Are you crazy?" - deprecating array() would, by his math, touch 3 quarters of WordPress core and nearly every plugin.
Seif's counter was all receipts: the rewrite is one ast-grep command, array(...) and [...] compile to byte-identical opcodes - and, for the record, "The proposal is to deprecate list(), not array()."
Then Juliette Reinders Folmer - who maintains the WordPress Coding Standards - corrected everyone: WordPress still supports PHP 7.4, and short arrays were blocked there for years by a handful of core committers, not the community.
It got personal - Morris told Seif to step out of his ivory tower; Seif kept answering with engineering. He wrote: "I've written a compiler that migrated a multi-million-line codebase from one language to another, automatically, overnight. Swapping one AST node for another that is literally equivalent to the compiler is not a feat of engineering courage."
To Morris's credit, when told he was turning it personal, he replied: "I am, and I apologize." - and the thread cooled.
Then Monday it reignited - over evidence. Gina regrouped the list, folded in new items sent to her directly, and set the clock: "If none are added or amended, I will initiate a call to vote next week."
Rowan Tommins counted 35 proposals and only 8 with any discussion of who'd be affected, and threatened to cast 27 blanket no votes. Gina drew her line: "You are free to do as you please." - she won't produce metrics for the sake of metrics without an agreed method.
Rowan held firm: "I do not think we should be removing features without thinking about who will be affected. I'm honestly shocked that that's a controversial opinion".
Juliette, once again the bridge, renewed her offer to generate real impact data with PHPCompatibility - feasible, she says, for about 25 of the 36 items.
One item is on its way out: the by-reference-return-modifier deprecation - Bob Weinand recommended a complete retraction, and its proposer had already offered one.
The RFC freezes July 13 - expect the call to vote next week, though with the mandatory 14-day cooldown after Gina's latest changes, actual ballots open July 21 at the earliest.
Time\Duration Class
Tim Dรผsterhus and Derick Rethans' Time\Duration class - the stopwatch value object aimed at 8.6 - got called done this week: "we would consider the RFC to be complete".
The final decisions:
addandsubwon an informal PHP Foundation Slack poll unanimously- The past-tense method suffixes are gone
divideInto()got pushed to future scope- The ban on negative constructor arguments stays, on Derick's call
One naming question goes to the voters as a secondary vote: full names like multiplyBy and absolute, or abbreviations like mul and abs - with the abbreviations needing a 2-thirds supermajority.
But one fight would not close: fromSeconds(). It takes seconds plus a nanoseconds argument, capped at 999 million 999 thousand 999 - overflow is rejected, not carried.
Marc B. objected: "It makes it simple to reason about for you as implementing it - it forces the burden to the one using the API."
Pierre Joye brought prior art: Java and Rust both carry the overflow instead of rejecting it, and JavaScript's Temporal doesn't impose the cap either.
Tim's defense: an injective constructor means one value, one spelling - a form asking for seconds should reject out-of-range input the same way June 31 should be rejected, not silently become July 1.
Neither side budged - and with the RFC complete, that question rides along to the vote.
Function Autoloading
Function autoloading now has 2 competing designs, and they met in the same inbox on the same day.
Paul M. Jones updated his mark-5 RFC - that's attempt number 5 - adding a declare(strict_namespace=1) directive to kill the global-fallback edge case, plus research across the top 1000 Packagist packages: exactly 2 packages and 8 call sites would misbehave.
Meanwhile, Michael Morris - fresh off the deprecations thread - had floated an idea on July 2, saying: "An idea that popped into my head an hour ago, that I don't have another PHP Dev to talk to about, what if you could register a function that is called by PHP the first time it sees a namespace declared?"
Five days later that spitball was a formal draft: autoloader callbacks that take 2 arguments - the class and the namespace - firing the first time the engine meets a namespace. And within hours of Paul's update, Morris was in Paul's thread advertising his rival.
The reason the spitball grew legs is Rowan Tommins. His endorsement became the backbone of Morris's draft - he wrote: "This really nicely side-steps the global-vs-namespace sequence problem that function autoloading always runs into: by the time the engine reaches an unqualified name, the namespace loader has already run for the current namespace, and defined any functions it wants."
Not everyone's sold. Aleksander Machniak flagged that passing null to existing string-typed autoloaders is itself a BC break, and Alex Rock argued the draft bundles 2 different proposals and called it overkill. Morris's reply had some edge: "And you've misread the proposal entirely."
Typed Closures
The busiest brand-new thread: Matheus Martins revived typed closures - write Closure(int): bool as a parameter type, and a mismatched callback fails at the boundary with a clean TypeError instead of exploding deep inside your filter().
The reception was warm - Matthew Weier O'Phinney would find it "very useful", and Larry Garfield is in favor, to nobody's surprise.
Rob Landers suggested waiting for generics; Seif pointed out that would need variadic generics, which have never appeared in any proposal - waiting for generics means waiting indefinitely.
Larry was blunter: "Generics syntax is the wrong format to use for this, full stop."
The real villain is the lexer: inside Closure(int), that (int) is a cast token. Osama Aldemeery, who's been down this exact tunnel, put it memorably: "So the natural spelling is, unfortunately, the engine-hostile one."
Where it landed: inline signatures first, named type-aliases later, and neither blocks the other. Larry pre-empted the objection everyone could see coming - if someone gets fussy about long signatures, the answer should be "that's nice, go work on aliases then and don't block this RFC".
By Monday he'd added just one ask: invokable objects should fit through the same door, not get squeezed through closures.
Primary Constructors
Rob Landers' primary constructors - the constructor hoisted onto the class line - spent June fighting over whether it may carry a body. This week that fight hit its endgame, in a single day of posts.
Rowan Tommins came off the fence - with a body bolted on, he'd be a definite no. Rob, the author, declined to relitigate: "All I can say is that I reject it for future scope, repeatedly."
Nick Sdot stood down under protest, warning: "We don't need more half finished, half not working, confusing features in PHP."
And then, quietly, the week's one unreserved fan - a reader who wrote that extending third-party classes and calling the parent constructor by hand "always felt dirty". The thread's been silent since July 1.
Scalar Object Methods
Michal Kral's scalar object methods - (3)->pow(2), dispatched at compile time - came back for round 2, and the room steered it somewhere new.
Michal gave real ground: he'd restrict or drop the file-order-dependent form, and lean on typed locals for safety.
Seif stayed unmoved, arguing: "Seeing $s->trim() where $s is a string, I should know it works. A construct where identical AST dispatches or doesn't depending on file position, a redundant cast, or whether a declaration sits above or below the call is not something people can reason about."
Then Larry Garfield reframed the whole conversation: a small curated set of methods, he said, "is bikeshed bait, and needlessly limiting" - and counter-pitched Kotlin-style extension functions on any type, from a design he drafted with Sara Golemon.
Michal's response? Genuinely interested. They're talking off-list once Larry's back from vacation.
Ballot Results
To the scoreboard - one ballot closed, one never opened.
Jordi Kroon's third-party extension documentation RFC is in: 26 to 1, with 1 abstention. The secondaries settled too:
- The docs land on a
php.netsubpath rather than a new subdomain, 15 to 8 - The old user notes get dropped in the move, 21 to 4
Meanwhile the grapheme_mask vote that was announced for July 3? As far as we can tell, it never opened - the RFC page still says draft, and the feedback stayed kind but firm. Yuya Hamada wrote: "Thank you very much for your RFC. But move to voting phase is too fast."
The pipeline ahead is stacked: deprecations expects its call to vote next week, and Duration finishes its cooldown just in time for the mid-August freeze.
Quick Hits
July 2 was patch day: security releases for 8.2, 8.3, 8.4, and 8.5, and 8.6.0 alpha 1 is out for testing.
Eric Norris and Tim Dรผsterhus published the minimum-supported-versions RFC - newer autoconf, and MySQL 5.7.3 or MariaDB 10.2.4 for persistent connections - and an anonymous tester promptly found a real connection leak on old MySQL, declaring: "There is connection leak here!" - Eric's tracked down the cause and is weighing a fix.
Nicolas Grekas redesigned serializable closures and offered a slimmed-down fallback, nudging the list that 8.6 won't wait.
Osama Aldemeery floated a PREG_THROW_ON_ERROR flag - implementation already built.
And Nick Sdot posted a tiny RFC: default values on readonly properties, a 5-line removal - zero replies so far.
Still going. Literal scalar types turned into an enums-versus-literals standoff, where Nick warned: "We should not make PHP another TypeScript."
Ben Ramsey added a Foundation-SIGs section to Working Groups and wants feedback before he votes it - or withdraws it.
The DTLS experiment graduated to a working 1.2 branch; Jakub Zelenka wants a draft PR.
Pierre Joye synced bundled GD with libgd 2.4 and is untangling Windows dependencies.
Pratik Bhujel's terminal helpers got Derick's blessing - ship it via PIE, since PECL takes no new packages.
And Pratik also asked whether fixing sscanf's %c whitespace bug - in place since PHP 4.3.2 - breaks anyone on master.
So that's the week: a deprecations list that fought about WordPress and then about evidence, with the call to vote days away; a Duration RFC wrapped up and waiting out its cooldown; 2 rival answers to function autoloading colliding in real time; typed closures winning the room while the lexer holds the door; and the one ballot that closed, passing 26 to 1.
Links to every thread are below. We're Artisan Build. See you next week.
Comments
No comments yet. Start the discussion.