This Week in PHP Internals | Sept 17, 2026

php dev.to

4 yes votes. 1 no vote. On Tuesday morning an RFC went to the ballot, and inside an hour its author closed the poll — while he was winning. Because of what the one no vote said.

Hello world, it's Thursday, September 17, 2026, and here's what happened This Week in PHP Internals. 10 stories this week, so let's get into it. But first,

Is AI working for your team? Anyone can count the lines it produced. Ballast counts the lines that survive. It reads your git history — never your code — and puts stable velocity next to a durability score between 300 and 850. It's free, and it updates monthly. Get it today at ballast.now.

Corrections (01:00)

1 correction from last week. Around the 6-minute mark I said "Tim Rethans". That's Derick Rethans — who has been Derick for the entire time I've been making this show. Larry Garfield caught it in the YouTube comments, with a smiley face and a good sense of humour. Thanks, Larry. In my defence, Tim Düsterhus is in every story every week, and apparently my mouth has decided that's just what people are called now.

Intl Vote (01:27)

This week's top story is a vote that was won 4 to 1 and closed anyway. Weilin Du opened voting on IntlRelativeDateTimeFormatter on Tuesday morning — ICU's "3 days ago" and "next Sunday" formatting for the intl extension. Within about 10 minutes Tim Düsterhus had voted no, and the closed poll reads 4 yes, 1 no. Tim's reasons were 2-fold. The RFC had changed after his review — Weilin had said the fix was planned, but no mail ever said it was made, so he never re-read it, and the intent to vote had expired. He wrote: "…there was also no email that changes were made to the RFC text (only that some were planned), which is why I didn't recheck the RFC before the vote - and the intent to vote expired." And he doesn't agree with untyped int constants where enums would do. Weilin called it a misunderstanding, treated it as a major change, and reverted the vote, writing: "There is no need to rush anyways :)" His case for constants is consistency — nothing else in intl uses enums. On Wednesday Tim sent the discussion thread a middle ground of 3 enums, for style, capitalization and unit, and no namespace, so IntlRelativeDateTimeFormatter::UNIT_DAY becomes IntlRelativeDateTimeFormatterUnit::Day. You get IDE autocompletion, documentable cases, and input checks the engine does for free, with RoundingMode as the precedent.

Array Str Contains (03:02)

The benchmark that was supposed to make the case for array_str_contains came back showing the C function slower than a foreach loop. Yuya Hamada ran the benchmark test shipped inside the pull request itself: with a match at the start of the array the native call took 578 milliseconds against 14 for userland, it lost in the middle and at the end too, and it only pulled level when nothing matched at all. Sepehr Mahmoudi disputed the run — the files didn't build for him — and on Sunday removed the benchmark tests from the proposal. Kamil Tekiela restated the bar a new standard-library function has to clear, writing: "In recent years, the consensus has been that we only add functions that provide behaviour which is either impossible or very difficult to emulate in userland, or so ubiquitous that it deserves a dedicated function." mickmackusa added that a faster C version is not, by itself, a reason to add anything to the array_ family. Larry Garfield said nobody is reviewing the benchmarks because nobody supports the function, and wrote: "It's OK to have a proposal rejected. Even very experienced long time contributors have ideas declined early on." As of Wednesday night the RFC is still on the wiki, and no vote is scheduled.

Preg Wrapping (04:19)

The PREG_THROW_ON_ERROR RFC now turns mostly on one question: when your own callback throws inside preg_replace_callback, does PHP wrap it or let it through? Tim Düsterhus, who wrote the throwables policy, wants it wrapped. The 3 others who spoke this week lean the other way. Casper Langemeijer said he isn't aware of any callback in PHP that is wrapped, autoloading included, and Sascha Ploss showed JavaScript and Python letting the callback's exception propagate, and says Java, C#, Rust and Ruby do too. He wrote: "PHP would be an outlier, if it started wrapping them inside PregException." Tim's line is that array_map exists to run your callback, but with preg_replace_callback, he wrote, "the high level operation is 'perform a replacement' and the provided callback is just an implementation detail." Osama Aldemeery, the RFC's author, went into the C and corrected himself twice. A callback throw does set preg_last_error — to PREG_INTERNAL_ERROR, because the bail-out path hands the match count to an error function that has no case for it. He wrote: "The engine matched fine, but the "Internal error" is a fallback the bail-out path leaves behind, not a diagnosis of anything PCRE did wrong." And the message-equals-preg_last_error_msg guarantee only holds for a single flagged call. Tim's Thursday mail adds one more piece: with the flag set, preg_last_error shouldn't be touched at all, as JSON_THROW_ON_ERROR already does, and then a single PregException, or PregError plus PregException, is enough. Osama says the policy call is Tim's. Tim hasn't made it yet.

PEAR Timeline (06:00)

The PEAR bug data that was thought gone last week has been recovered, and the end-of-endorsement RFC now has a timeline instead of a future-scope section. Nick S. made the edits on Monday: he struck the line saying attempts to reach PEAR's maintainers led nowhere, replaced it with a section on the new situation, and, coordinated with Derick Rethans, wrote an explicit timeline into the proposal. That is a major change, so discussion stays open until at least September 27. The better news is that Chuck went and recovered the missing bug pages, so the archive can be complete after all — Juliette Reinders Folmer's thanks went to both of them. Jakub Zelenka asked whether php-src should unbundle PEAR before the site goes static, since he thinks the Windows build still uses the installer; he plans to resume that pull request in October or November. Nick's answer, checked with Derick, is that the switch can flip first, as long as go-pear.phar and the rest URLs keep serving from the same domain. Either way the vote can't end before mid-October, and Nick doesn't expect anything to land before November. Related, Daniel Scherzer's pull request commits the PEAR installer phar into the repo instead of downloading it when a release is packaged, and targets 8.2.

Quick Hits (07:16)

Quick hits. The PHP 8.6 branch cut is next Tuesday, September 22, alongside the packaging of 8.6.0 RC1 — that's the hard feature freeze, after which master becomes 8.7. Beta 3 shipped last Thursday, RC1 is expected September 24, and 8.5.11 and 8.4.26 both have release candidates out. Matthieu Napoli got RFC karma for an --enable-cli-fpm build option that links FPM into the php binary — php --fpm runs FPM — because on Lambda, with Bref, a second 24-megabyte binary slows every cold start. Marc Henderkes wants it to be the default, not an opt-in nobody ships. On the opt-in JSON comments and trailing commas idea from August, Tim suggests a single JSON_ALLOW_JSONC flag that references the existing standard, which to me sounds like the correct approach, rather than 2 flags and a combinatorial explosion. Vilius Buividavičius wants MyClass::properties::name — a ::class-style constant for property names, so Doctrine field references stop being hardcoded strings — and Nick S. pointed him at an earlier thread on the same idea. Alwyn Bester published php-grammar, a source-backed EBNF grammar for PHP 8.5 audited against the parser, and is asking the list for review — reviving a 15-year-old thread that asked for an official EBNF for PHP. And David Maye Kitenge, moving an extension from Zephir output to hand-written C, asked whether making a zend_string static changes its refcount, and whether interned strings need freeing. Alexandru Pătrănescu answered that static is about the C variable, not the refcount; interned strings belong to Zend and OPcache, so never free them directly, intern the permanent ones in MINIT, and don't assume a string interned mid-request outlives the request.

TL;DR (09:17)

So that's the week. A vote won 4 to 1 and closed inside the hour, and the enum question it left behind now has a concrete proposal on the table. The array_str_contains benchmark came back slower than a loop, and the list said, in as many words, that it doesn't want the function. The regex RFC's callback question has 3 people this week against wrapping and the policy's author for it. PEAR's bug data is back, and nothing moves before November. And as of tonight the wiki's list of RFCs in voting is empty, a 5th straight week. Links below. The PHP Foundation funds more than half of ongoing php-src commits, so if you use the language, maybe consider donating at opencollective.com/phpfoundation — or try guilting your employer into it. Thanks again to Ballast.now for supporting this week's episode. We're Artisan Build. See you next week.

Source: dev.to

arrow_back Back to Tutorials