DEV Community

Len Woodward
Len Woodward

Posted on • Originally published at youtu.be

This Week In PHP Internals | July 29, 2026

Hello world, from Laracon US 2026 in Boston — it's Wednesday, July 29, 2026, and here's what happened This Week in PHP Internals.

15 stories this week, so let's get into it. But first, This week's episode is brought to you by Tideways. When a request is slow and your logs won't say why, Tideways shows you where the time went — profiling, tracing, and monitoring built specifically for PHP. Slow request to root cause, in minutes. Setup takes 5 minutes, no credit card required. Start your free trial at tideways.com. And we have a second sponsor this week — Geocodio: address correction, geocoding, data enrichment, and distance calculations for North America and the UK. Built on Laravel since 2014. Try it free at geocod.io.

This week's top story: the mass deprecation vote for PHP 8.6 is open. Gina P. Banyard opened it Monday, and it's 35 separate ballots, each needing its own 2/3 majority — and each submitted individually, because as Gina reminded everyone, the wiki can only handle one vote at a time. Voting runs through August 10, and most of the 35 are passing easily — mysqli_get_charset() stands at 34 to nothing, and spl_classes() at 33 to nothing. But the headliners are moving the other way. list() — the construct Juliette Reinders Folmer's Packagist scan found over twelve thousand times — stands at 17 yes to 19 no, falling well below the required two-thirds threshold. The gettext _() alias is failing at 6 to 18. Reserving in, out, and inout is failing at 5 to 16, with 13 abstentions. And let sits at 17 to 10 — a majority, but still shy of 2/3.

The loudest argument is about one of the smallest items: the dechunk stream filter, which as of recording sits at 15 yes to 13 no — a coin-flip vote on a 2/3 question. On Monday, Matteo Beccati was the only no vote, and he explained why, warning: "I believe we should provide such an alternative together with the deprecation," rather than expecting projects with 200-million-plus installations — he names symfony/http-client — to write their own decoder in PHP. Jakub Zelenka agreed the item wasn't ready, saying it "should wait till it's properly investigated." Pierre Joye ran his own usage research and pushed back, noting: "Being present in a code base does not automatically mean it is used" — Symfony's native client disables the filter by default, and most stacks sit on curl anyway. Matteo then corrected the research: Symfony has shipped a pure-PHP alternative since release 8.2, which is exactly why Pierre's search pointed the wrong way. Jakub's objection sharpened from there, and he wrote: "This is exactly a half baked deprecation because we need to keep it for internal use anyway ... so this does not give us any code removal and we still need to maintain it. I don't understand why we need to rush it as there is no real reason for that." By Tuesday evening he'd also revealed a twist — he already fixed the select limitation on filtered streams in master, so that improvement lands in 8.6 no matter how this ballot goes. Kamil Tekiela, meanwhile, asked a different question — why deprecate define()'s dead case-insensitive flag at all, when just removing the parameter breaks nobody. So far, nobody has answered him.

Caleb White's pipe assignment operator, |>= — the compound form of the pipe, and his first RFC — went to ballot Tuesday morning, walked to the deadline with detailed coaching from Tim Düsterhus, whom Caleb thanked for "going to bat for this RFC". The machinery worked; the voters are split right down the middle — as of recording the count is 8 yes, 8 no, 3 abstaining, and it needs 2/3. Voting runs to August 11.

The queue from last week showed up on time. Nick Sdot opened voting on readonly property defaults Friday. It stands at 17 to nothing, with 5 abstentions — nobody's against it yet. That one closes August 7. And Khaled Alam opened voting Saturday on const object property writes — allowing writes to properties of objects referenced by constants. After a couple of quickly-fixed procedural stumbles, the count stands at 11 to 2, with 5 abstentions — above the 2/3 line. That one closes August 8.

Two carryover votes come off the board this week, and neither thread needed a single new email. The minimum-supported-versions vote for 8.6 closes Thursday. Requiring autoconf 2.71 stands at 27 to 2 — and notably, the no column shrank from 3 to 2 since last week. Requiring COM_RESET_CONNECTION stands at 26 to nothing. And the Time\Duration class closes Friday. The primary has stretched to 33 to 1, and full method names — multiplyBy, divideBy — lead the naming question 28 to 2. Barring a very strange 48 hours, PHP 8.6 gets a Duration class.

Seifeddine Gmati's literal scalar types made it to a ballot Thursday morning — for 18 minutes. At 5:26 UTC he opened the vote, 3 questions deep: integer and string literals, float literals, and strict-versus-coercive matching. At 5:44 he pulled it back down, writing: "I am retracting this vote: I opened it prematurely, in violation of the voting prerequisites in the Feature Proposals policy." No intent-to-vote 2 days ahead — and that morning's 1.0 update was a minor change, which starts a 7-day cooldown. He plans to reopen tomorrow, July 30 — a date that brushes right up against the freeze, so it may yet retarget 8.7. The self-retraction turned into a referendum on the process itself. Juris Evertovskis — a longtime reader and one-time RFC author who says he never felt "internal enough" to comment on the process — decided to comment on the process: "All the mandatory cooldowns, cooldown resets on minor changes, announcements to vote, cooldown resets on inactive discussions appears to me like bureaucratic hoops that people have to jump through. The process was hard and daunting enough before this." Bob Weinand agreed, noting he voted against the process RFC back then, and framed the trade plainly: "You sort of have to decide what you optimize for - easier for authors, or easier for commenters. But I think in this case it went way overboard in terms of strictness."

The gd 2.4 timing dispute from last week wound down to closing statements, and they were constructive ones. Pierre Joye's position: the late arrival was unavoidable — the libgd sync had to survive PHP's full CI matrix first — and he argued: "Process has to be humane ... If they are purely for the sake of having a process, we fail as a project and solve users' needs." Rowan Tommins made the case that this isn't red tape but triage: "There are maybe twenty sections describing details of the proposal, and the crude [reading-time] estimate in Firefox is 47-60 minutes. It may be clear in your head that most of this is uncontroversial, but for anyone else to even make that judgement requires investing a reasonable amount of time." Better, he says, to spend that time on 8.6 work now and this RFC after — though he left open whether the cut-off itself sits in the right place. One concrete footnote: Pierre added the procedural gd image functions to the deprecation path — on his telling, a warning from the gd extension itself in 8.7, and gone in PHP 9.

Derick Rethans hit a fresh regression on master: his Xdebug test suite started failing, and the trail led to the commit implementing the display-error-function-args RFC. Stream warnings from include, require, bzopen(), finfo_open() and friends no longer say which file couldn't be opened — the path was an argument, and arguments got scrubbed. Derick's verdict was blunt, arguing this "Doesn't seem to me like an enhanced for users" — either put the filename into the message text itself, or revert the change, RFC or not. Kamil Tekiela defended the new behavior, countering: "The file path could leak sensitive information". His suggestion runs the other direction — fold the path into all stream error messages deliberately, rather than leaking it by accident — and while he's at it, he'd rather streams stopped raising their own duplicate warnings entirely. With open_basedir in effect, one failed include currently earns you 3 warnings.

Edmond of the TrueAsync project turned last week's zero-reply pre-RFC into a real one: Concurrency Support in the PHP Engine. The pitch is deliberately minimal — give the engine a coroutine representation and make the scheduler pluggable by extensions. He was explicit about the shape of it, writing: "It adds no classes, no functions, no constants and no syntax: the engine compiles in no PHP symbols at all. With no scheduler registered, PHP behaves exactly as it does today." This is not True Async — it's the seam True Async would plug into, alongside anyone else. A scheduler can adopt fibers started by ReactPHP, Revolt, or AMPHP; there's per-coroutine storage that could someday make ob_start() coroutine-safe; and there is no parallelism — everything stays on one OS thread. The implementation already exists as a pull request. And this time he got a reply. Seifeddine Gmati expects the real discussion to wait until after 8.6 ships, but his early read was warm: "Overall, I really like this idea and approach. I think this is the right path forward." Edmond's answer: no rush.

Osama Aldemeery — who got his RFC karma in 2 minutes flat last week — shipped the RFC: PREG_THROW_ON_ERROR. Pass the flag to any preg_*() call and a PCRE failure throws a catchable PregException, instead of a warning plus a false or null you have to notice and then chase through preg_last_error(). It's the same pattern JSON_THROW_ON_ERROR already set, and it's strictly opt-in. He stressed the conservatism, writing: "A call does exactly the same thing with it or without it, byte for byte" — the flag only changes how the error is delivered. It targets the release after 8.6, and he's aware of Larry Garfield's request to hold non-8.6 business until September — his compromise is to let the thread tick over quietly rather than restart it. So far it has 0 replies.

Quick hits. The 8.6 release managers posted the 2-week warning: beta 1 lands Thursday, August 13, the soft freeze hits when the tag is created August 11, and every RFC vote targeting 8.6 must be closed before beta 1 — after that, merges need release-manager approval until the hard freeze at RC 1 on September 22. The CURLOPT_HTTPHEADER newline thread came back with a verdict from upstream: Sjoerd Langkemper relayed word from curl's own Daniel Stenberg that the docs already say headers "must not be CRLF-terminated" and libcurl may start rejecting the stragglers outright — there's a curl pull request in flight. Matteo Beccati's conclusion was to stand down, saying: "libcurl will eventually take care of it." And Steven Wilton's snmp extension work is back at the finish line — both reworked PRs updated per Gina P. Banyard's review, awaiting a final squash-and-merge check, with a third PR queued behind them.

The PEAR decay story found a new symptom: Juliette Reinders Folmer reports that individual bug pages on the PEAR site now error out claiming the original reporter "has not yet confirmed their email address" — which locks away exactly the archaeology she'd argued is worth preserving. And the typed-arrays thread got its epilogue: Larry Garfield explained why PHP probably won't get new base types for collections — the engine makes that "really really hard", which is the same reason enums became objects — shared his and Derick Rethans's old collections research notes, and set the course: wait for reified generics, then convene a working group. Holly Schilling's counter-offer was to skip the wait, pointing everyone at her self-published PHP 9 roadmap — generics, structs, modules, extensions, and surfaces — which she'd like the list to treat "as a rough outline for the future."

So that's the week: 42 ballots open at once — the 35 deprecations, with list() headed for defeat and dechunk splitting the room; pipe assignment dead even out of the gate; readonly defaults and const writes both comfortably clear; Duration and minimum versions closing within days, both far ahead; a literal-types vote that lasted 18 minutes and reopens tomorrow; and the soft freeze 2 weeks out. Links to every thread are below. Thanks again to Tideways.com and Geocod.io for supporting this week's episode. We're Artisan Build. See you next week.

Top comments (0)