<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Len Woodward</title>
    <description>The latest articles on DEV Community by Len Woodward (@projektgopher).</description>
    <link>https://dev.to/projektgopher</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1383734%2Ff5ede504-5ae0-422b-8d13-69b3bfd2a1a1.jpeg</url>
      <title>DEV Community: Len Woodward</title>
      <link>https://dev.to/projektgopher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/projektgopher"/>
    <language>en</language>
    <item>
      <title>This Week in PHP Internals | Oct 1, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Fri, 02 Oct 2026 00:27:01 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-oct-1-2026-1f24</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-oct-1-2026-1f24</guid>
      <description>&lt;p&gt;Pick a password longer than 72 bytes for a PHP app on the default hash. PHP keeps the first 72 and throws the rest away, without a word. Then it lets you log in with only part of it. This week someone proposed that PHP refuse instead, and the list can't agree it's worth the break.&lt;/p&gt;

&lt;p&gt;Hello world, it's Thursday, October 1, 2026, and here's what happened This Week in PHP Internals. 14 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I think we can all agree that the number of small, paid subscription services we're all being bombarded with is getting a little bit out of hand. And this is what Scalpels aims to solve. It's a collection of professionally built, open source alternatives to the parts you actually use of things like Private Packagist, Mailtrap and remove.bg. You fork them into your own GitHub organization and deploy them to your own Laravel Cloud account, so you're only paying for your own usage, it scales to zero when it's not being used, and you're not just feeding another company's profits. If you want updates, you just pull them down from upstream. And since it's your own fork, you have complete control over the code and the features. And it's all MIT. Find your next tool at &lt;a href="https://scalpels.app" rel="noopener noreferrer"&gt;scalpels.app&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bcrypt Limit (01:19)
&lt;/h2&gt;

&lt;p&gt;This week's top story is a password that's too long. Sjoerd Langkemper's new RFC targets &lt;code&gt;password_hash&lt;/code&gt; with bcrypt, which silently drops everything past the 72nd byte. He'd make that a deprecation in 8.7 and a &lt;code&gt;ValueError&lt;/code&gt; in 8.8. His case is FreshRSS, where a 64-character nonce went in front of the hash, so the 72 bytes held no password at all.&lt;/p&gt;

&lt;p&gt;Kamil Tekiela replied that checking the length is the application's job, not the algorithm's, and Tim Düsterhus agreed in full. It's also 72 bytes, not characters, Tim noted, so non-ASCII passwords could hit it. Rowan Tommins answered: "If every PHP login implementation was reviewed by an expert senior developer, we would not need the password_* API in the first place. The value of this API is that it makes doing the right thing easy, so that you don't need to be an expert in the underlying algorithms to use it safely."&lt;/p&gt;

&lt;p&gt;Robert Chapin showed a shortened password verifying against the full one's hash, and asked: "Is the function named password_verify going to verify the password or not?" Tim says the lost bytes are not where the risk is, and he wrote: "I don't necessarily disagree with the BCrypt truncation being a problem, but in this case the cure is worse than the disease." Derick Rethans is a minus 1, writing: "The problem for me is that this a scary BC break." Overnight, Sjoerd asked Derick what would win him over, &lt;em&gt;maybe switching the default away from bcrypt first&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/bcrypt_max_password_length" rel="noopener noreferrer"&gt;bcrypt max password length RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132689" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/23076" rel="noopener noreferrer"&gt;implementation&lt;/a&gt; · &lt;a href="https://pentesterlab.com/blog/freshrss-bcrypt-truncation-auth-bypass" rel="noopener noreferrer"&gt;FreshRSS bcrypt truncation write-up (CVE-2025-68402)&lt;/a&gt; · &lt;a href="https://www.php.net/manual/en/function.password-hash.php" rel="noopener noreferrer"&gt;password_hash() manual&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Regex Object (03:00)
&lt;/h2&gt;

&lt;p&gt;PHP's proposed regex object has broad support and one unpopular word in its name. Gina P. Banyard's &lt;code&gt;CompiledRegex&lt;/code&gt; prototype drew 18 replies, and Sjoerd Langkemper was in favour of "improving the API, instead of slapping more flags onto the existing one." Larry Garfield wrote: "I would ask that we just call it Regex, not CompiledRegex." Casper Langemeijer, Jordi Kroon and Juris Evertovskis also want it to lose the &lt;em&gt;Compiled&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then there are the 8 boolean flags. Juris says named arguments already make them readable, Gina would rather pass an enum set, which PHP doesn't have yet, and Ayesh Karunaratne and Jordi Boggiano want a factory that takes the modifier letters you already know.&lt;/p&gt;

&lt;p&gt;Osama Aldemeery, who wrote the regex exceptions RFC, pointed out what a compiled pattern can't catch, writing: "Compilation errors are only half of the error story...the other half happens at match time, on patterns that compiled just fine." Tim Düsterhus suggested passing the class could simply switch on throw-on-error, and Osama says he may park his RFC until Gina's reaches a vote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132609" rel="noopener noreferrer"&gt;pre-RFC thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/23868" rel="noopener noreferrer"&gt;prototype&lt;/a&gt; · &lt;a href="https://externals.io/message/132426" rel="noopener noreferrer"&gt;PREG_THROW_ON_ERROR thread&lt;/a&gt; · &lt;a href="https://github.com/composer/pcre" rel="noopener noreferrer"&gt;composer/pcre, cited by Jordi Boggiano&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Io Terminal (04:16)
&lt;/h2&gt;

&lt;p&gt;PHP may finally read single key presses without shelling out to &lt;code&gt;stty&lt;/code&gt;. Pratik Bhujel's terminal extension is now the &lt;code&gt;Io\Terminal&lt;/code&gt; RFC for 8.7, covering terminal size, raw mode that restores itself, single keys and hidden input.&lt;/p&gt;

&lt;p&gt;A Symfony Console pull request, approved by Nicolas Grekas, already uses the extension when it's installed, and Nicolas wrote: "PHP definitely needs native terminal support, calling stty is a workaround we've been carrying since way too long." Nicolas suggested raw mode stay on while any token for that terminal is alive and reset when the last one goes, and Pratik adopted it the same day.&lt;/p&gt;

&lt;p&gt;Larry Garfield is in favour, but called false-on-error an anti-pattern and asked for a way to mock it. Version 0.3 makes &lt;code&gt;Terminal&lt;/code&gt; the interface and &lt;code&gt;SystemTerminal&lt;/code&gt; the native class. Pratik is giving it the full 14 days before an intent to vote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/io_terminal" rel="noopener noreferrer"&gt;Io\Terminal RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132663" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/23941" rel="noopener noreferrer"&gt;implementation&lt;/a&gt; · &lt;a href="https://github.com/prateekbhujel/php-terminal" rel="noopener noreferrer"&gt;reference extension&lt;/a&gt; · &lt;a href="https://github.com/symfony/symfony/pull/66173" rel="noopener noreferrer"&gt;Symfony Console PR using it&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Time Instant (05:15)
&lt;/h2&gt;

&lt;p&gt;The proposed &lt;code&gt;Time\Instant&lt;/code&gt; class got a bridge back to &lt;code&gt;DateTime&lt;/code&gt; this week. Tim Düsterhus and Derick Rethans added &lt;code&gt;toInstant()&lt;/code&gt; to &lt;code&gt;DateTime&lt;/code&gt; and &lt;code&gt;DateTimeImmutable&lt;/code&gt;, and ISO strings now keep their trailing zeros, to show how precise the value is. They won't write the RFC for testing clocks, because they're not convinced it belongs in core, so Tim wrote: "we want to invite you (as the PHP internals community) to write the follow-up RFC for testing clocks". He also asked for a "LGTM, ship it" if people are happy.&lt;/p&gt;

&lt;p&gt;Mirco Babin answered with 8 comments. One is that &lt;code&gt;Time\Clock&lt;/code&gt; and the PSR-20 clock both define &lt;code&gt;now()&lt;/code&gt;, so one class can't implement both. Tim is keeping &lt;code&gt;now()&lt;/code&gt;, with a 15-year horizon in mind, but he'll discuss a single &lt;code&gt;SystemClock::get()&lt;/code&gt; with Derick. And when Mirco asked for minute precision for bus timetables, Morgan replied: "Well, then it's not an instant, is it?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/time_instant_class" rel="noopener noreferrer"&gt;Time\Instant and Time\Clock RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132588" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://www.php-fig.org/psr/psr-20/" rel="noopener noreferrer"&gt;PSR-20 Clock&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Array Shorthand (06:14)
&lt;/h2&gt;

&lt;p&gt;Weilin Du wants PHP arrays to stop making you type every name twice. His new RFC turns &lt;code&gt;=$x&lt;/code&gt; into &lt;code&gt;'x' =&amp;gt; $x&lt;/code&gt;, in arrays, destructuring and &lt;code&gt;foreach&lt;/code&gt;. It started with a colon and switched to the equals sign within the hour, because the colon clashes with the ternary.&lt;/p&gt;

&lt;p&gt;Sebastian Bergmann will vote against, writing: "A syntax change should be backed by data, for instance an analysis of a representative body of real-world code." David Carlier showed that one missing comma would silently turn one valid program into another. Anton Smirnov pointed out that &lt;code&gt;compact&lt;/code&gt; and &lt;code&gt;extract&lt;/code&gt; still exist.&lt;/p&gt;

&lt;p&gt;On the other side, Christian Schneider has run a local patch for this "for many years". Weilin pointed to the same pattern in Composer, Laravel, PHPUnit and Symfony, but says it already feels like he could withdraw the RFC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/array_shorthand" rel="noopener noreferrer"&gt;array shorthand RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132700" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/24034" rel="noopener noreferrer"&gt;implementation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  IO Hooks (07:14)
&lt;/h2&gt;

&lt;p&gt;A new RFC would let ordinary blocking PHP run concurrently, without rewriting it. Jakub Zelenka's IO Hooks starts from the fact that PHP has had Fibers since 8.1, but every blocking function still blocks the whole process, so AMPHP, ReactPHP and Revolt reimplement IO themselves.&lt;/p&gt;

&lt;p&gt;Under his proposal, blocking calls in streams, sockets, curl and the sleep functions get handed to a provider, usually an event loop, which suspends the Fiber until the IO is done. The RFC compares it to Go's runtime. With no provider installed, PHP behaves exactly as today. With one, &lt;code&gt;sleep(1)&lt;/code&gt; in one Fiber is a second of work for the others.&lt;/p&gt;

&lt;p&gt;It depends on a second RFC posted the same evening, Polling API Additions, which fills the gaps in 8.6's Poll API, like sockets, timers and signals. IO Hooks is in an early stage, and neither has replies yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/io_hooks" rel="noopener noreferrer"&gt;IO Hooks RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132727" rel="noopener noreferrer"&gt;IO Hooks thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/23997" rel="noopener noreferrer"&gt;proof of concept&lt;/a&gt; · &lt;a href="https://wiki.php.net/rfc/poll_api_additions" rel="noopener noreferrer"&gt;Polling API Additions RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132725" rel="noopener noreferrer"&gt;Polling API Additions thread&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  List Ban (08:14)
&lt;/h2&gt;

&lt;p&gt;The internals list has removed a contributor. Sepehr Mahmoudi spent the last month posting new-function proposals. On September 15, Derick Rethans warned him over AI-generated content and the number of new threads. On September 21, Ilija Tovilo, as list moderator, set limits of one new thread a month and three emails a week, and called it a last warning. On Sunday Sepehr proposed another RFC, an &lt;code&gt;intl_date_format&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;On Monday Derick confirmed that, after consultation off list, the address is blocked from emailing php.net, wiki access is withdrawn, and it's unsubscribed from the list.&lt;/p&gt;

&lt;p&gt;And this is a tough one. It sucks having to take the nuclear option. He was clearly eager to help, but the list had spent literal weeks trying to get him to slow down, and to stop burdening the list with AI responses, and at some point you've got to enforce the consequences that have been laid out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132664" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://news-web.php.net/php.internals/132684" rel="noopener noreferrer"&gt;Derick Rethans, Sep 28 (news-web)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Hits (09:18)
&lt;/h2&gt;

&lt;p&gt;Quick hits. PHP &lt;code&gt;8.6.0&lt;/code&gt; RC2 is out. RC1 was skipped over a packaging error, so RC2 is the first release candidate, and RC3 is due October 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132617" rel="noopener noreferrer"&gt;PHP 8.6.0RC2&lt;/a&gt; · &lt;a href="https://scherzer.dev/Blog/20260923-no-php86-rc-1" rel="noopener noreferrer"&gt;why RC1 was skipped&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same day brought security releases for 8.5, 8.4, 8.3 and 8.2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://www.php.net/releases/8_5_11.php" rel="noopener noreferrer"&gt;PHP 8.5.11&lt;/a&gt; · &lt;a href="https://www.php.net/releases/" rel="noopener noreferrer"&gt;PHP 8.4.26, 8.3.35, 8.2.34&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sjoerd Langkemper changed his number-base RFC to throw a plain &lt;code&gt;Exception&lt;/code&gt; instead of a &lt;code&gt;ValueError&lt;/code&gt;, since bad input isn't necessarily a bug in your program. &lt;code&gt;intval&lt;/code&gt; stays as it is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/throw_error_for_invalid_characters_for_number_base" rel="noopener noreferrer"&gt;number-base functions RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132379" rel="noopener noreferrer"&gt;thread&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Juliette Reinders Folmer wants to deprecate the &lt;code&gt;b&lt;/code&gt; string prefix, a leftover from PHP 6, and Tim suggested adding it to the 8.7 deprecations RFC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132634" rel="noopener noreferrer"&gt;deprecate the b prefix&lt;/a&gt; · &lt;a href="https://wiki.php.net/rfc/deprecations_php_8_7" rel="noopener noreferrer"&gt;8.7 deprecations RFC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pedro Veloso floated a &lt;code&gt;#[Pure]&lt;/code&gt; attribute the engine would enforce. Larry Garfield said it needs to do more than the static analysers already do, like memoizing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132643" rel="noopener noreferrer"&gt;pure functions idea&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Karoly Negyesi posted a pre-RFC with an implementation for &lt;code&gt;implements … by&lt;/code&gt;, which hands an interface's methods to a property, modelled on Kotlin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132737" rel="noopener noreferrer"&gt;automated delegation pre-RFC&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/24030" rel="noopener noreferrer"&gt;implementation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Alexander Danilov found that much of post-quantum OpenSSL already works in PHP, and offered small PRs for the gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132629" rel="noopener noreferrer"&gt;OpenSSL post-quantum&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the PEAR vote Nick S. planned for September 28 hasn't opened. The RFC is still in discussion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/end_pear_endorsement" rel="noopener noreferrer"&gt;End PEAR Project Endorsement RFC&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR (10:36)
&lt;/h2&gt;

&lt;p&gt;So that's the week. An RFC wants bcrypt to refuse passwords past 72 bytes, and the list is split on whether it's worth the break. Several replies want the regex object called just &lt;code&gt;Regex&lt;/code&gt;, &lt;code&gt;Io\Terminal&lt;/code&gt; is an RFC, and &lt;code&gt;Time\Instant&lt;/code&gt; is looking for someone to write testing clocks. The array shorthand met skeptics, and IO Hooks would make blocking code concurrent. The list also removed a contributor after two warnings. Nothing is in voting for a 7th straight week. Links below.&lt;/p&gt;

&lt;p&gt;The PHP Foundation funds more than half of ongoing &lt;code&gt;php-src&lt;/code&gt; commits, so if you use the language, maybe consider donating at &lt;a href="https://opencollective.com/phpfoundation" rel="noopener noreferrer"&gt;opencollective.com/phpfoundation&lt;/a&gt; — or try guilting your employer into it.&lt;/p&gt;

&lt;p&gt;If you found this useful, a like or a comment helps more people find it. And if you missed &lt;a href="https://dev.to/projektgopher/this-week-in-php-internals-sept-24-2026-3j03"&gt;last week's episode&lt;/a&gt; — where a new time class couldn't tell you what time it is — that's a good one to watch next. Thanks again to &lt;a href="https://scalpels.app" rel="noopener noreferrer"&gt;Scalpels.app&lt;/a&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io" rel="noopener noreferrer"&gt;raw feed&lt;/a&gt; · &lt;a href="https://wiki.php.net/rfc" rel="noopener noreferrer"&gt;RFC wiki&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week in PHP Internals | Sept 24, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Fri, 25 Sep 2026 02:13:27 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-sept-24-2026-3j03</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-sept-24-2026-3j03</guid>
      <description>&lt;p&gt;PHP is getting a new class for a moment in time. It's precise to the nanosecond. It carries no timezone. It ignores leap seconds on purpose. And it &lt;strong&gt;cannot&lt;/strong&gt; tell you what time it is. Not by itself.&lt;/p&gt;

&lt;p&gt;Hello world, it's Thursday, September 24, 2026, and here's what happened This Week in PHP Internals. 12 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Paying every month for small tools you could own? Scalpels replaces expensive subscriptions with professionally built, expertly maintained apps you host yourself — MIT-licensed, forked into your GitHub organization, on your own Laravel Cloud account. At the early-access price, 500 dollars, once, gets you every app in the catalog, and everything they add later. Find your next tool at &lt;a href="https://scalpels.app" rel="noopener noreferrer"&gt;scalpels.app&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time Instant (00:54)
&lt;/h2&gt;

&lt;p&gt;This week's top story is a time class with no &lt;code&gt;now()&lt;/code&gt; method. On Tuesday Tim Düsterhus and Derick Rethans opened the RFC for &lt;code&gt;Time\Instant&lt;/code&gt; and &lt;code&gt;Time\Clock&lt;/code&gt;, the next piece of the new date and time API that started with &lt;code&gt;Time\Duration&lt;/code&gt; in 8.6. An &lt;code&gt;Instant&lt;/code&gt; is a point on the timeline, with no timezone and nanosecond precision, and it ignores leap seconds by design, because operating systems ignore them too.&lt;/p&gt;

&lt;p&gt;What it doesn't have is &lt;code&gt;Instant::now()&lt;/code&gt;. To find out what time it is, you ask a clock. The RFC adds a &lt;code&gt;Time\Clock&lt;/code&gt; interface with one method, &lt;code&gt;now()&lt;/code&gt;, and a &lt;code&gt;SystemClock&lt;/code&gt; that implements it, which Tim, speaking for himself, says nudges people toward a clock they can inject.&lt;/p&gt;

&lt;p&gt;Seifeddine Gmati wants a static &lt;code&gt;now()&lt;/code&gt; anyway, and would rename the class &lt;code&gt;SystemTime&lt;/code&gt;, as Rust does, saving &lt;code&gt;Instant&lt;/code&gt; for a monotonic clock. Tim's view is that the name follows Java and JavaScript's Temporal, and that a &lt;code&gt;Time\now()&lt;/code&gt; function could come as an immediate follow-up, still in 8.7. Juris Evertovskis added that an &lt;code&gt;Instant&lt;/code&gt; "could be the time of the big bang."&lt;/p&gt;

&lt;p&gt;Larry Garfield is broadly in favour and asked about the serialization format, and Tim replied: "If you need to look at the output of serialization you are doing something very wrong." Larry's bigger ask is a roadmap for the whole new API, writing: "You clearly have a roadmap in your heads. Share it. At whatever level of granularity it exists, share it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/time_instant_class" rel="noopener noreferrer"&gt;Time\Instant and Time\Clock RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132588" rel="noopener noreferrer"&gt;discussion thread&lt;/a&gt; · &lt;a href="https://wiki.php.net/rfc/duration_class" rel="noopener noreferrer"&gt;Time\Duration (PHP 8.6)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preg Callbacks (02:32)
&lt;/h2&gt;

&lt;p&gt;The regex exceptions RFC's longest-running question has an answer: when your callback throws inside &lt;code&gt;preg_replace_callback&lt;/code&gt;, the exception goes through as-is. Osama Aldemeery, the RFC's author, showed Python, Java and C# all letting it propagate, with Java's docs spelling it out: exceptions are relayed to the caller. He also offered a fallback — if the policy still demanded wrapping, drop the 2 callback functions from the RFC. His scan of the top forty-eight hundred sixty-five packages puts them at 4.9 percent of the calls to the 8 functions.&lt;/p&gt;

&lt;p&gt;Larry Garfield separated implementation details from inputs, writing: "However, I believe Python, C#, and Java are correct in this case: The callback is an input. It's not an implementation detail hidden from the caller, it's explicitly provided by the caller."&lt;/p&gt;

&lt;p&gt;Tim Düsterhus, who wrote the throwables policy, answered on Monday, writing: "I still believe wrapping is the correct choice, but I won't insist on it based on policy." He asked for 2 other changes: errors like a syntax error in the pattern should be a &lt;code&gt;PcreError&lt;/code&gt;, since they aren't meant to be caught, and &lt;code&gt;preg_last_error&lt;/code&gt; should stay untouched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/preg_throw_on_error" rel="noopener noreferrer"&gt;PREG_THROW_ON_ERROR RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132426" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/22797" rel="noopener noreferrer"&gt;implementation&lt;/a&gt; · &lt;a href="https://github.com/php/policies/blob/main/coding-standards-and-naming.rst#throwables" rel="noopener noreferrer"&gt;throwables policy&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Compiled Regex (03:49)
&lt;/h2&gt;

&lt;p&gt;A new pre-RFC would let PHP regex patterns drop their delimiters entirely. Gina P. Banyard posted it with a prototype on Wednesday, writing: "I spent the day prototyping an alternative to the PREG_THROW_ON_ERROR RFC as I'm not fully a fan of the approach."&lt;/p&gt;

&lt;p&gt;Her &lt;code&gt;Regex\CompiledRegex&lt;/code&gt; class takes a bare pattern plus named boolean flags — case-sensitive, multi-line, dot-matches-newline and so on — so there's no delimiter, no &lt;code&gt;preg_quote&lt;/code&gt; call, and no modifier letters after the pattern. Patterns must be UTF-8, the &lt;code&gt;D&lt;/code&gt; modifier is always on, and there's a &lt;code&gt;Regex\CompilationError&lt;/code&gt; exception to go with it.&lt;/p&gt;

&lt;p&gt;So far the prototype only plugs into &lt;code&gt;preg_split&lt;/code&gt; and &lt;code&gt;preg_grep&lt;/code&gt;. She says the class could be the base for a proper object-oriented regex API, with &lt;code&gt;match&lt;/code&gt; returning a real bool, but she isn't designing that yet. As of Wednesday night the thread has no replies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132609" rel="noopener noreferrer"&gt;Regex\CompiledRegex pre-RFC thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/23868" rel="noopener noreferrer"&gt;prototype&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Script (04:51)
&lt;/h2&gt;

&lt;p&gt;A proposal to make PHP files work like runnable Python modules lasted about 24 hours. Tim Düsterhus brought his pull request to the list, &lt;em&gt;at Gina's request&lt;/em&gt;: the CLI would run any closure the main script returns, so one file is a library when included and a command when executed, like Python's &lt;code&gt;if __name__ == '__main__'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Seifeddine Gmati gave it "A BIG yes", then also floated Hack's approach, an &lt;code&gt;#[EntryPoint]&lt;/code&gt; attribute on a function. Rowan Tommins preferred that, since the entry point wouldn't have to sit at the end of the file. Levi Morrison asked why only the CLI, pointed at Symfony's runtime, which already returns a closure from the front controller, and wondered if the status quo is better. Larry Garfield said he'd be minus 1 on the original, because auto-executing a return type "feels hacky".&lt;/p&gt;

&lt;p&gt;On Wednesday Tim dropped it, writing: "Based on the replies it has become clear that the proposed Closure approach has several questions to solve and possibly needs prior design … This requires much more thought than I'm willing to spend right now, given I wanted to solve a specific use case of mine." He'll look at a &lt;code&gt;__MAIN__&lt;/code&gt; constant instead, holding the path of the script that ran first. Alexandru Pătrănescu thinks &lt;code&gt;realpath&lt;/code&gt; on the script filename already does that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132587" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/23658" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Argon2 Default (06:14)
&lt;/h2&gt;

&lt;p&gt;PHP's default password hash, bcrypt, silently truncates at 72 bytes, Andrey Andreev pointed out, and he asked whether it's time to switch &lt;code&gt;PASSWORD_DEFAULT&lt;/code&gt; to Argon2id. His question for the list was narrower than the case for it: Argon2 needs an outside library — libargon2, libsodium, or OpenSSL since 8.4 — so is any dependency a deal-breaker?&lt;/p&gt;

&lt;p&gt;Casper Langemeijer called that as much a pro as a con, since a real crypto library beats rolling your own. Anton Smirnov pointed back to a 2023 thread that called Argon2 weaker than bcrypt at login-speed settings, and Tim Düsterhus said 500 milliseconds is far too long for an interactive login. Andrey measures PHP's Argon2 defaults at about 240 milliseconds, the same as bcrypt at cost 12.&lt;/p&gt;

&lt;p&gt;Jakub Zelenka answered the dependency question: OpenSSL is an external shared library, so it can't be always enabled. Making it a hard requirement would need an RFC of its own, and with OpenSSL 1.1.1 and 3.0 still supported, it would be a long wait anyway. Andrey's last reply, he wrote: "But anyway, if Jakub's comment was describing the status-quo, it's just not happening."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132542" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://externals.io/message/120993#120996" rel="noopener noreferrer"&gt;2023 discussion&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/pull/19360" rel="noopener noreferrer"&gt;enable --with-openssl-argon2 by default&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Str Mask (07:37)
&lt;/h2&gt;

&lt;p&gt;A proposed &lt;code&gt;str_mask&lt;/code&gt; function met the question the list put to &lt;code&gt;array_str_contains&lt;/code&gt;: does this need to be in core? Sepehr Mahmoudi withdrew &lt;code&gt;array_str_contains&lt;/code&gt; on September 17, and the next day proposed &lt;code&gt;str_mask&lt;/code&gt;, which replaces part of a string with a repeated character, for card numbers, phone numbers and tokens.&lt;/p&gt;

&lt;p&gt;Osama Aldemeery replied that it looks identical to &lt;code&gt;substr_replace&lt;/code&gt; with &lt;code&gt;str_repeat&lt;/code&gt;. Pratik Bhujel found it failed open — an out-of-range offset returned the value unmasked — and that a multibyte mask character got cut to a single byte, so Sepehr switched to throwing a &lt;code&gt;ValueError&lt;/code&gt;. Jordi Kroon suggested &lt;code&gt;#[SensitiveParameter]&lt;/code&gt;, and it went in, until Morgan asked "anyone for a game of Hangman?" — not everything masked is sensitive — and it came back out.&lt;/p&gt;

&lt;p&gt;Pratik did find the prior art: Laravel's &lt;code&gt;Str::mask&lt;/code&gt; and CakePHP's &lt;code&gt;Text::mask&lt;/code&gt; do the same core operation, but both handle multibyte text and behave differently at the edges, and he wrote: "evidence that masking exists is different from evidence that this API is the common missing primitive." Casper Langemeijer called it easily done in userland, and Weilin Du showed &lt;code&gt;substr_replace&lt;/code&gt; doing it in one allocation. 30 messages in, no vote is scheduled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/str_mask" rel="noopener noreferrer"&gt;str_mask() RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132539" rel="noopener noreferrer"&gt;thread&lt;/a&gt; · &lt;a href="https://externals.io/message/132488" rel="noopener noreferrer"&gt;array_str_contains withdrawal&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Contributions (09:02)
&lt;/h2&gt;

&lt;p&gt;Running under two of these new-function threads is a question about AI-written contributions. One reply said the mail and proposals read as machine-generated, and the objection, with or without AI, was quality and the time it costs the people reading.&lt;/p&gt;

&lt;p&gt;Pratik Bhujel set out an order of work, writing: "So I think the order should be: demonstrate the use-case, settle the contract, then benchmark the implementation." The author withdrew one RFC and says he's now building and testing everything locally first. Juris Evertovskis replied: "I'm pretty sure most people here will fairly evaluate that work itself, without worrying what has happened previously with other RFCs."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132539" rel="noopener noreferrer"&gt;str_mask thread (order of work)&lt;/a&gt; · &lt;a href="https://externals.io/message/132488" rel="noopener noreferrer"&gt;array_str_contains withdrawal thread&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Hits (09:49)
&lt;/h2&gt;

&lt;p&gt;Quick hits. PHP &lt;code&gt;8.6&lt;/code&gt; is forked. Matteo Beccati cut the branch on Tuesday, the feature freeze is on, master now targets &lt;code&gt;8.7&lt;/code&gt;, and the first release candidate is due today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132585" rel="noopener noreferrer"&gt;PHP 8.6 forked&lt;/a&gt; · &lt;a href="https://github.com/php/php-src/commit/7f8a74fb29d" rel="noopener noreferrer"&gt;branch commit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week's top story now has a date. Weilin Du updated the &lt;code&gt;IntlRelativeDateTimeFormatter&lt;/code&gt; RFC to use Tim's enums, Tim says it's much better now, and voting should start October 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/reldateformatter" rel="noopener noreferrer"&gt;IntlRelativeDateTimeFormatter RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132187" rel="noopener noreferrer"&gt;thread&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if there are no objections, Nick S. will open the PEAR vote on September 28.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://wiki.php.net/rfc/end_pear_endorsement" rel="noopener noreferrer"&gt;End PEAR Project Endorsement RFC&lt;/a&gt; · &lt;a href="https://externals.io/message/132358" rel="noopener noreferrer"&gt;thread&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pratik Bhujel's &lt;code&gt;php-terminal&lt;/code&gt; extension adds raw mode and single-key reads, so tools like Laravel Prompts can work properly on Windows, and it installs through PIE. Larry pointed out it's 8.7 material now. After Tim's review it lives under an &lt;code&gt;Io\Terminal&lt;/code&gt; namespace with unbacked enums, restores your terminal when its object is destroyed, and is moving to a single object API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://github.com/prateekbhujel/php-terminal" rel="noopener noreferrer"&gt;php-terminal&lt;/a&gt; · &lt;a href="https://externals.io/message/132530" rel="noopener noreferrer"&gt;threads: 1&lt;/a&gt; · &lt;a href="https://externals.io/message/132526" rel="noopener noreferrer"&gt;2&lt;/a&gt; · &lt;a href="https://externals.io/message/132523" rel="noopener noreferrer"&gt;3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And David Maye Kitenge, planning a web framework as a PHP extension, asked about the request lifecycle and threads. Rowan Tommins answered that the CLI leaves parallelism to whoever runs it, and that running user code in a thread per request needs a thread-safe ZTS build, or asynchronous handling in a single thread instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io/message/132534" rel="noopener noreferrer"&gt;extension design Q&amp;amp;A&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR (11:08)
&lt;/h2&gt;

&lt;p&gt;So that's the week. PHP's next time class marks a moment and leaves telling the time to a clock, and Larry wants the map for the rest of the new API. The regex RFC's callback question is settled against wrapping, and Gina posted an alternative that compiles the pattern first. A closure-as-entry-point idea lasted a day, the Argon2 default ran into OpenSSL, and &lt;code&gt;str_mask&lt;/code&gt; met the same question as &lt;code&gt;array_str_contains&lt;/code&gt;. And &lt;code&gt;8.6&lt;/code&gt; is frozen, with nothing in voting for a 6th straight week. Links below.&lt;/p&gt;

&lt;p&gt;The PHP Foundation funds more than half of ongoing &lt;code&gt;php-src&lt;/code&gt; commits, so if you use the language, maybe consider donating at &lt;a href="https://opencollective.com/phpfoundation" rel="noopener noreferrer"&gt;opencollective.com/phpfoundation&lt;/a&gt; — or try guilting your employer into it.&lt;/p&gt;

&lt;p&gt;If you found this useful, a like or a comment helps more people find it. And if you missed &lt;a href="https://dev.to/projektgopher/this-week-in-php-internals-sept-17-2026-4nch"&gt;last week's episode&lt;/a&gt; — where an RFC was winning its vote 4 to 1 and got closed inside the hour — that's a good one to watch next. Thanks again to &lt;a href="https://scalpels.app" rel="noopener noreferrer"&gt;Scalpels.app&lt;/a&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt; &lt;a href="https://externals.io" rel="noopener noreferrer"&gt;raw feed&lt;/a&gt; · &lt;a href="https://wiki.php.net/rfc" rel="noopener noreferrer"&gt;RFC wiki&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week in PHP Internals | Sept 17, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Fri, 18 Sep 2026 09:14:15 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-sept-17-2026-4nch</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-sept-17-2026-4nch</guid>
      <description>&lt;p&gt;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 &lt;strong&gt;winning&lt;/strong&gt;. Because of what the one no vote &lt;strong&gt;said&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;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. &lt;em&gt;But first,&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Is AI working for your team? Anyone can count the lines it produced. Ballast counts the lines that &lt;strong&gt;survive&lt;/strong&gt;. 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 &lt;code&gt;ballast.now&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Corrections (01:00)
&lt;/h2&gt;

&lt;p&gt;1 correction from last week. Around the 6-minute mark I said "Tim Rethans". That's &lt;strong&gt;Derick&lt;/strong&gt; Rethans — who has been Derick for the entire time I've been making this show. Larry Garfield caught it in the YouTube comments, &lt;em&gt;with a smiley face and a good sense of humour.&lt;/em&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intl Vote (01:27)
&lt;/h2&gt;

&lt;p&gt;This week's top story is a vote that was won 4 to 1 and closed anyway. Weilin Du opened voting on &lt;code&gt;IntlRelativeDateTimeFormatter&lt;/code&gt; on Tuesday morning — ICU's "3 days ago" and "next Sunday" formatting for the &lt;code&gt;intl&lt;/code&gt; extension. Within about 10 minutes Tim Düsterhus had voted no, and the closed poll reads &lt;strong&gt;4&lt;/strong&gt; yes, &lt;strong&gt;1&lt;/strong&gt; 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 &lt;code&gt;int&lt;/code&gt; 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 &lt;code&gt;intl&lt;/code&gt; uses enums. On Wednesday Tim sent the discussion thread a middle ground of 3 enums, for style, capitalization and unit, and no namespace, so &lt;code&gt;IntlRelativeDateTimeFormatter::UNIT_DAY&lt;/code&gt; becomes &lt;code&gt;IntlRelativeDateTimeFormatterUnit::Day&lt;/code&gt;. You get IDE autocompletion, documentable cases, and input checks the engine does for free, with &lt;code&gt;RoundingMode&lt;/code&gt; as the precedent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array Str Contains (03:02)
&lt;/h2&gt;

&lt;p&gt;The benchmark that was supposed to make the case for &lt;code&gt;array_str_contains&lt;/code&gt; came back showing the C function &lt;strong&gt;slower&lt;/strong&gt; than a &lt;code&gt;foreach&lt;/code&gt; 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 &lt;code&gt;array_&lt;/code&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preg Wrapping (04:19)
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt; RFC now turns mostly on one question: when your own callback throws inside &lt;code&gt;preg_replace_callback&lt;/code&gt;, 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 &lt;code&gt;array_map&lt;/code&gt; exists to run your callback, but with &lt;code&gt;preg_replace_callback&lt;/code&gt;, 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 &lt;em&gt;does&lt;/em&gt; set &lt;code&gt;preg_last_error&lt;/code&gt; — to &lt;code&gt;PREG_INTERNAL_ERROR&lt;/code&gt;, 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-&lt;code&gt;preg_last_error_msg&lt;/code&gt; guarantee only holds for a single flagged call. Tim's Thursday mail adds one more piece: with the flag set, &lt;code&gt;preg_last_error&lt;/code&gt; shouldn't be touched at all, as &lt;code&gt;JSON_THROW_ON_ERROR&lt;/code&gt; already does, and then a single &lt;code&gt;PregException&lt;/code&gt;, or &lt;code&gt;PregError&lt;/code&gt; plus &lt;code&gt;PregException&lt;/code&gt;, is enough. Osama says the policy call is Tim's. Tim hasn't made it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  PEAR Timeline (06:00)
&lt;/h2&gt;

&lt;p&gt;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, &lt;em&gt;coordinated with Derick Rethans&lt;/em&gt;, 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 &lt;em&gt;before&lt;/em&gt; the site goes static, &lt;em&gt;since he thinks the Windows build still uses the installer&lt;/em&gt;; he plans to resume that pull request in October or November. Nick's answer, &lt;em&gt;checked with Derick&lt;/em&gt;, is that the switch can flip first, as long as &lt;code&gt;go-pear.phar&lt;/code&gt; and the &lt;code&gt;rest&lt;/code&gt; 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 &lt;code&gt;8.2&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Hits (07:16)
&lt;/h2&gt;

&lt;p&gt;Quick hits. The PHP &lt;code&gt;8.6&lt;/code&gt; branch cut is next Tuesday, September 22, alongside the packaging of &lt;code&gt;8.6.0&lt;/code&gt; RC1 — that's the hard feature freeze, after which master becomes &lt;code&gt;8.7&lt;/code&gt;. Beta 3 shipped last Thursday, RC1 is expected September 24, and &lt;code&gt;8.5.11&lt;/code&gt; and &lt;code&gt;8.4.26&lt;/code&gt; both have release candidates out. Matthieu Napoli got RFC karma for an &lt;code&gt;--enable-cli-fpm&lt;/code&gt; build option that links FPM into the &lt;code&gt;php&lt;/code&gt; binary — &lt;code&gt;php --fpm&lt;/code&gt; runs FPM — because on Lambda, with Bref, a second 24-megabyte binary slows every cold start. Marc Henderkes wants it to be the &lt;em&gt;default&lt;/em&gt;, not an opt-in nobody ships. On the opt-in JSON comments and trailing commas idea from August, Tim suggests a single &lt;code&gt;JSON_ALLOW_JSONC&lt;/code&gt; flag that references the existing standard, which to &lt;em&gt;me&lt;/em&gt; sounds like the correct approach, rather than 2 flags and a combinatorial explosion. Vilius Buividavičius wants &lt;code&gt;MyClass::properties::name&lt;/code&gt; — a &lt;code&gt;::class&lt;/code&gt;-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 &lt;code&gt;8.5&lt;/code&gt; 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 &lt;code&gt;zend_string&lt;/code&gt; &lt;code&gt;static&lt;/code&gt; changes its refcount, and whether interned strings need freeing. Alexandru Pătrănescu answered that &lt;code&gt;static&lt;/code&gt; 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 &lt;code&gt;MINIT&lt;/code&gt;, and don't assume a string interned mid-request outlives the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR (09:17)
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;array_str_contains&lt;/code&gt; 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 &lt;code&gt;php-src&lt;/code&gt; commits, so if you use the language, maybe consider donating at &lt;code&gt;opencollective.com/phpfoundation&lt;/code&gt; — or try guilting your employer into it. Thanks again to &lt;code&gt;Ballast.now&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week in PHP Internals | Sept 9, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Thu, 10 Sep 2026 04:58:41 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-sept-9-2026-1dao</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-sept-9-2026-1dao</guid>
      <description>&lt;p&gt;A PHP RFC went to a vote on Friday. By Sunday night its author had pulled it back, over a &lt;strong&gt;no&lt;/strong&gt; vote from the person who wrote the policy it broke. What's left is a question every regex you've ever written has an opinion on: when a pattern fails, is that &lt;em&gt;your&lt;/em&gt; bug — or something you &lt;strong&gt;catch&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Hello world, it's Wednesday, September 9, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;11 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; Is AI working for your team? Lines produced is easy to count. Lines that &lt;strong&gt;survive&lt;/strong&gt; is the number that matters. Ballast reads your git history — never your code — and gives you stable velocity alongside a durability score from 300 to 850. It's &lt;strong&gt;free&lt;/strong&gt;, and it updates monthly. &lt;code&gt;ballast.now&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;3 corrections from last week. PHP &lt;code&gt;8.4.25&lt;/code&gt; was a &lt;strong&gt;bug-fix&lt;/strong&gt; release, not a security release. The announcement mails said security, we repeated it, and Daniel Scherzer pointed us at the NEWS file and the php.net archive. In the libxml-rs story we described 2 contributors without naming them, and Tim Düsterhus pointed out that every &lt;code&gt;From&lt;/code&gt; header in that thread carried a &lt;strong&gt;real name&lt;/strong&gt;. They were James Gilliland and David Carlier. And around the 4-minute mark I said Tim agreed with Sjoerd on the substance. He &lt;strong&gt;disagreed&lt;/strong&gt; — Džuris caught that one on the internals Discord. Thanks to all 3.&lt;/p&gt;

&lt;p&gt;This week's top story is a vote that lasted &lt;strong&gt;56 hours&lt;/strong&gt;. Osama Aldemeery opened voting on &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt; on Friday — an opt-in flag that turns a PCRE error into a &lt;code&gt;PregException&lt;/code&gt;. Within the hour, Tim Düsterhus, who wrote PHP's throwables policy, voted &lt;strong&gt;no&lt;/strong&gt;, writing: "I have just read through the RFC and voted against it, despite being in agreement of the general concept." His 2 reasons: a pattern that fails to compile would keep its warning and the exception would carry only the thin &lt;code&gt;preg_last_error_msg&lt;/code&gt; text, and an exception thrown inside your own &lt;code&gt;preg_replace_callback&lt;/code&gt; callback would pass through &lt;strong&gt;unwrapped&lt;/strong&gt;, where the policy says an extension must wrap what it calls. Osama pushed back, but on Sunday night he pulled the vote, writing: "The flag as it stands violates the throwable policy, as Tim's point shows. That's not something to fix with the vote open, so I'm pulling it back rather than changing the proposal out from under people who already voted." Osama's case against wrapping, in his words: "…wrapping a callback's exception in a PregException produces a PregException that maps to no preg error. You can be holding a PregException while preg_last_error() and preg_last_error_msg() report no error at all." Fixing that means a 3-class hierarchy. Robert Humphries argued that most of those errors — an invalid pattern, bad UTF-8 — are programmer errors, so, arguably, &lt;code&gt;PregError&lt;/code&gt;. Tim agreed compilation failures should be. The RFC is back under discussion; what a regex error &lt;strong&gt;is&lt;/strong&gt; stays open.&lt;/p&gt;

&lt;p&gt;There's a &lt;em&gt;whole class&lt;/em&gt; of engine crashes in PHP that, it's said, &lt;strong&gt;only&lt;/strong&gt; fuzzers and LLMs have ever triggered — and Gina P. Banyard wants PHP to stop fixing them. Her Tuesday mail describes a growing pile of use-after-free reports where an error handler frees the very variable that triggered the warning. Each fix, she says, is a refcount dance around the emit that &lt;strong&gt;everyone&lt;/strong&gt; pays for in performance, and most of the triggers are deprecations PHP 9 removes or promotes to Errors anyway. Her ask is a consensus, ideally without an RFC, that callbacks messing with engine state are &lt;em&gt;undefined behaviour&lt;/em&gt;. The 4 replies from 3 people inside 90 minutes mostly want the bugs fixed. Ilia Alshanetsky says PHP 9 is far off and production migration further, so fix case by case where the cost is low. Ilija Tovilo shares the frustration, but says case by case has already been tried, and wrote: "I'd still very much be in favor of fixing these issues, mainly because they are a big time sink for the security team as well, due to false-positive reports. Arnaud and I were planning on proposing an RFC that mitigates at least a large portion of them…" Tim Düsterhus adds that PHP 9 will bring new deprecations of its own, &lt;em&gt;and we're back where we started.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The PEAR maintainer nobody could reach for &lt;strong&gt;months&lt;/strong&gt; has answered, and according to Nick S. he agrees with the goal. Nick reported Monday that Chuck Burgess of the PEAR Group got in touch and is good with looking at sunsetting the website and removing PEAR from the PHP source. Nick wants to strike the RFC's line about maintainers not responding, and Larry Garfield and Tim Düsterhus both call that a minor change, so the vote can open after a &lt;strong&gt;1-week&lt;/strong&gt; cooldown rather than 2. Rowan Tommins pushed on Nick's word &lt;em&gt;formality&lt;/em&gt;: Chuck is one of 8 listed members of the PEAR Group, so his agreement is one vote, not final authority. He wrote: "I would make a distinction between technical ability and moral authority… Derick has the ability to repoint the DNS for pear.php.net, but holding this discussion and an RFC vote is a way to grant authority." There's a loss, too: the PEAR user accounts are gone, so the missing bug data &lt;strong&gt;can't&lt;/strong&gt; be recovered. Derick Rethans wants the readonly site left up for a year, then a tarball on museum.php.net. And Rowan sent Nick's mirror a pull request with the old site's colours and a &lt;em&gt;locked PEAR&lt;/em&gt; logo. The favicon is under discussion. Derick doesn't care what it is, as long as there is one.&lt;/p&gt;

&lt;p&gt;Last week's top story ended &lt;strong&gt;without&lt;/strong&gt; an RFC — by its author's choice. Luca Rodenhäuser closed the strict-identifiers thread on Thursday, saying the proposal he opened with "did not survive the thread, and I think it was right that it did not." He credited 3 people with changing his mind — Claude Pache for the distinction between a name and an identifier, Rowan Tommins for separating rejecting from normalising, and Larry Garfield for insisting 250 packages wasn't enough, which is how math-php's 888 formula-shaped variables turned up. The question the list never answered is whether non-ASCII identifiers are a supported feature &lt;em&gt;at all&lt;/em&gt;. The manual says they work by accident; fourteen hundred forty-seven of them in the top 5,000 packages say otherwise. His line: "I am not going to write an RFC on a guess." Instead he's sending a documentation PR describing what actually happens today, and leaving one offer on the table — a compiler complaint about invisible characters in names, 68 cases in half a million files, no opt-in needed, &lt;em&gt;if anyone ever wants it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The vote that was due Friday on the number-base functions &lt;strong&gt;didn't open&lt;/strong&gt;. What the list got instead was a naming question. Sjoerd Langkemper's RFC makes &lt;code&gt;octdec&lt;/code&gt;, &lt;code&gt;hexdec&lt;/code&gt;, &lt;code&gt;bindec&lt;/code&gt; and &lt;code&gt;base_convert&lt;/code&gt; throw on invalid input, and after last week's argument that parsing is &lt;em&gt;Exception&lt;/em&gt; territory rather than &lt;em&gt;Error&lt;/em&gt;, he says he's considering it — and asked what the exception should be, with SPL's &lt;code&gt;RangeException&lt;/code&gt; and &lt;code&gt;RuntimeException&lt;/code&gt; on his list. The policy answer, from Rowan Tommins, is that the base has to be &lt;code&gt;Exception&lt;/code&gt; plus something of its own, never SPL — maybe a &lt;code&gt;BaseConversionException&lt;/code&gt;. Tim Düsterhus would go further and throw plain &lt;code&gt;Exception&lt;/code&gt;: these functions sit in &lt;code&gt;standard&lt;/code&gt;, which the policy says not to namespace under, they may be redesigned into an &lt;code&gt;int&lt;/code&gt; or &lt;code&gt;number&lt;/code&gt; namespace later, and promising &lt;strong&gt;nothing&lt;/strong&gt; costs nothing. Morgan asked whether &lt;code&gt;intval&lt;/code&gt; is on the list. No answer yet.&lt;/p&gt;

&lt;p&gt;Whether &lt;strong&gt;speed&lt;/strong&gt; is a reason to put something in PHP's standard library is now a real 2-way disagreement. Last week Tim Düsterhus said performance should not be a factor at all. On Friday Larry Garfield answered that it's one data point among many, writing: "If, to use the current example, benchmarking shows that array_str_contains() is 50% faster in C than in user-space, that's a very different conclusion than if we find it is 0.5% faster." Tim's reply: "Performance is a property of the implementation, not a property of the feature." Something too slow can't ship, but that's a fact about &lt;em&gt;one implementation&lt;/em&gt;; nothing ships &lt;strong&gt;because&lt;/strong&gt; it's fast, and a userland-versus-C benchmark is rarely apples to apples anyway. His alternative is the Optimizer: rewrite &lt;code&gt;array_filter&lt;/code&gt; with a partial application into a &lt;code&gt;foreach&lt;/code&gt; loop, the way &lt;code&gt;8.6&lt;/code&gt; already rewrites &lt;code&gt;array_map&lt;/code&gt;. Larry's position, restated: never decisive, still worth knowing. That's where it sits.&lt;/p&gt;

&lt;p&gt;The scan meant to prove &lt;code&gt;array_str_contains&lt;/code&gt; is a common need found 32 uses in 200 packages — then lost nearly &lt;strong&gt;half&lt;/strong&gt; of them on review. Sepehr Mahmoudi scanned the top 200 Composer packages, about 21,000 files, and counted 32 filter-an-array-by-substring patterns. Rowan Tommins read the results and found at least 15 doing extra logic the function couldn't replace, concluding: "That's still something, but it's not strong evidence that this is an extremely common task." Sepehr agreed the scanner matched shapes rather than closure bodies, and the RFC now says &lt;em&gt;up to&lt;/em&gt; 17 of 32, with a benchmark promised. David Carlier wants the RFC's claim that non-strings are cast proven in the tests. And as of Friday the RFC still wasn't on the wiki's index page — Tim Düsterhus's &lt;strong&gt;second&lt;/strong&gt; reminder.&lt;/p&gt;

&lt;p&gt;Quick hits. Weilin Du intends to open voting on &lt;code&gt;IntlRelativeDateTimeFormatter&lt;/code&gt; on September 15. Tim Düsterhus's one catch is that the RFC clones the ICU number formatter internally, so reconfiguring your &lt;code&gt;NumberFormatter&lt;/code&gt; afterwards would &lt;em&gt;silently&lt;/em&gt; do nothing; Weilin called it a good catch and will refresh it lazily before each format call. Timo Poppinga, new to the list, wants the &lt;code&gt;openssl&lt;/code&gt; extension to expose OpenSSL's provider model &lt;strong&gt;generically&lt;/strong&gt;, so post-quantum algorithms like ML-KEM and ML-DSA work without a constant per algorithm — and says he's probably not the right person to write the C. Ayesh Karunaratne pointed out Sebastian raised the same thing a while back with no traction, and argued the extension should stay as close to OpenSSL as &lt;code&gt;curl&lt;/code&gt; stays to libcurl. Dmytro Kulyk answered Nicolas Grekas's review of the &lt;code&gt;NoSerialize&lt;/code&gt; attribute &lt;strong&gt;10 months&lt;/strong&gt; on, conceding Symfony has no &lt;code&gt;__sleep&lt;/code&gt; the attribute would replace, but Magento 2 has 31 classes of them; the RFC now migrates 107 internal classes and makes &lt;code&gt;unserialize&lt;/code&gt; discard marked properties too. And Florent Morselli, who maintains a base64url library with 46 million downloads, wants the data-encoding RFC's strict mode to actually be &lt;strong&gt;strict&lt;/strong&gt;. Today it skips whitespace and ignores non-canonical trailing bits, which means one WebAuthn credential has 16 spellings, &lt;em&gt;15 of them outside your unique index.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So that's the week. A vote opened on Friday and was gone by Sunday night, and what it left behind is a real argument about whether a regex error is an Exception, an Error, or &lt;strong&gt;both&lt;/strong&gt;. Gina wants a class of engine crashes declared undefined behaviour, and 3 people would rather fix them. The PEAR maintainer answered, the RFC can go to a vote after a 1-week cooldown, and the user accounts are already gone. Last week's top story closed itself with a documentation PR instead of an RFC. And for the &lt;em&gt;fourth&lt;/em&gt; week running, nothing is in the voting phase. Links below. The PHP Foundation funds more than half of ongoing &lt;code&gt;php-src&lt;/code&gt; commits, so if you use the language, maybe consider donating at &lt;code&gt;opencollective.com/phpfoundation&lt;/code&gt; — or try guilting your employer into it. Thanks again to &lt;code&gt;Ballast.now&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | Sept 2, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Thu, 03 Sep 2026 01:20:30 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-sept-2-2026-5a9p</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-sept-2-2026-5a9p</guid>
      <description>&lt;p&gt;Hello world, it's Wednesday, September 2, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;11 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; Is AI working for your team? You can measure the code it produces, but the number that matters is how much of it survives. Ballast reads your git history — never your code — and gives you stable velocity plus a durability score between 300 and 850. Updated monthly, and it's &lt;strong&gt;free&lt;/strong&gt;. &lt;code&gt;ballast.now&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This week's top story starts with a rule most of us never read. Luca Rodenhäuser opened Wednesday with the line in the scanner that defines a PHP identifier — in &lt;strong&gt;bytes&lt;/strong&gt;, not characters. Every byte at or above hex &lt;code&gt;80&lt;/code&gt; is accepted, so &lt;code&gt;$x&lt;/code&gt; followed by a no-break space is a second variable that looks identical. He proposed a per-file &lt;code&gt;declare&lt;/code&gt; to pin that down, then scanned the 250 most-installed Packagist packages and found exactly &lt;strong&gt;one&lt;/strong&gt; identifier that would break.&lt;/p&gt;

&lt;p&gt;Larry Garfield suggested skipping the opt-in and having PHP 9 enforce it, since Symfony fixes its one class and &lt;em&gt;99.99% of developers never notice&lt;/em&gt;. So Luca reran it against the top 5,000 packages. Half a million files turned up fourteen hundred forty-seven non-ASCII identifiers, 91% of them in &lt;code&gt;math-php&lt;/code&gt;, where the variable names spell the formula. He reported the result himself, writing: "So the honest answer to '99.99 % won't notice' is that one library would notice 888 times, and its author chose that style deliberately and has shipped it for years." Then came 3 questions. Derick Rethans asked whether 13.7 kilobytes of tables in every PHP process is worth it. Juliette Reinders Folmer asked what it does to variable variables. And Rowan Tommins asked how much of this is &lt;strong&gt;rejecting&lt;/strong&gt; names and how much &lt;strong&gt;normalising&lt;/strong&gt; them. Each sent him back to measure, and he split his proposal into 3: a diagnostic, a well-formedness rule, and a conformance rule. He says he owes the thread a problem statement.&lt;/p&gt;

&lt;p&gt;Nick Sdot opened an RFC on Thursday to end PHP's endorsement of PEAR. He started about three months ago, going back through every previous discussion and every unvoted attempt, and he's already built a static mirror so the command-line tool keeps working. His case is that PEAR is partly broken, spammed, barely active and now unmaintained. Rowan Tommins backed it. On the argument that PEAR deserves more time to be revived, he wrote: "If that's not long enough, how long is? If the site stays alive in its current state for 10 years, it will continue to be exploited by spammers and probably worse. That's not in anyone's interest." Nick then put a number on the whole thing. &lt;strong&gt;6 packages&lt;/strong&gt; are still publishing to PEAR. 3 of them are PEAR's own infrastructure. 2 more were recently marked unmaintained. Which leaves exactly one independent package still being maintained, and that's &lt;code&gt;Net_SMTP&lt;/code&gt;. Nick gave its maintainer a one-word aside in the thread, and the word was &lt;em&gt;legend&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Sjoerd Langkemper told the list on Friday he intends to open a vote on making the number-base functions throw. His RFC makes &lt;code&gt;octdec&lt;/code&gt;, &lt;code&gt;hexdec&lt;/code&gt;, &lt;code&gt;bindec&lt;/code&gt; and &lt;code&gt;base_convert&lt;/code&gt; throw a &lt;code&gt;ValueError&lt;/code&gt; on invalid input. His framing was that this isn't controversial — the list agreed to it in an earlier &lt;code&gt;base_convert&lt;/code&gt; proposal — and that the RFC is mostly procedure. Tim Düsterhus disagreed on the substance. He argued that passing untrusted input to these functions is an expected use case, which means developers will want to catch what comes back, and drew the line firmly: "The Error hierarchy is not intended to be caught, though. It should thus use something from the Exception hierarchy." Sjoerd asked whether that distinction is written down anywhere. It is. Tim pointed him at the throwables section of the coding standards policy, and quoted it: "The Error hierarchy MUST NOT be used for errors that are expected to be thrown (and caught) during normal operation of a PHP program. … a parsing function that is expected to be used with untrusted input must not throw an Error if the input is malformed." Base conversion, Tim argues, &lt;strong&gt;is&lt;/strong&gt; parsing.&lt;/p&gt;

&lt;p&gt;The array-filtering function we covered last week came back on Sunday, renamed &lt;code&gt;array_str_contains&lt;/code&gt; and retargeted at &lt;code&gt;8.7&lt;/code&gt;. Sepehr Mahmoudi's case is that filtering an array by substring is common enough to deserve C, instead of paying for a closure on every element. Seifeddine Gmati went first and went broad. He couldn't remember ever writing that code, said the same argument would justify &lt;code&gt;array_str_starts_with&lt;/code&gt; and a few hundred more combinations, and pointed out that nothing in the name tells you it filters. He called it redundant. Bruce Weirdan turned the performance claim around, asking whether the closure overhead itself should be fixed, since that would speed up &lt;strong&gt;every&lt;/strong&gt; builtin that takes a callable. Kamil Tekiela asked what the numbers actually are, and said he'd never hit it as a bottleneck. Sepehr then walked back his own strongest claim, agreeing that a filter has to read the whole array rather than stopping at the first match. He's promised static analysis across Packagist to back the frequency claim.&lt;/p&gt;

&lt;p&gt;Last week's top story was the list arguing about machine-written mail in the abstract. This week it stopped being abstract. Juris was the one who did the work, drafting the guideline text he thinks a newcomer should get. It says to write the message yourself rather than rephrase yourself with an LLM, and that there's no requirement to have perfect English on that list — plenty of productive contributors are more fluent in C and PHP than in English. Then he demonstrated it instead of asserting it. He wrote his next 3 paragraphs in Latvian, machine-translated them, and sent both versions in the same message, arguing the imperfect translation stays closer to what he meant than anything a chatbot would phrase for him. Then Sepehr Mahmoudi acknowledged that he had been having AI write his replies. Weilin Du asked the thread to stop naming people, saying it had become a place to point fingers rather than a place for technical debate. Yuya Hamada apologised for going too hard, and it stopped there. &lt;strong&gt;There's still no written policy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Théo Attali introduced himself on Saturday with a first contribution and a small, well-argued gap. PHP's &lt;code&gt;DATE_RFC3339_EXTENDED&lt;/code&gt; gives you milliseconds with a numeric offset, but a lot of systems expect the same instant with a &lt;code&gt;Z&lt;/code&gt; on the end, which is what JavaScript's &lt;code&gt;toISOString&lt;/code&gt; produces. He proposed a constant for it, and flagged the flaw in his own idea before anyone else could. A format string containing a literal &lt;code&gt;Z&lt;/code&gt; can't force the value into UTC. Andreas Heigl agreed, with unusual standing to do it — he added the extended constants. He wouldn't add any more now, since a constant only helps people who've already upgraded, and pointed Théo at a userland formatter built on one line that has worked since PHP 5.3. Théo revised on the spot, proposing an instance method instead. Then Tim Düsterhus redirected it. He pointed out that PHP 8.6 ships the first piece of a new date and time API, and that the proposed &lt;code&gt;Time\Instant&lt;/code&gt; is deliberately timezone-less — which makes a Zulu-format method an obvious thing to add &lt;em&gt;there&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;An offer arrived on Saturday from a name the list hadn't seen before. Riaan de Beer has written &lt;code&gt;libxml-rs&lt;/code&gt;, a native-Rust reimplementation of libxml2 that's compatible at the C ABI level, and he asked whether php-src would be open to a test build against it. He says &lt;code&gt;xmllint&lt;/code&gt; and &lt;code&gt;xmlcatalog&lt;/code&gt; come out byte-identical against libxml2 2.15.3 across eleven hundred ten tests, and he's careful about the ask — an experimental alternative provider, not a default. What the list answered was his opening sentence. He'd said libxml2 has been unmaintained since December 2025, and Pierre replied that the repository has had many commits since, and that a mature XML library not cutting frequent releases isn't an abandoned one. 2 more contributors agreed. One wrote that libxml2 was only briefly unmaintained before new maintainers stepped up, and the other added that one of those maintainers helps php-src out directly. &lt;em&gt;Nobody has answered the actual question yet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The question of whether RFCs should ship a userland polyfill got 2 substantial answers this week. Nicolas Grekas answered from the Symfony side, which is the side that does the work. Every polyfillable feature ends up in the &lt;code&gt;symfony/polyfill&lt;/code&gt; monorepo anyway, and the one that ships is often not the one in the RFC. Polyfills, he concluded, need a separate workflow. Then Tim Düsterhus answered the other argument for them, which was Larry Garfield's suggestion that a polyfill gives you something to benchmark the C against. Tim wrote: "I believe performance should not be a factor in deciding what should be part of the stdlib and what should not: Performance is a moving target and what might be true today might no longer be true tomorrow… Once we add something to the stdlib we need to maintain it for the next 15+ years. (Broad) usefulness and good API design must be the deciding factors…" He added that PIE has made building a private extension easier than it's ever been.&lt;/p&gt;

&lt;p&gt;Quick hits. 3 releases landed in 3 days. Calvin Buckley put out &lt;code&gt;8.4.25&lt;/code&gt;, a &lt;strong&gt;security&lt;/strong&gt; release, so that one's worth doing today. Daniel Scherzer released &lt;code&gt;8.5.10&lt;/code&gt;, a bugfix. And Matteo Beccati has &lt;code&gt;8.6.0beta2&lt;/code&gt; up for testing. Last night Nick Sdot replied to the &lt;code&gt;nameof&lt;/code&gt; RFC to say he'd like to see it in &lt;code&gt;8.7&lt;/code&gt; — and the message he was replying to was posted in May of 2023. &lt;em&gt;3 years and 3 months is a long time to keep a browser tab open.&lt;/em&gt; And on the named parameter lists thread, somebody answered Larry Garfield's question from a fortnight ago about why people treat a small data structure as unworthy of being a class. The answer wasn't performance. It's cognitive cost — returning 2 values as an array and unpacking them at the call site is easier to hold in your head than a dedicated object, and static analysis can describe that array well enough that you don't lose much.&lt;/p&gt;

&lt;p&gt;So that's the week. No RFC has been in the voting phase for 3 weeks running. Somebody scanned half a million PHP files to work out what a PHP identifier is, and came back having split his own proposal into 3. There's an RFC to end PHP's endorsement of PEAR, which has one maintained package left on it. There's a real disagreement about whether base conversion counts as parsing, which decides which kind of throwable it gets. A new array function has 4 people against it and nobody for it. And the argument about who writes the mail on that list got a concrete answer. Links below. The PHP Foundation funds more than half of ongoing &lt;code&gt;php-src&lt;/code&gt; commits, so if you use the language, maybe consider donating at &lt;code&gt;opencollective.com/phpfoundation&lt;/code&gt; — or try guilting your employer into it. Thanks again to &lt;code&gt;Ballast.now&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | August 26, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Fri, 28 Aug 2026 04:05:42 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-august-26-2026-2675</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-august-26-2026-2675</guid>
      <description>&lt;p&gt;Hello world, it's Wednesday, August 26, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;10 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; You shipped a lot of code this quarter, but do you know how much of it is actually still there? Ballast reads your git history — never your code — and scores what survives. Stable velocity, plus a durability rating between 300 and 850 — &lt;em&gt;like a credit score for your codebase&lt;/em&gt; — updated every month, and it's &lt;strong&gt;free&lt;/strong&gt;. &lt;code&gt;ballast.now&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This week's top story isn't really about PHP. It's about how the internals list talks to itself. Messages have been arriving that were clearly written or heavily assisted by a large language model — that flat, over-professional register that thanks you warmly and then restates your own point back at you — and somebody finally said the quiet part in plain text. 24 messages followed, about where the line actually sits. Nobody argued against translation. English is a second or third language for a good part of that list, and that is a real accessibility question rather than a laziness one. What people object to is &lt;strong&gt;authorship&lt;/strong&gt; — the argument itself being handed to a machine — and the harder problem underneath, which is that there's no reliable way to tell the difference from the outside. Nothing's been written down yet. But if you want a say in what does get written down, the community Discord is at &lt;code&gt;phpc.chat&lt;/code&gt;, and there's an internals channel there. &lt;em&gt;It's a community server, not an official PHP one.&lt;/em&gt; There's a thread in it working on exactly these guidelines. So if you want to head there and argue with us about what should be in the guidelines, feel free to join the discussion.&lt;/p&gt;

&lt;p&gt;A new RFC opened on Saturday, from the same contributor whose last one had just been withdrawn. Sepehr Mahmoudi proposed &lt;code&gt;array_match()&lt;/code&gt;, which filters an array down to the values containing a substring, implemented in C so you don't have to pay for a closure on every element. Yuya Hamada replied within the hour, asking whether &lt;code&gt;array_filter()&lt;/code&gt; isn't already enough, pointing at a GitHub search full of userland functions already named &lt;code&gt;array_match&lt;/code&gt; that don't all behave alike, and noting that the &lt;code&gt;str_icontains&lt;/code&gt; RFC was declined, so an ASCII-only case-insensitive flag is a hard sell. Then Tim Düsterhus pointed out that in &lt;code&gt;8.6&lt;/code&gt; this is already 1 line, because partial function application lets you drop &lt;code&gt;str_contains&lt;/code&gt; into &lt;code&gt;array_filter()&lt;/code&gt; with a placeholder. Christian Schneider noted that &lt;code&gt;preg_grep()&lt;/code&gt; has done basically the same job for years.&lt;/p&gt;

&lt;p&gt;The case against it was mostly one case, made 5 ways. Ayesh Karunaratne went after the premise, writing: "I have worked on Drupal, WordPress, Silex, and bespoke code bases, spending enough time profiling them. An array string search has never been a bottleneck." Larry Garfield called it an XY problem and said huge in-memory arrays are a code smell to begin with. mickmackusa offered the alternative nobody else had — make &lt;code&gt;str_contains()&lt;/code&gt; polymorphic, the way &lt;code&gt;str_replace()&lt;/code&gt; already takes an array. Sepehr has since dropped the case-insensitive flag, renamed it &lt;code&gt;array_str_contain()&lt;/code&gt;, and moved the target to &lt;code&gt;8.7&lt;/code&gt;, since &lt;code&gt;8.6&lt;/code&gt; is frozen. &lt;strong&gt;Nobody's argued in favour of it so far.&lt;/strong&gt; &lt;em&gt;The proposal, so far, contains no support.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nick Sdot brought a documentation question to the list on Thursday. He's restructuring PHP's internals book, the docs that live inside &lt;code&gt;php-src&lt;/code&gt;, and his first pull request converts the pages from reStructuredText to Markdown — a light 1,100-line mechanical diff that nets out 86 lines shorter. Ilija Tovilo, who set the book up, called it churn, and answered that the source is neither pure Markdown nor reStructuredText but MyST, so renaming files fixes some rendering and breaks the reStructuredText-flavoured parts. His real objection was the diagnosis. He wrote: "None of this is wrong, but I don't think the docs have stalled because the syntax is too hard. Rather, more time should be designated to them." Weilin Du and Calvin Buckley both said the effort belongs in the content. Nick's clarification explains the thread. The old docs folder he's merging in is &lt;strong&gt;already Markdown&lt;/strong&gt;, so a conversion happens in one direction or the other. It's still open.&lt;/p&gt;

&lt;p&gt;Robert Chapin spent the week working through an old RFC. Deprecate Fuzzy Type Casts, by Alexandre Daubois and Nicolas Grekas, dates to January, is still under discussion, and still targets &lt;code&gt;8.6&lt;/code&gt; on the wiki — which Robert would like changed, given there's been no discussion since. His objection is that the RFC's own migration guidance doesn't hold up. He points out that with the string &lt;code&gt;1.5&lt;/code&gt;, &lt;code&gt;is_numeric()&lt;/code&gt; returns true, so the validate-before-casting example still triggers the deprecation, while &lt;code&gt;is_int()&lt;/code&gt; and &lt;code&gt;is_float()&lt;/code&gt; return false for every numeric string. He says the &lt;code&gt;filter_var()&lt;/code&gt; alternative doesn't guarantee an integer back either. He asked: "Are developers expected to replace a sing[le] type cast with 8 lines of code for PHP 8.6?" &lt;em&gt;Nobody has answered him.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A process question opened yesterday morning. Sepehr Mahmoudi noticed that some RFCs proposing new functions include a userland polyfill and some don't, and asked whether the RFC template should recommend one wherever that's feasible. His reasons are that a polyfill pins down the exact behaviour, edge cases and all, without anyone reading the C, and that it gives teams like Symfony's polyfill maintainers an accurate head start. Larry Garfield called recommended-where-relevant-but-not-required a reasonable policy, and added a second use for it, saying: "And it would also give us a target to benchmark against to see if putting it in C really has a performance benefit." &lt;em&gt;Which is exactly what 2 people spent the weekend asking Sepehr for on his other proposal.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gina P. Banyard posted a correction on Friday to an already-accepted RFC. Steven Wilton's SNMP improvements proposal states that its target is the next stable release for all currently supported PHP versions. Gina's point is that this runs against the release process policy on patch versions, so the changes will land in &lt;code&gt;8.6&lt;/code&gt; only. She also asked for a design change — the new integer constants in the output-controls section would become PHP &lt;strong&gt;enums&lt;/strong&gt; instead, which improves type safety in userland and translates the C enums SNMP already defines into PHP ones. The plan is to have it merged in time for &lt;code&gt;8.6.0&lt;/code&gt; beta 2.&lt;/p&gt;

&lt;p&gt;Weilin Du, who maintains the &lt;code&gt;intl&lt;/code&gt; extension, spent part of the week handing out work. He'd like some of the extension's constants turned into enums, proper namespaces on its classes so they stop colliding, and the remaining gaps between PHP's APIs and the underlying ICU APIs filled in. He was blunt about the error handling, writing: "the error state stuff in the extension is, frankly, bad, in my opinion, and could be optimized since it has caused a lot of very stupid bugs." He suggested the enums and namespaces could be an &lt;code&gt;8.7&lt;/code&gt; RFC if somebody picks it up. Yuya Hamada added the reason it matters. Feedback from right-to-left language users is thin across the &lt;strong&gt;whole&lt;/strong&gt; industry, not just PHP, and PHP's internationalisation depends on getting it.&lt;/p&gt;

&lt;p&gt;Quick hits. &lt;code&gt;array_search_range()&lt;/code&gt;, last week's top story, is officially withdrawn — mickmackusa posted a 7-point review hours after we recorded, and Sepehr Mahmoudi pulled it on Thursday and called it a valuable learning experience. Weilin Du's extension-name case sensitivity proposal is going to a vote, eventually. A core developer objected, which under policy makes it an RFC, and he'll open that after the &lt;code&gt;8.6&lt;/code&gt; branch is cut on September 22, with both behaviours on the ballot for &lt;code&gt;8.7&lt;/code&gt;. And Zachary DuBois introduced himself on Thursday, asked whether adding missing libsodium functions needs an RFC or just a pull request, was told to open the pull request, and had it up by Sunday. It adds X-Wing and ML-KEM-768 bindings to the &lt;code&gt;sodium&lt;/code&gt; extension. &lt;em&gt;Post-quantum key encapsulation, arriving as somebody's first pull request. Quantum-resistant, and so far review-resistant.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So that's the week: no RFC in the voting phase for the second week running; a long argument about who is actually writing the mail on the internals list; a new &lt;code&gt;array_str_contain()&lt;/code&gt; proposal with 5 people against it and nobody for it; a documentation pull request that turned out to be a consolidation question rather than a format preference; unanswered holes in the fuzzy casts migration path; and post-quantum crypto arriving as somebody's first pull request. Links to every thread are below. The PHP Foundation bankrolls a lot of &lt;code&gt;php-src&lt;/code&gt; development, so if you use the language, maybe consider donating at &lt;code&gt;opencollective.com/phpfoundation&lt;/code&gt; — or try guilting your employer into it. Thanks to &lt;code&gt;Ballast.now&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | August 19, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Fri, 21 Aug 2026 22:56:58 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-august-19-2026-6mh</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-august-19-2026-6mh</guid>
      <description>&lt;p&gt;Hello world, it's Wednesday, August 19, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;12 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; Is AI working for your team? Ballast answers that for &lt;strong&gt;free&lt;/strong&gt;. It reads your git history — never your code — and gives you 2 numbers every month. Stable velocity tells you how much of what you ship survives. A durability score from 300 to 850 tells you whether it holds up. &lt;code&gt;ballast.now&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This week's top story: a 5-argument function proposal turned into 25 messages, 3 threads, and the week's central design argument. Sepehr Mahmoudi, who introduced himself to the list 8 days ago, proposed &lt;code&gt;array_search_range()&lt;/code&gt; — an &lt;code&gt;array_search()&lt;/code&gt; that takes an offset and a length, so you can search part of an array without building an intermediate copy with &lt;code&gt;array_slice()&lt;/code&gt;. Weilin Du replied the same evening to say the soft feature freeze had already closed &lt;code&gt;8.6&lt;/code&gt; to it. Then Rowan Tommins raised the objection that shaped everything after it, suggesting: "I think it would be better to design something more composable - that is, a way to create a 'lazy array slice', and then accept that in functions which can use it safely." He pointed at Swift, which has types that let you refer to part of an array &lt;strong&gt;without copying any of it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rowan put his objection plainly: "if we add an ArraySlice type then array_search_range would immediately become redundant." Sepehr's answer is that the general thing doesn't exist, and that building it would mean a new type in the engine and updates to potentially hundreds of array functions. Larry Garfield sided with Rowan and suggested shelving it. mickmackusa said he'd never had a professional project that required the function, and put a design question back: "If a PHP array needed a pagination-style search function, should perhaps the data structure be reconsidered?" Rowan then broke his own idea into 3 shippable steps. An optimized &lt;code&gt;ArraySliceIterator&lt;/code&gt; comes first, then &lt;code&gt;iter_search&lt;/code&gt; and &lt;code&gt;iter_any&lt;/code&gt; functions that would work with &lt;strong&gt;any&lt;/strong&gt; iterator, and possibly syntax after that. He wrote the first 2 in under 20 lines each, and a polyfill for Sepehr's function on top. Sepehr added a Polyfill section to the RFC, and Rowan pointed out that the version now on the wiki calls &lt;code&gt;array_slice()&lt;/code&gt;, which copies the array. &lt;em&gt;That is the cost the proposal exists to avoid.&lt;/em&gt; As of this recording the RFC is still a draft, still targeting &lt;code&gt;8.6&lt;/code&gt;, and Rowan's GitHub review found the implementation still walking the entire array.&lt;/p&gt;

&lt;p&gt;Something small and irritating went to the list on Saturday. 4 functions take an extension name, and &lt;code&gt;ini_get_all()&lt;/code&gt; is the only one of them that's &lt;strong&gt;case-sensitive&lt;/strong&gt;. Weilin Du opened a pull request to bring it into line with &lt;code&gt;extension_loaded()&lt;/code&gt;, &lt;code&gt;phpversion()&lt;/code&gt; and &lt;code&gt;get_extension_funcs()&lt;/code&gt;. Sjoerd Langkemper agreed it should be consistent, then asked the question that turned the thread around: "Another option to make them consistent would be to have them all case-sensitive. Have you considered that?" &lt;em&gt;He also spotted that the manual's lowercase-only note for &lt;code&gt;get_extension_funcs()&lt;/code&gt; isn't true. AllenJB traced it to a change back in PHP &lt;code&gt;5.0.4&lt;/code&gt;, and there's a docs issue open now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Daniel Scherzer objected, arguing PHP should make all 4 case-sensitive instead, since BC breaks have an established path through deprecation and removal in the next major version. Weilin agreed and &lt;strong&gt;withdrew his own proposal&lt;/strong&gt;, saying he'd add extension-name case sensitivity to the &lt;code&gt;8.7&lt;/code&gt; deprecations RFC instead. And then 3 people showed up to argue for the thing he'd just withdrawn. Aleksander Machniak listed &lt;code&gt;PDO&lt;/code&gt;, &lt;code&gt;SimpleXML&lt;/code&gt;, &lt;code&gt;Xdebug&lt;/code&gt; and &lt;code&gt;swoole&lt;/code&gt;, and asked why a developer should have to know the exact casing of each one. Matteo Beccati called the alternative "one of those useless BC breaks that make the user experience worse instead of improving it." He also noted that &lt;code&gt;composer.json&lt;/code&gt; generally writes its extension requirements in lowercase. Juliette Reinders Folmer had the last word, with the practical cost. Build a version list with &lt;code&gt;get_loaded_extensions()&lt;/code&gt; and you'd have to lowercase every name before &lt;code&gt;phpversion()&lt;/code&gt; would take it. Nobody has replied to her yet.&lt;/p&gt;

&lt;p&gt;Henrik Skov posted an idea on Tuesday morning. He wants a &lt;code&gt;params&lt;/code&gt; keyword that lets you name a block of arguments once and spread it into a call, so a 6-argument cookie call collapses to 1 line. One of the 6 arguments in his own example is labelled "Can't remember what this is." AllenJB replied 22 minutes later that PHP already does this with named arguments and array unpacking. Henrik came back with the actual requirement. He wants the expressions evaluated &lt;strong&gt;when the call happens&lt;/strong&gt;, not when the compiler first sees them, so a &lt;code&gt;time()&lt;/code&gt; in there stays fresh. Kamil Tekiela suggested making it a type. Henrik said it wasn't worthy of a full class. Larry Garfield answered: "I really don't understand why people keep saying this. What makes something 'unworthy' of being a class? ... A data construct doesn't need to be as righteous as Thor to be 'worthy' of a class." Then he named the thing Henrik was reaching for: a lazy value, evaluated only when it's read. Henrik agreed that was what he'd been after all along. &lt;em&gt;2 unrelated threads this week, and both of them landed on the word "lazy." Nobody involved was.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Jens has been writing PHP since around the time version 2 was in use, and on Thursday he posted about something beyond a documentation fix for the first time. Why does &lt;code&gt;var_export()&lt;/code&gt; still print the long &lt;code&gt;array(...)&lt;/code&gt; syntax, when that output gets pasted around by PhpStorm and Xdebug all day? There's an RFC for changing it that has been sitting there for 6 years. Larry Garfield linked 3 previous rounds of the same conversation without taking a side. Kamil Tekiela offered the explanation: "IMHO, the two main reasons for the lack of change are apathy and lack of agreement as to what exactly the better syntax is." The constraint he describes is that &lt;code&gt;var_export()&lt;/code&gt; is meant to be &lt;strong&gt;PHP-executable first&lt;/strong&gt; and human-readable second, so as long as the output runs, the function is doing its job. He also named the trap. Change one thing about that output and everyone arrives with everything else they'd like fixed — &lt;em&gt;which is a fair summary of the last 6 years.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Otar Chekurishvili posted a pre-RFC on Monday for 2 opt-in flags in the &lt;code&gt;json&lt;/code&gt; extension, targeting &lt;code&gt;8.7&lt;/code&gt;. One is &lt;code&gt;JSON_ALLOW_COMMENTS&lt;/code&gt; and the other is &lt;code&gt;JSON_ALLOW_TRAILING_COMMAS&lt;/code&gt;, and both would be accepted by &lt;code&gt;json_decode()&lt;/code&gt; and &lt;code&gt;json_validate()&lt;/code&gt;. &lt;strong&gt;Strict JSON stays the default.&lt;/strong&gt; Trailing commas allow exactly 1 after the last element. &lt;em&gt;That's 1 more than JSON allows today, and exactly as many as most of us have typed by accident.&lt;/em&gt; He's proposing 2 separate primary votes so either flag can pass on its own, and says the implementation reuses the existing scanner and grammar rather than preprocessing the input, so error positions survive intact. Larry Garfield asked: "Does this essentially mean JSON5 support? If so, just call it that." Anton Smirnov corrected the name. What's proposed is Microsoft's JSONC, or Nigel Tao's JWCC; real JSON5 would also need single quotes, unquoted keys, infinities and multiline strings, among other things. No reply from Otar yet.&lt;/p&gt;

&lt;p&gt;Alexander Lisachenko wants to fix something about PHP's FFI. Every C value it hands back comes back as the same final class, &lt;code&gt;FFI\CData&lt;/code&gt;. A string pointer, a zval pointer and a raw &lt;code&gt;char&lt;/code&gt; pointer are all the same type to PHP. &lt;em&gt;Which makes FFI strongly typed, in the sense that there is 1 type.&lt;/em&gt; He described the consequence bluntly: "no C struct a binding works with can ever be described to static analysis or an IDE, and CData being final closes off every userland workaround." To get any static typing in his own library he ships 4 separate workarounds, and &lt;code&gt;instanceof&lt;/code&gt; still doesn't work. His proposal is an opt-in class map passed as an options array, in the same shape as &lt;code&gt;SoapClient&lt;/code&gt; takes one, so a registered C type comes back as &lt;strong&gt;your&lt;/strong&gt; class instead of bare &lt;code&gt;CData&lt;/code&gt;. He says it stays inside the &lt;code&gt;ffi&lt;/code&gt; extension and costs nothing when unused. Bob Weinand's is the only reply so far, asking for patience: "don't rush this, write a RFC, and check what actually feels good to use and read."&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;8.6&lt;/code&gt; deprecation vote closed 9 days ago, and one of the items that passed deprecates &lt;code&gt;SplFileObject&lt;/code&gt;'s CSV methods. In the last days of voting Takuya Aramaki pointed out that the &lt;code&gt;READ_CSV&lt;/code&gt; flag was left out, and that &lt;code&gt;setCsvControl()&lt;/code&gt; is the only thing that can configure it — so removing the method leaves the flag stuck on its defaults. Nobody answered him. On Saturday Robert Humphries picked it back up. His reading is that leaving &lt;code&gt;READ_CSV&lt;/code&gt; in place does resolve the original issue, but doesn't achieve the goal of getting CSV handling &lt;strong&gt;out&lt;/strong&gt; of SPL. By his reading of the code there's a second problem. When the default escape character for &lt;code&gt;fgetcsv()&lt;/code&gt; changes, code using &lt;code&gt;READ_CSV&lt;/code&gt; will behave differently across PHP versions with no way to pin it. His conclusion is that &lt;code&gt;READ_CSV&lt;/code&gt; needs deprecating too, and that a migration path should have been part of the proposal. &lt;em&gt;Still no reply.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Eloi Montañés asked the list on Saturday whether abstract class constants are worth an RFC. The idea is to let an abstract class or a trait declare a constant with the &lt;code&gt;abstract&lt;/code&gt; keyword, and require implementers to define one. His examples are a base class that requires a table name and a trait that requires a log tag — things you want fixed at author time rather than changeable at runtime. He points back to a &lt;strong&gt;2017&lt;/strong&gt; thread on the same idea, from before typed constants landed. John Bafford suggested interfaces should get the same treatment, since an interface can already require a property but has no way to require a constant or a static one. Eloi was persuaded, and this morning asked why interfaces have never supported static properties. Larry Garfield answered from experience. He says they considered it while building interface property support for property hooks, and passed for 2 reasons. Object properties cover almost every case and attributes cover the rest, and "static properties are way harder to deal with in the engine, because reasons." &lt;em&gt;He also left a parser problem on the table.&lt;/em&gt; Interfaces already support ordinary constants, so an &lt;code&gt;abstract&lt;/code&gt; keyword may be necessary there regardless.&lt;/p&gt;

&lt;p&gt;Quick hits. Sjoerd Langkemper gave its own page to a proposal that missed the &lt;code&gt;8.6&lt;/code&gt; window. &lt;code&gt;bindec()&lt;/code&gt;, &lt;code&gt;octdec()&lt;/code&gt;, &lt;code&gt;hexdec()&lt;/code&gt; and &lt;code&gt;base_convert()&lt;/code&gt; would throw a &lt;code&gt;ValueError&lt;/code&gt; when you hand them characters that aren't valid for the base, instead of the deprecation notice they've emitted since &lt;code&gt;7.4&lt;/code&gt;. Today &lt;code&gt;hexdec('z')&lt;/code&gt; returns 0. It targets &lt;code&gt;8.7&lt;/code&gt; and has no replies yet. Weilin Du also asked for feedback on tightening 2 INI settings. Right now &lt;code&gt;upload_max_filesize=1GB&lt;/code&gt; can be read as &lt;strong&gt;1 byte&lt;/strong&gt; by the request parser while &lt;code&gt;ini_get()&lt;/code&gt; still reports the string you wrote, &lt;em&gt;which is a spectacular way to lose an afternoon&lt;/em&gt;. His change warns and falls back to the default instead. Jakub Zelenka reads that as incomplete wording in the BC policy rather than a real break. Osama Aldemeery is parking his &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt; RFC until early September, writing: "This has gone quiet, which I'm taking as the freeze crunch and people being busy, not as everyone being fine with it as-is." And 3 releases went out on Thursday. Joe Ferguson shipped PHP &lt;code&gt;8.6.0&lt;/code&gt; beta 1, with beta 2 due on August 27, and Calvin Buckley and Daniel Scherzer followed with &lt;code&gt;8.4.25&lt;/code&gt; and &lt;code&gt;8.5.10&lt;/code&gt; RC 1. &lt;em&gt;Matteo Beccati mentioned in passing that the &lt;code&gt;8.6&lt;/code&gt; branch should be cut on September 22.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here's the week in short. &lt;strong&gt;No RFC went to a vote&lt;/strong&gt;, and nothing is in the voting phase at all. A new contributor's &lt;code&gt;array_search_range()&lt;/code&gt; ran into a counter-proposal for a general lazy array slice, and is still a draft. A one-line inconsistency in &lt;code&gt;ini_get_all()&lt;/code&gt; turned into a question about case sensitivity that ended with the author withdrawing a proposal 3 other people then defended. A &lt;code&gt;params&lt;/code&gt; keyword got talked into being a lazy value. Abstract class constants may pick up interfaces. And PHP &lt;code&gt;8.6&lt;/code&gt; beta 1 is out, with beta 2 due &lt;em&gt;next week.&lt;/em&gt; Links to every thread are below. Thanks again to &lt;code&gt;Ballast.now&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | August 12, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Thu, 13 Aug 2026 19:55:59 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-august-12-2026-3ejb</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-august-12-2026-3ejb</guid>
      <description>&lt;p&gt;happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;11 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; Your team adopted AI. Everyone says it made them faster. Ballast measures whether that's &lt;strong&gt;true&lt;/strong&gt; — how much faster you're &lt;em&gt;actually&lt;/em&gt; going, and whether what you ship is still holding up. 6.75 times the commits. Durability down 19 points. &lt;em&gt;Now you know.&lt;/em&gt; It runs on &lt;strong&gt;your&lt;/strong&gt; machine. It reads your git history, not your source — your code never goes anywhere, and nothing here is scored by a model. It's arithmetic you could check by hand. Setting it up isn't your job either. Paste one prompt into your coding agent and it does the whole thing. Find out for &lt;strong&gt;free&lt;/strong&gt; today. &lt;code&gt;ballast.now&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One correction before the top story. Last week we described the &lt;code&gt;list()&lt;/code&gt; deprecation vote as &lt;strong&gt;deadlocked&lt;/strong&gt; at 21 to 21. Derick Rethans pointed out that's the wrong word — a deadlock is when something is stuck and can't proceed. The vote wasn't stuck. It was simply &lt;strong&gt;tied&lt;/strong&gt;, and voting carried on to the finish. He's right, we'll say it properly this week — and thanks, Derick, for keeping us precise.&lt;/p&gt;

&lt;p&gt;This week's top story: the verdict is in on the 35-ballot mass deprecation vote for PHP &lt;code&gt;8.6&lt;/code&gt;. Voting closed Monday at 13:00 UTC, and Gina P. Banyard posted the full results — 31 proposals accepted, 4 rejected. Start with the 4 that fell. Deprecating &lt;code&gt;list()&lt;/code&gt; finished on a flat tie — 23 to 23, with 1 abstention — exactly 50 percent, nowhere near two-thirds. Reserving &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;out&lt;/code&gt;, and &lt;code&gt;inout&lt;/code&gt; failed at 8 to 21. The gettext &lt;code&gt;_()&lt;/code&gt; alias survived at 10 to 22. And the &lt;code&gt;dechunk&lt;/code&gt; filter — the item disputed all through the voting window — finished at 18 to 15 with 12 abstentions, 54.5 percent, and stays in the language.&lt;/p&gt;

&lt;p&gt;Now last week's cliffhangers. Reserving &lt;code&gt;let&lt;/code&gt; was balanced exactly on the two-thirds line 7 days ago — it found its margin and passed at 24 to 11, with 9 abstentions — 68.6 percent. Reserving &lt;code&gt;is&lt;/code&gt; passed at 29 to 10, despite Rowan Tommins's warning about the Hamcrest testing library and its 500 million installs. And the &lt;code&gt;define()&lt;/code&gt; case-insensitivity flag — the item Kamil Tekiela wanted simply deleted instead — passed without a single no vote, at 41 to 0. The vote also drew one final flag on its way out. Takuya Aramaki wrote in Friday, opening with: "Apologies for bringing this up so close to the end of the vote." His concern is the &lt;code&gt;SplFileObject&lt;/code&gt; CSV methods item. He laid out the inconsistency plainly: "setCsvControl() is the only way to configure the delimiter, enclosure and escape character used by READ_CSV; the constructor does not accept them. If setCsvControl() is removed in PHP 9 while READ_CSV remains, READ_CSV is permanently locked to its defaults and tab-separated files can no longer be read through it." He asked that &lt;code&gt;READ_CSV&lt;/code&gt; be deprecated alongside the methods, or that &lt;code&gt;setCsvControl()&lt;/code&gt; stay until a replacement exists. No answer yet — and the item passed at 25 to 5, with 15 abstentions.&lt;/p&gt;

&lt;p&gt;The final 3 ballots of the &lt;code&gt;8.6&lt;/code&gt; season are settled, and they went 2 and 1. Caleb White's pipe assignment operator — &lt;code&gt;|&amp;gt;=&lt;/code&gt; — was declined. The vote closed Tuesday morning at 14 yes, 12 no, and 7 abstentions — 53.8 percent, short of the two-thirds it needed. It had climbed all the way from dead even, but never got over the bar. Nick Sdot's readonly property defaults went the other way entirely. It closed Friday at 24 to 0, with 5 abstentions — it never drew a single no vote in 2 weeks. And Khaled Alam's const object property writes closed Saturday. He announced the result Sunday: accepted, 17 to 2 with 6 abstentions — 89.5 percent. With those 3 in the books alongside &lt;code&gt;Duration&lt;/code&gt; and the deprecations, PHP &lt;code&gt;8.6&lt;/code&gt;'s RFC season is &lt;strong&gt;over&lt;/strong&gt; — the beta 1 tag brings the soft freeze this week, and beta 1 itself lands Thursday.&lt;/p&gt;

&lt;p&gt;Ilija Tovilo posted a very late update to an RFC that passed 24 to 0 back in March. The closure optimizations RFC promised 2 things: a cache for stateless closures, and &lt;strong&gt;inference&lt;/strong&gt; — the engine automatically detecting closures that never touch &lt;code&gt;$this&lt;/code&gt; and treating them as static. That second part is out. Ilija found an edge case where a closure violates none of the RFC's inference rules and still makes an instance call — pass a callable &lt;strong&gt;string&lt;/strong&gt; like "Foo::instanceCall" into an &lt;code&gt;array_map&lt;/code&gt; inside the closure, and the rules never see it. He owned it completely, writing: "I failed to consider this case, and sadly this is not easy to detect via a new rule. For this reason, I have decided to omit static closure inference from the implementation and only merge the stateless closure cache." The practical takeaway: the cache — which carries most of the performance win — still ships in &lt;code&gt;8.6&lt;/code&gt;, but the engine won't infer anything for you. Mark your closures &lt;code&gt;static&lt;/code&gt; yourself and you get the full benefit.&lt;/p&gt;

&lt;p&gt;Ignace Nyamagana Butera's data encoding API — the base64, base16, base58, and base85 family — got a detailed security review from Sjoerd Langkemper on Monday. He's for it, noting: "the current base64_decode is very tolerant towards invalid input, causing both functional and security problems." Along the way he found errors in the RFC's own code examples, corrected them in a companion repository, and flagged a signature mismatch in the base85 functions. He's skeptical of one feature — the optional constant-time mode — arguing: "Constant-time algorithms are pretty difficult to develop and maintain", and suggesting PHP hand that job to libsodium or openssl instead. He also built a working implementation to test the API, introducing it with unusual billing: "LLMs and I have created an implementation here." &lt;em&gt;And in the research footnotes:&lt;/em&gt; he spent real time evaluating the base85 variant from RFC 1924 before discovering: "that RFC was submitted in jest as an April fool's joke." Ignace thanked him for the remarks and is holding all implementation work until after &lt;code&gt;8.6&lt;/code&gt; ships — Tim Düsterhus, who's building it, is busy with the release.&lt;/p&gt;

&lt;p&gt;The first RFC aimed past the freeze is already here. Weilin Du proposed &lt;code&gt;IntlRelativeDateTimeFormatter&lt;/code&gt; on Friday, targeting PHP &lt;code&gt;8.7&lt;/code&gt; — a wrapper for ICU's locale-aware relative time, the "in 3 days" and "last Sunday" strings, in every language ICU speaks. Ignace asked the obvious question: &lt;code&gt;8.6&lt;/code&gt; just gained a &lt;code&gt;Duration&lt;/code&gt; class — shouldn't this accept one? Weilin argued the types don't fit, since Duration is stopwatch time and this formatter wants a unit: "We don't know how to deal with 90 minutes here. It can be 90 minutes or 1.5 hour." And weekdays, months, and quarters aren't durations at all. David Carlier pushed for enums and a namespace; Weilin is keeping class constants and the global &lt;code&gt;Intl&lt;/code&gt; prefix for consistency with the existing &lt;code&gt;intl&lt;/code&gt; extension, and filed modernization under future scope. One suggestion did land immediately: by Saturday the constructor had grown an optional &lt;code&gt;NumberFormatter&lt;/code&gt; parameter, with Weilin reporting: "The implementation is way more smoother than I expected."&lt;/p&gt;

&lt;p&gt;The generics conversation is parked until September — the implementations aren't waiting. Carlos Granados posted a pre-RFC Thursday: he took Rob Landers's experimental &lt;strong&gt;reified&lt;/strong&gt; branch — built on Seifeddine Gmati's bound-erased proposal — and worked it into something complete, with a full write-up of the changes and findings. He argued the original deserved better: "I think that this was a very valid proposal that should have been explored in more detail." Rob's reply was brief, noting: "You really should have reached out instead of a working in isolation. Join us in discord, the proposal is delayed until September-ish." Which raised a practical question — &lt;em&gt;what&lt;/em&gt; Discord? Rob posted channel links; Carlos, a Discord newcomer, still couldn't get in. Larry Garfield finally supplied the address, &lt;code&gt;phpc.chat&lt;/code&gt;, with a review: "The PHP Community chat is unofficial, but lately it's where the big names are hanging out, including a lot of Internals regulars. Beware, the Internals channel is annoyingly noisy and has a hard time staying on topic." &lt;em&gt;And I can personally vouch for that statement.&lt;/em&gt; Then Monday brought a &lt;strong&gt;third&lt;/strong&gt; generics experiment: Alexander Lisachenko shared a userland proof-of-concept — a Composer package — where specialized classes share the compiled method bodies, so each specialization costs one small structure per method instead of a full copy of the opcodes.&lt;/p&gt;

&lt;p&gt;Liam Hammett's native markup expressions RFC — JSX-style HTML in PHP — got the one review nobody else could write. T.J. L, who maintains the XHP extension — the long-running ancestor of this exact idea — posted his &lt;strong&gt;first message ever&lt;/strong&gt; to internals. He corrected one detail in the RFC's history section, then confirmed its central argument from experience: he wrote: "While it is technically possible for extensions to add new syntax, it is unreasonable to expect tools to be aware of that syntax. I can absolutely confirm that the biggest point of friction in using XHP today is the fact that static analysis tools like psalm or phpstan can't analyze files, code using XHP cannot be formatted or linted with php-cs-fixer..." In other words, the case for putting markup in core, signed by the person who spent years doing it the other way. He also brought 3 asks: context passing through a component tree without threading attributes; a ruling on inline SVG, which leans on XML features the HTML-only RFC excludes; and a note that dropping per-tag objects means no runtime validation of tags and attributes — XHP's original selling point — which he says JSX gets away with "in large part because of the Typescript ecosystem". No response from Liam yet.&lt;/p&gt;

&lt;p&gt;Quick hits. Juris Evertovskis ran a temperature check on &lt;code&gt;isset&lt;/code&gt;: expressions &lt;strong&gt;inside&lt;/strong&gt; the square brackets still throw warnings and deprecations even though &lt;code&gt;isset&lt;/code&gt; silences everything else, and he put his conclusion bluntly: "To me it looks like isset is not doing its job." He'd like the brackets silenced too — no replies yet. The did-you-mean error suggestions are officially not being rushed: Jorg Sowa announced: "I will finish it after feature freeze", and Larry Garfield agreed, adding: "If it doesn't happen until 2027, that's OK." Jorg also picked up his VCS account this week — approved by Ilija Tovilo — with the &lt;code&gt;session&lt;/code&gt; extension in his sights. And the list has a new face: Sepehr Mahmoudi introduced himself Tuesday with a pull request already open and an &lt;code&gt;array_search_range&lt;/code&gt; idea in hand; mickmackusa pointed him at &lt;code&gt;array_find_key()&lt;/code&gt; and suggested making the case on the list before writing more code, and Yuya Hamada thanked him for the contribution.&lt;/p&gt;

&lt;p&gt;So that's the week: the 35-ballot deprecation vote landed 31 to 4 — &lt;code&gt;list()&lt;/code&gt; survives on a flat tie, &lt;code&gt;dechunk&lt;/code&gt; survives, and &lt;code&gt;let&lt;/code&gt; squeaked through; the pipe assignment operator was declined while readonly defaults and const object writes made it in, closing out &lt;code&gt;8.6&lt;/code&gt;'s RFC season; closure inference got walked back to just the cache; and the first &lt;code&gt;8.7&lt;/code&gt; RFC is already on the table. Links to every thread are below. Thanks again to &lt;code&gt;Ballast.now&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | Aug 05, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Wed, 05 Aug 2026 21:19:09 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-aug-05-2026-3oc3</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-aug-05-2026-3oc3</guid>
      <description>&lt;p&gt;Hello world, it's Wednesday, August 5, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;13 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; This week's episode is brought to you by &lt;strong&gt;Tideways&lt;/strong&gt;. When a request is slow in production, Tideways takes you from symptom to root cause in minutes, with profiling, tracing, and monitoring built &lt;strong&gt;specifically&lt;/strong&gt; for PHP. It installs in 5 minutes, there's no credit card required, and it's hosted in Germany. Start your free trial at &lt;code&gt;tideways.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This week's top story: the mass deprecation vote for PHP &lt;code&gt;8.6&lt;/code&gt; is in its final week. All 35 ballots close &lt;strong&gt;Monday&lt;/strong&gt;, August 10, and Gina P. Banyard posted the 1-week reminder so nobody gets caught out. Most of the 35 are passing comfortably. The interesting ones are the holdouts. &lt;code&gt;list()&lt;/code&gt; is now deadlocked at 21 to 21 — a flat tie, nowhere near the 2/3 it needs. Reserving &lt;code&gt;let&lt;/code&gt; stands at 22 to 11, which is &lt;em&gt;exactly&lt;/em&gt; two-thirds — a single vote in either column decides it. The &lt;code&gt;dechunk&lt;/code&gt; filter sits at 17 to 15 — still well short. The gettext &lt;code&gt;_()&lt;/code&gt; alias is failing at 9 to 20, and reserving &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;out&lt;/code&gt;, and &lt;code&gt;inout&lt;/code&gt; is failing at 7 to 20, with 12 abstentions. Everything else you'd recognize from the list — the object-parameter cleanups, the &lt;code&gt;is_double()&lt;/code&gt; family, &lt;code&gt;spl_classes()&lt;/code&gt; — is cruising toward the finish.&lt;/p&gt;

&lt;p&gt;The thread itself turned into a corrections desk this week. Calvin Buckley relayed a note from Nora, who isn't on the list, pointing out: "The text for the metaphone deprecation isn't fully right. It lists \"linguistics\" as a replacement package, but that one actually uses php-src's metaphone internally too." Weilin Du, who proposed that item, conceded the docs point while standing by the idea, writing: "My point in deprecating it is to stop using ancient metaphone algo as a whole." Voters seem unbothered — metaphone stands at 19 to 6, with 15 abstentions. Rowan Tommins raised a bigger flag on reserving &lt;code&gt;is&lt;/code&gt;: it would collide with Hamcrest, the test assertion framework, whose PHP port has &lt;strong&gt;500 million&lt;/strong&gt; Packagist installs and an &lt;code&gt;is()&lt;/code&gt; function all over its README. He urged: "I think we should think very carefully whether we can avoid disrupting that much code." So far the voters disagree — &lt;code&gt;is&lt;/code&gt; stands at 26 to 9. Meanwhile Sjoerd Langkemper, who proposed the contested &lt;code&gt;dechunk&lt;/code&gt; item, stepped back from the argument with unusual candor, writing: "the discussion phase wasn't properly completed yet, and I did a poor job in merging all opinions into a RFC proposal." He'd rather let the voting play out — and he closed by asking Jakub Zelenka, who led last week's objections, whether anyone could help lighten his workload. And Kamil Tekiela's question from last week — why deprecate &lt;code&gt;define()&lt;/code&gt;'s dead flag instead of just deleting the parameter — got its answer: Tim Düsterhus pointed out that deleting it isn't silent, since extra arguments throw an &lt;code&gt;ArgumentCountError&lt;/code&gt;, and concluded: "Making it explicit (and deciding) that the parameter will go in PHP 9 is a good thing."&lt;/p&gt;

&lt;p&gt;Function autoloading — Paul M. Jones's 5th-generation attempt — went to a vote Thursday afternoon. It lasted about a day. Matteo Beccati opened the replies with praise and a caveat, calling it "the best autoloading proposal up to date" but adding: "Perhaps I'm biased as RM, but last minute RFCs are making me nervous, I hope you understand." Then Tim Düsterhus spotted the procedural problem, writing: "In fact the start of the vote is in violation of our policy, since there was no \"intent to vote\" message in the last 7 days." Paul's intent notice was 2 weeks old, and a July 15 revision had reset the clock besides. Paul took it entirely in stride, replying: "Ah so -- my apologies. I'll pull the vote and wait for ... looks like ~6 weeks?" For the record, the widget stood at 2 yes to 11 no when he pulled it — so the pause may be a mercy. Tim ran the math: cancellation carries a 2-week cooldown, so a mid-August reopen is &lt;em&gt;technically&lt;/em&gt; possible, but he judged it "likely not useful to reopen the vote without making further changes" — and offered one: resolve namespaced functions &lt;strong&gt;before&lt;/strong&gt; falling back to globals. Rowan Tommins countered that the fallback path makes that slow, and pointed instead at Michael's namespace-autoloader idea — loading a whole namespace's functions at once — calling it "a much cleaner way forward". Paul is unbothered, saying he'll "come back to it after 8.6 is fully out the door." That's the 2nd vote in 2 weeks pulled by its own author over the intent-to-vote rule.&lt;/p&gt;

&lt;p&gt;Seifeddine Gmati's literal scalar types will &lt;strong&gt;not&lt;/strong&gt; be reopening. His retraction last week came with a plan to re-vote; this week he canceled that too, after asking the release manager exactly where the freeze line sits. The answer: the effective cutoff isn't the beta 1 announcement on August 13, it's the creation of the beta 1 &lt;strong&gt;tag&lt;/strong&gt; on August 11 — and a vote opened now would close after the tag exists. So the RFC is retargeted to the next PHP version, text final, intent withdrawn. Matteo Beccati apologized for the ambiguity, admitting his emails "were pointing the 13th as deadline for RFCs", and went further: "having RFCs end voting so close to the feature freeze is a terrible idea as it gives very little wiggle room in case something unexpected comes out ...". Seifeddine took it well, noting his own retarget email had already started a 14-day cooldown anyway — in his words, "8.6 was out of reach the moment that email hit the list." Pierre Joye pushed back on the caution, arguing: "beta phases exist exactly for this reason. wider base of testers." He also vented about the calendar: between the new policies and the Christmas quiet period, "the time left in a year is low, very low, now." And with the clock pressure gone, Tim Düsterhus gave the RFC one more read and found just one loose end — the matching-semantics vote has no explicit tie-breaker — and otherwise signed off: "No further comments to the contents of the actual proposal."&lt;/p&gt;

&lt;p&gt;Two carryover votes are now in the books, and both passed emphatically. The &lt;code&gt;Time\Duration&lt;/code&gt; class closed Friday. The primary finished at 35 to 1, with 2 abstentions — 97 percent. The naming question went to full method names — &lt;code&gt;multiplyBy&lt;/code&gt;, &lt;code&gt;divideBy&lt;/code&gt;, &lt;code&gt;negate&lt;/code&gt;, &lt;code&gt;absolute&lt;/code&gt; — at 30 to 2. So PHP &lt;code&gt;8.6&lt;/code&gt; officially gets a &lt;code&gt;Duration&lt;/code&gt; class. The minimum-supported-versions RFC closed Thursday. Requiring &lt;code&gt;autoconf&lt;/code&gt; 2.71 passed at 27 to 2, with 5 abstentions, and requiring &lt;code&gt;COM_RESET_CONNECTION&lt;/code&gt; passed clean at 26 to nothing. That second one has a coda. Alexander Kurilo — who'd argued during the vote that the connection-reset change carries an undisclosed BC break — requested RFC karma on Saturday to propose making the new behavior optional. Ilija Tovilo granted it Tuesday, with a reality check, noting: "the vote result was quite clear, and the time for another RFC discussion + vote has run out." He left any next step to the release managers.&lt;/p&gt;

&lt;p&gt;Three ballots are still open, and none of them drew a single email this week — the voting is doing the talking. Caleb White's pipe assignment operator closes next Tuesday. As of recording it stands at 12 yes, 10 no, 6 abstaining — 54.5 percent, needing two-thirds. It has climbed from dead even, but the gap is real. Nick Sdot's readonly property defaults closes &lt;strong&gt;Friday&lt;/strong&gt; morning. It still hasn't drawn a single no — 22 to nothing, with 5 abstentions. And Khaled Alam's const object property writes closes Saturday. That one sits at 14 to 2, comfortably above the line.&lt;/p&gt;

&lt;p&gt;A new discussion opened Saturday: Sjoerd Langkemper wants to stop &lt;code&gt;curl_setopt&lt;/code&gt; from leaking secrets into stack traces. The problem is that one function sets everything, and he laid it out cleanly: "The value for CURLOPT_PASSWORD is likely sensitive, the value for CURLOPT_RETURNTRANSFER is not, and CURLOPT_URL may be sensitive sometimes." He brought 3 options, 2 of them with working pull requests: blanket-mark the value as sensitive and lose debug info; teach &lt;code&gt;curl_setopt&lt;/code&gt; which options are secret, at an engine-level performance cost; or make callers wrap secrets in a &lt;code&gt;SensitiveParameterValue&lt;/code&gt;. Iliya Miroslavov Iliev questioned the premise, arguing stack traces shouldn't be reachable in production at all — and asked how you'd debug a wrong password you can no longer see. Matthew Weier O'Phinney leaned opt-in, warning that automatic detection "will be difficult and a game of whack-a-mole", since options carry arbitrary headers and content — and floated letting the engine accept sensitive-value wrappers on &lt;strong&gt;any&lt;/strong&gt; function call, so callers could opt in regardless of the signature.&lt;/p&gt;

&lt;p&gt;Jorg Sowa wants PHP's undefined-function errors to answer back. His pull request adds "did you mean" suggestions — call &lt;code&gt;defined()&lt;/code&gt; when you meant &lt;code&gt;define()&lt;/code&gt;, and the error names the function you were probably reaching for, the way Python and Ruby already do. His question to the list was procedural: does this need an RFC, or is PR consensus enough? Sjoerd Langkemper answered with the policy exempting error messages from the BC rules, noting: "rephrasing error messages is not subject to the backwards compatibility break policy" — and he's in favor. Matteo Beccati liked it too, suggested Python's exact shape for the message, and nudged the list for feedback given the freeze is days away. If the sentiment holds, Jorg wants to extend it to methods, classes, and constants next. The only debate so far is punctuation — how many brackets and question marks one error message can carry.&lt;/p&gt;

&lt;p&gt;The generics conversation is officially on hold until after &lt;code&gt;8.6&lt;/code&gt; ships — which isn't stopping anyone. Henrik Skov wrote in asking for generics to be &lt;strong&gt;opt-in&lt;/strong&gt;, worrying: "adding reified generics will just make it even slower." His sketch: type-erased generics hiding inside comment syntax, checked by IDE plugins or a C extension, with the engine substituting &lt;code&gt;mixed&lt;/code&gt; at compile time. Holly Schilling's reply opened like a sermon: "Have you heard the good word of Monomorphized Generics? Performance matches standard typed code." And she restated the schedule — generics talk waits until September or October, &lt;em&gt;so it doesn't bury the 8.6 release work&lt;/em&gt; — with her inbox open in the meantime.&lt;/p&gt;

&lt;p&gt;Osama Aldemeery's &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt; RFC got its first real design review. Bernard Scharp asked whether compile failures and runtime failures deserve &lt;strong&gt;separate&lt;/strong&gt; exception classes. Rowan Tommins supplied the rulebook: PHP's throwables policy says extension exceptions extend the extension's own base class, never the SPL ones. Osama's position is one &lt;code&gt;PregException&lt;/code&gt;, &lt;em&gt;with the door open&lt;/em&gt; — and he had a concrete reason: today, the useful detail of a compile failure lives only in the warning text, so a dedicated compilation exception "would carry \"Internal error\" and little else". That connects to Christian Schneider's other catch: under the flag, a bad pattern raises &lt;strong&gt;both&lt;/strong&gt; the warning and the exception. Osama confirmed it, and defended it as the honest trade — the warning is where the detail is — while agreeing that "exception-instead-of-warning is the cleaner end state" once the exception can carry that detail itself.&lt;/p&gt;

&lt;p&gt;Quick hits. Thursday was patch day: security releases landed across 4 branches at once — &lt;code&gt;8.2.33&lt;/code&gt;, &lt;code&gt;8.3.33&lt;/code&gt;, &lt;code&gt;8.4.24&lt;/code&gt;, and &lt;code&gt;8.5.9&lt;/code&gt; — upgrade when you can. The same day brought PHP &lt;code&gt;8.6.0alpha3&lt;/code&gt;, an early test release. And the &lt;code&gt;8.6&lt;/code&gt; release managers posted the formal 1-week warning: the soft freeze hits when the beta 1 tag is created &lt;strong&gt;next Tuesday&lt;/strong&gt;, August 11, beta 1 itself lands Thursday the 13th, every &lt;code&gt;8.6&lt;/code&gt; RFC vote must be closed before then, and the hard freeze follows at RC 1 on September 22.&lt;/p&gt;

&lt;p&gt;So that's the week: the 35-ballot deprecation vote closes Monday with &lt;code&gt;list()&lt;/code&gt; deadlocked and &lt;code&gt;let&lt;/code&gt; balanced exactly on the 2/3 line; a function-autoloading vote opened and was pulled inside a day — the 2nd author in 2 weeks to stop his own ballot over the process rules; literal types bowed out of &lt;code&gt;8.6&lt;/code&gt; on its own terms; &lt;code&gt;Duration&lt;/code&gt; and the minimum-versions RFC are officially in; pipe assignment has a week to find its two-thirds; and the freeze arrives Tuesday. Links to every thread are below. Thanks again to &lt;code&gt;Tideways.com&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | July 29, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Sun, 02 Aug 2026 08:07:27 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-july-29-2026-45ge</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-july-29-2026-45ge</guid>
      <description>&lt;p&gt;Hello world, from &lt;strong&gt;Laracon US 2026&lt;/strong&gt; in Boston — it's Wednesday, July 29, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

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

&lt;p&gt;This week's top story: the mass deprecation vote for PHP &lt;code&gt;8.6&lt;/code&gt; is open. Gina P. Banyard opened it Monday, and it's &lt;strong&gt;35&lt;/strong&gt; 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 — &lt;code&gt;mysqli_get_charset()&lt;/code&gt; stands at 34 to &lt;strong&gt;nothing&lt;/strong&gt;, and &lt;code&gt;spl_classes()&lt;/code&gt; at 33 to nothing. But the headliners are moving the other way. &lt;code&gt;list()&lt;/code&gt; — the construct Juliette Reinders Folmer's Packagist scan found over twelve thousand times — stands at 17 yes to 19 &lt;strong&gt;no&lt;/strong&gt;, falling well below the required two-thirds threshold. The gettext &lt;code&gt;_()&lt;/code&gt; alias is failing at 6 to 18. Reserving &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;out&lt;/code&gt;, and &lt;code&gt;inout&lt;/code&gt; is failing at 5 to 16, with 13 abstentions. And &lt;code&gt;let&lt;/code&gt; sits at 17 to 10 — a majority, but still shy of 2/3.&lt;/p&gt;

&lt;p&gt;The loudest argument is about one of the smallest items: the &lt;code&gt;dechunk&lt;/code&gt; stream filter, which as of recording sits at 15 yes to 13 &lt;strong&gt;no&lt;/strong&gt; — a coin-flip vote on a 2/3 question. On Monday, Matteo Beccati was the &lt;em&gt;only&lt;/em&gt; 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 &lt;code&gt;symfony/http-client&lt;/code&gt; — 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 &lt;code&gt;8.2&lt;/code&gt;, 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 &lt;code&gt;8.6&lt;/code&gt; no matter how this ballot goes. Kamil Tekiela, meanwhile, asked a different question — why deprecate &lt;code&gt;define()&lt;/code&gt;'s dead case-insensitive flag at all, when just removing the parameter breaks nobody. So far, nobody has answered him.&lt;/p&gt;

&lt;p&gt;Caleb White's pipe assignment operator, &lt;code&gt;|&amp;gt;=&lt;/code&gt; — 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 &lt;strong&gt;no&lt;/strong&gt;, 3 abstaining, and it needs 2/3. Voting runs to August 11.&lt;/p&gt;

&lt;p&gt;The queue from last week showed up on time. Nick Sdot opened voting on &lt;strong&gt;readonly property defaults&lt;/strong&gt; 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 &lt;strong&gt;const object property writes&lt;/strong&gt; — 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.&lt;/p&gt;

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

&lt;p&gt;Seifeddine Gmati's &lt;strong&gt;literal scalar types&lt;/strong&gt; 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 &lt;em&gt;minor change&lt;/em&gt;, 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 &lt;code&gt;8.7&lt;/code&gt;. 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."&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;gd&lt;/code&gt; 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 &lt;code&gt;8.6&lt;/code&gt; 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 &lt;code&gt;gd&lt;/code&gt; image functions to the deprecation path — on his telling, a warning from the &lt;code&gt;gd&lt;/code&gt; extension itself in &lt;code&gt;8.7&lt;/code&gt;, and gone in PHP 9.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;include&lt;/code&gt;, &lt;code&gt;require&lt;/code&gt;, &lt;code&gt;bzopen()&lt;/code&gt;, &lt;code&gt;finfo_open()&lt;/code&gt; and friends no longer say &lt;strong&gt;which file&lt;/strong&gt; 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 &lt;strong&gt;all&lt;/strong&gt; 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 &lt;code&gt;open_basedir&lt;/code&gt; in effect, one failed &lt;code&gt;include&lt;/code&gt; currently earns you &lt;strong&gt;3&lt;/strong&gt; warnings.&lt;/p&gt;

&lt;p&gt;Edmond of the TrueAsync project turned last week's zero-reply pre-RFC into a real one: &lt;strong&gt;Concurrency Support in the PHP Engine&lt;/strong&gt;. The pitch is deliberately minimal — give the engine a coroutine representation and make the scheduler &lt;em&gt;pluggable&lt;/em&gt; 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 &lt;code&gt;ob_start()&lt;/code&gt; 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 &lt;code&gt;8.6&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Osama Aldemeery — who got his RFC karma in 2 minutes flat last week — shipped the RFC: &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt;. Pass the flag to any &lt;code&gt;preg_*()&lt;/code&gt; call and a PCRE failure throws a catchable &lt;code&gt;PregException&lt;/code&gt;, instead of a warning plus a &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; you have to notice and then chase through &lt;code&gt;preg_last_error()&lt;/code&gt;. It's the same pattern &lt;code&gt;JSON_THROW_ON_ERROR&lt;/code&gt; 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 &lt;em&gt;delivered&lt;/em&gt;. It targets the release &lt;strong&gt;after&lt;/strong&gt; &lt;code&gt;8.6&lt;/code&gt;, 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.&lt;/p&gt;

&lt;p&gt;Quick hits. The &lt;code&gt;8.6&lt;/code&gt; 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 &lt;code&gt;8.6&lt;/code&gt; must be &lt;strong&gt;closed&lt;/strong&gt; before beta 1 — after that, merges need release-manager approval until the hard freeze at RC 1 on September 22. The &lt;code&gt;CURLOPT_HTTPHEADER&lt;/code&gt; 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 &lt;code&gt;snmp&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;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."&lt;/p&gt;

&lt;p&gt;So that's the week: &lt;strong&gt;42&lt;/strong&gt; ballots open at once — the 35 deprecations, with &lt;code&gt;list()&lt;/code&gt; headed for defeat and &lt;code&gt;dechunk&lt;/code&gt; splitting the room; pipe assignment dead even out of the gate; readonly defaults and const writes both comfortably clear; &lt;code&gt;Duration&lt;/code&gt; 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 &lt;code&gt;Tideways.com&lt;/code&gt; and &lt;code&gt;Geocod.io&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | July 22, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Thu, 23 Jul 2026 05:10:06 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-july-22-2026-4gij</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-july-22-2026-4gij</guid>
      <description>&lt;p&gt;Hello world, it's Wednesday, July 22, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;20 stories this week, so let's get into it. &lt;em&gt;But first,&lt;/em&gt; This week's episode is brought to you by &lt;strong&gt;Tideways&lt;/strong&gt;. Slow requests, and no clear reason why? Tideways helps you understand exactly where your PHP application spends its time — profiling, tracing, and monitoring to find and fix bottlenecks &lt;strong&gt;faster&lt;/strong&gt;. And your profiling data stays hosted in Germany — GDPR-friendly by default. Learn more at &lt;code&gt;tideways.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This week's top story: the season's first ballots are open — 2 sets of them — and the early counts are lopsided. Tim Düsterhus opened voting on the &lt;code&gt;Time\Duration&lt;/code&gt; class on Friday with 2 ballots: a primary, needing a 2/3 majority, and a secondary choosing between full and abbreviated method names. As of recording, the primary stands at &lt;strong&gt;23 to 1&lt;/strong&gt;, and full names lead 18 to 1 — so &lt;code&gt;multiplyBy&lt;/code&gt; and &lt;code&gt;divideBy&lt;/code&gt;, not &lt;code&gt;mul&lt;/code&gt; and &lt;code&gt;divBy&lt;/code&gt;. Voting closes July 31. And remember Pierre Joye, who last week was leaning no over &lt;code&gt;fromSeconds()&lt;/code&gt; and its capped nanoseconds argument? This week he closed the loop and voted &lt;strong&gt;yes&lt;/strong&gt;, writing: "We were like ships passing in the night for some of my disagreements. The RFC wiki page did not show the additional constructor for other units, which hence the inconsistency I pointed out for the extra [nanoseconds] argument in fromSecond. They are here, and reduce this down to a lower level of bad APIs, more a pragmatic compromise conciliating different (if not numerous) use cases. Anything can be perfect, or shipped. Choose one." It turns out the per-unit constructors that resolved his objection had been in the RFC all along. His ballot almost didn't register, though — each vote on the wiki is a separate form, and Tim had to point out that you submit each one individually. The count now includes him.&lt;/p&gt;

&lt;p&gt;Before the ballots opened, the &lt;code&gt;Duration&lt;/code&gt; thread picked up a subplot about PHP 9. Holly Schilling — who wrote the class-extensions RFCs we covered last week — announced she's drafting a &lt;strong&gt;Value Structs&lt;/strong&gt; proposal for after the &lt;code&gt;8.6&lt;/code&gt; window, and argued that &lt;code&gt;Duration&lt;/code&gt; would make a better struct than a class, with both ideally landing together in PHP 9. Ilija Tovilo replied by linking his own existing &lt;code&gt;structs-v2&lt;/code&gt; draft and asking whether she was aware of it. She was — she'd read it before drafting her own, and diverged from it on purpose, keeping mutating and non-mutating functionality separate. Tim saw no reason to wait on any of this, saying a draft-stage idea "will take an unknown duration to land - if it ever happens" — &lt;em&gt;his pun, not mine&lt;/em&gt; — and that improvements to the standard library shouldn't queue behind it.&lt;/p&gt;

&lt;p&gt;The week's other live vote came from Eric Norris, who opened balloting Thursday on &lt;strong&gt;minimum supported versions&lt;/strong&gt; for PHP &lt;code&gt;8.6&lt;/code&gt; — also with 2 questions, each needing a 2/3 vote. Requiring autoconf &lt;code&gt;2.71&lt;/code&gt; for builds from git stands at 20 to 3 with 4 abstentions. Requiring &lt;code&gt;COM_RESET_CONNECTION&lt;/code&gt; — which sets a floor of MySQL &lt;code&gt;5.7.3&lt;/code&gt; or MariaDB &lt;code&gt;10.2.4&lt;/code&gt;, so persistent connections actually get reset — stands at &lt;strong&gt;21 to nothing&lt;/strong&gt; with 3 abstentions. Alexander Kurilo arrived after the discussion phase to ask for an opt-in instead, warning that on older databases persistent connections will silently turn non-persistent. Eric noted: "MySQL 5.7.3 is at least a decade old; it was released on December 3rd, 2013." After walking through every opt-out design he could think of, he concluded the right move is to make the correct behavior the default. The 3 no votes on autoconf include Jakub Zelenka, who's worried about building on Red Hat Enterprise Linux 8 and 9 — Tim offered to delay that particular merge to early &lt;code&gt;8.7&lt;/code&gt;. Both votes close July 30.&lt;/p&gt;

&lt;p&gt;Saturday night, Pierre Joye opened the RFC that grew out of the libgd sync we covered last week: &lt;strong&gt;&lt;code&gt;gd&lt;/code&gt; 2.4&lt;/strong&gt;. It's big — 3 pillars. First, syncing the bundled &lt;code&gt;gd&lt;/code&gt; extension with upstream libgd: new codecs like QOI, JPEG XL, and UltraHDR, animated GIF and WebP support, multi-page TIFF, and real metadata handling. Second, an additive object-oriented &lt;code&gt;Gd\&lt;/code&gt; API — codecs with &lt;code&gt;fromFile()&lt;/code&gt; and &lt;code&gt;toStream()&lt;/code&gt;, immutable image info, streaming readers and writers. Third, a brand-new &lt;strong&gt;2D vector canvas&lt;/strong&gt; built on FreeType's rasterizer, with gradients and the full Cairo compositing set. He says the implementation is nearly done, including a security audit. He declared discussion open for 14 days, until August 1 — and that one sentence is where the trouble started.&lt;/p&gt;

&lt;p&gt;Because August 1 plus a 14-day vote lands &lt;em&gt;after&lt;/em&gt; the deadline. Release manager Matteo Beccati was gentle about it, writing: "As much as I like this RFC, I'm afraid it came in a little too late." Jakub Zelenka explained that nobody — release managers included — has the authority to grant an exception; that would take a change to the policy itself. And Rowan Tommins did the arithmetic: with alpha 1 out July 2, the cutoff for an RFC's final state was July 14, which is 4 days before this thread even opened. Pierre's frustration has a specific shape. The implementation was finished weeks ago — what delayed everything was that his pull request sat waiting on an approval that had been assigned to an automated bot reviewer, so no human was ever going to sign off, and he eventually merged it himself. He also argues the stakes are real, because PHP 9 is the one chance to change old defaults, and missing this window locks the current design in for years. The thread got tense over tone along the way — Pierre felt brushed off by a terse reply, and Rowan apologized outright, then made the counter-case that a fixed cutoff applied to everyone is fairer than debating each RFC's merits one at a time. All of this landed the same day Larry Garfield asked the list, in a separate thread, to hold new business until September 1 so reviewers can focus on &lt;code&gt;8.6&lt;/code&gt;'s finish line. So &lt;code&gt;gd&lt;/code&gt; 2.4 is alive and under discussion — just aimed at the &lt;em&gt;next&lt;/em&gt; release, whatever its number turns out to be.&lt;/p&gt;

&lt;p&gt;Caleb White's pipe assignment operator, &lt;code&gt;|&amp;gt;=&lt;/code&gt;, had a crowded week. Larry Garfield opened it unable to find a compelling use case, and by Monday had moved to a no — pushed there, he says, by a competing proposal. That competing proposal is Vadim Dvorovenko's &lt;strong&gt;left-to-right assignment&lt;/strong&gt; RFC, published Sunday, which claims the &lt;em&gt;same&lt;/em&gt; &lt;code&gt;|&amp;gt;=&lt;/code&gt; token with opposite semantics. Vadim objects on principle, arguing: "Attempting to transform such an operator from an immutable, functional construct into a mutable, imperative one steers the language in the wrong direction and undoes previous efforts." Caleb declined to merge the proposals, noting that F#, Elixir, OCaml, and Hack all kept ordinary assignment alongside their pipes. Larry also claimed none of the pipe proposals could make &lt;code&gt;8.6&lt;/code&gt;, and Tim Düsterhus corrected him, asserting: "This is false" — the last major change was July 13, so voting could open July 27 and close August 10, before the freeze. Meanwhile Bob Weinand asked whether the desugaring double-fires property hooks. Caleb came back with tests showing &lt;code&gt;|&amp;gt;=&lt;/code&gt; behaves exactly like &lt;code&gt;??=&lt;/code&gt;, and updated the RFC's single-evaluation section to match. Vadim's own RFC, as of recording, has &lt;strong&gt;0&lt;/strong&gt; replies.&lt;/p&gt;

&lt;p&gt;Paul M. Jones's &lt;code&gt;strict-namespace&lt;/code&gt; RFC — the piece he carved out of function autoloading last Tuesday night — spent its first full week in one long argument about a single word. Rowan Tommins objected first, writing that strict "implies some extra check that namespaces are [correct] in some way, which isn't really what this is about." Ilija Tovilo went deeper, arguing: "the value-add of this declaration is very small if the plan isn't ever to deprecate/remove the old behavior." Tim Düsterhus is &lt;strong&gt;in favor&lt;/strong&gt; — with a rename to &lt;code&gt;global_fallback=0&lt;/code&gt;. By Friday Paul had 4 candidate names on the table and a diagnosis: the pushback is the name, not the feature. Theodore Brown pointed out he'd floated the same directive in 2019; Paul added it to the prior art with an apology. And Benjamin Außenhofer suggested splitting the ballot — vote the concept, then vote the name. Rowan warned against it, writing: "a split vote leaves voters who actively dislike a particular name with an awkward choice: vote Yes, and risk the [bad] name being chosen; or vote No, even though you would support the feature under a different name." The rest of the autoloading corner kept moving too: Paul updated &lt;strong&gt;function autoloading&lt;/strong&gt; mark 5 to lean on the new RFC and wants its vote open in about 2 weeks, and Michael Morris's improved-autoloading draft drew warm-but-firm feedback from Larry Garfield and Rowan Tommins — both like the namespace-setup-file idea, neither wants it crammed into the class autoloader's callback.&lt;/p&gt;

&lt;p&gt;Nicolas Grekas didn't let Ilija Tovilo's "sadly not in favor" be the last word on &lt;strong&gt;serializable closures&lt;/strong&gt;. His rebuttal: caching one attribute isn't the point — the point is skipping the &lt;em&gt;entire&lt;/em&gt; metadata pipeline that frameworks re-run on every request, and that's the measured slow path. On the security design, he refused to loosen it, writing: "Name-based closure unserialization would ship a universal, app-independent gadget in the engine ... I won't commit to an RFC that turns every serialized payload into that kind of gadget, and I don't think we should, either." Then Saturday brought version &lt;code&gt;0.3&lt;/code&gt;, and a surgical cut — the reflection API is gone, the &lt;code&gt;serialize()&lt;/code&gt; support stays. His reasoning: "serialize() is the one feature that most/all cache systems are built on, so that's the place that needs the improvement." Fresh reviews welcome.&lt;/p&gt;

&lt;p&gt;Wendell Adriel came back to the list Thursday proposing &lt;strong&gt;typed array declarations&lt;/strong&gt; — &lt;code&gt;array&amp;lt;int, string&amp;gt;&lt;/code&gt; as real syntax, with 3 escalating enforcement levels. The review was fast and unsparing. Lazare Inepologlou flagged that you can't soundly subtype a mutable array without splitting reads from writes, and Wendell shipped a revised draft the &lt;em&gt;next day&lt;/em&gt;. Rob Landers warned the whole thing overlaps the reified generics work, on hold until after the freeze, which is late August at the earliest. Rowan Tommins noted that level 1 — syntax without enforcement — rhymes with the bound-erased generics RFC the list just declined. Michał Marcin Brzuchalski even found a runtime hole, where functions like &lt;code&gt;parse_str()&lt;/code&gt; that build results directly into a typed property can dodge the check. By Monday, Wendell put the RFC on hold himself. Larry Garfield's verdict was the sharpest, calling this "the already-dangerously-overloaded array mega-type" and asking for real typed list, set, and dictionary objects instead — which Wendell promptly volunteered to help build.&lt;/p&gt;

&lt;p&gt;The frozen &lt;strong&gt;deprecations&lt;/strong&gt; list for PHP &lt;code&gt;8.6&lt;/code&gt; got its evidence file. Juliette Reinders Folmer scanned the Packagist Top 4-thousand — nearly four hundred fifty thousand files — and posted counts for every proposal. The headline &lt;strong&gt;being&lt;/strong&gt;: &lt;code&gt;list()&lt;/code&gt; appears over &lt;strong&gt;twelve thousand&lt;/strong&gt; times, and Juliette wrote plainly: "Having said that, I'm definitely not in favour of deprecating list()." Compare &lt;code&gt;spl_object_hash()&lt;/code&gt; at 625, &lt;code&gt;is_integer()&lt;/code&gt; at 303, and a long tail of single and double digits — several proposals scored a clean 0. Kamil Tekiela discovered his mysqli proposal had missed the procedural &lt;code&gt;mysqli_stmt_init()&lt;/code&gt;, patched the text, and worried aloud: "I hope this change is not going to reset the counter." Tim Düsterhus was quick to correct the record downward — one scary-looking count, on &lt;code&gt;_&lt;/code&gt; as a constant, collapses to 0 once false positives come out. And Monday, right on schedule, Gina P. Banyard confirmed the timetable, writing: "I intend to open the vote next Monday (the 27th of July) for 2 weeks so that the vote is finished on time for 8.6." Every deprecation gets voted in isolation — bring a lunch.&lt;/p&gt;

&lt;p&gt;Quick hits. Go Kudo returned with a rebuilt cache proposal — a bundled &lt;code&gt;user_cache&lt;/code&gt; extension, fully decoupled from OPcache this time; Larry Garfield likes it, flagged the lock story around &lt;code&gt;remember()&lt;/code&gt;, and gently redirected it to &lt;code&gt;8.7&lt;/code&gt; — adding: "Or 9, if that's what we call it." Holly Schilling's &lt;strong&gt;4x&lt;/strong&gt; fix for non-public asymmetric setters got its answer: no RFC needed — Tim confirmed a pure performance improvement just needs PR review, and Ilia Alshanetsky called it "definitely a strong candidate for PHP 8.6 inclusion." &lt;strong&gt;fennic&lt;/strong&gt; pitched engine-native PSR-4 autoloading with &lt;code&gt;spl_autoload_psr4_register()&lt;/code&gt;; Alex Rock wants classmap support before it can replace Composer's bootstrap, and Heinz Wiesinger pointed to his existing PECL extension doing much the same. Edmond of the TrueAsync project published a pre-RFC for an &lt;strong&gt;async scheduler&lt;/strong&gt; engine interface — coroutine-aware core, no scheduler in core itself. His philosophical problem is that the RFC has &lt;em&gt;no&lt;/em&gt; user-visible changes at all, and so far it has 0 replies. And Osama Aldemeery asked for RFC karma to formalize &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt; — Ilija Tovilo granted it &lt;strong&gt;2 minutes&lt;/strong&gt; later.&lt;/p&gt;

&lt;p&gt;Liam Hammett's markup expressions thread sprouted an alternative: Edmond proposed making the &lt;em&gt;parser&lt;/em&gt; extensible instead, so JSX-like syntaxes could ship as extensions — Morgan liked that better than blessing one syntax, and within a day Edmond had a working DSL-hooks prototype, announcing: "Your wish has been granted. 🙂" Máté Kocsis and Ignace Nyamagana Butera kept refining &lt;strong&gt;query parameters&lt;/strong&gt; — the open question is whether parsing limits belong on builder methods too, with Ignace arguing PHP shouldn't police what's really a business constraint. Prateek Bhujel's terminal-helpers extension hit &lt;code&gt;0.6.0&lt;/code&gt; — it's now installable via PIE, and its output methods now write to standard PHP streams like STDOUT and STDERR instead of only its own built-in targets. The ballot queue grew by 2: Nick Sdot posted intent to vote on &lt;strong&gt;readonly property defaults&lt;/strong&gt; for on or around July 23, and Khaled Alam's const-object-property-write opens Saturday the 25th — both aiming ahead of the freeze. Ben Ramsey amended the &lt;strong&gt;Working Groups&lt;/strong&gt; RFC with a new section setting expectations for charter-RFC discussion. And release week: PHP &lt;code&gt;8.6.0alpha2&lt;/code&gt;, &lt;code&gt;8.5.9RC1&lt;/code&gt;, and &lt;code&gt;8.4.24RC1&lt;/code&gt; all shipped — with alpha 3 and both GA releases converging on July 30 — while the release managers posted the countdown that framed half of this episode: soft feature freeze August 11, beta 1 August 13, every &lt;code&gt;8.6&lt;/code&gt; vote closed before then.&lt;/p&gt;

&lt;p&gt;So that's the week: 2 ballot boxes open and both lopsided — &lt;code&gt;Duration&lt;/code&gt; cruising at 23 to 1, minimum versions right behind it; &lt;code&gt;gd&lt;/code&gt; 2.4 arriving 4 days after the door closed and pointing at the next release instead; a pipe operator with 2 authors claiming 1 token; typed arrays proposed, revised, and shelved inside 5 days; and the deprecations list armed with its evidence file, ballots opening Monday — with readonly defaults and const-property-write queued right behind. Links to every thread are below. Thanks again to &lt;code&gt;Tideways.com&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
    <item>
      <title>This Week In PHP Internals | July 15, 2026</title>
      <dc:creator>Len Woodward</dc:creator>
      <pubDate>Thu, 16 Jul 2026 00:50:01 +0000</pubDate>
      <link>https://dev.to/projektgopher/this-week-in-php-internals-july-15-2026-4nhb</link>
      <guid>https://dev.to/projektgopher/this-week-in-php-internals-july-15-2026-4nhb</guid>
      <description>&lt;p&gt;Hello world, it's Wednesday, July 15, 2026, and here's what happened This Week in PHP Internals.&lt;/p&gt;

&lt;p&gt;This week's episode is brought to you by &lt;strong&gt;Tideways&lt;/strong&gt;. Something in production is slow — and you can't see &lt;em&gt;where&lt;/em&gt;. Tideways takes PHP developers from slow request to root cause in minutes, with profiling, tracing, and monitoring built specifically for PHP. 5-minute install, no credit card. Start your free trial at &lt;code&gt;tideways.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This week's top story is a brand-new keyword knocking on the door: &lt;code&gt;extension&lt;/code&gt;. One week after Larry Garfield floated Kotlin-style extension functions at the scalar-methods RFC, Holly Schilling arrived with working prototypes of Swift-style &lt;strong&gt;class extensions&lt;/strong&gt; — born, she says, out of a Discord conversation — and it became the biggest thread of the week at 26 messages. The idea: add methods to a class you don't own — &lt;code&gt;extension \DateTimeImmutable&lt;/code&gt; gives every date an &lt;code&gt;isWeekend()&lt;/code&gt; — and, in a later phase, put methods on scalars, so &lt;code&gt;"hello"&lt;/code&gt; gets a &lt;code&gt;length()&lt;/code&gt;. She published 3 draft RFCs as gists, implementation included. Michael Morris asked the obvious first question, writing: "Looking at Swift's extension syntax I fail to see anything it adds not covered by the above." — the above being inheritance and traits. Holly drew the line clean: "An extension is essentially the reverse of a trait." With a trait, the &lt;strong&gt;author&lt;/strong&gt; of the class decides; with an extension, the &lt;em&gt;user&lt;/em&gt; of the class decides.&lt;/p&gt;

&lt;p&gt;Then came the twist. 2 days in, Holly sat down to defend her own scalar-methods implementation — and couldn't. She wrote: "Typing this email this morning gave me real hesitation. If I can’t support my own implementation, no one else should either. I immediately set out to build a better version that I could put my full weight behind." The better version came from an unexpected place: &lt;strong&gt;C# 14&lt;/strong&gt;, whose new extension syntax puts the receiver right in the declaration — &lt;code&gt;extension string $str&lt;/code&gt; — no autoboxing, no downcast headaches. She rewrote all 3 drafts and the implementation around it in a day. Not everything got absorbed so gracefully: when Alex Rock proposed an explicit &lt;code&gt;extend ... with ...&lt;/code&gt; wiring statement, Holly apologized in advance for the bluntness, then answered: "I reject this functionality." — extensions stay file-scoped, and they &lt;strong&gt;never&lt;/strong&gt; override a real method. And Pierre Joye flagged a process problem: proposals keep citing Discord conversations as their origin, while he reads only internals and GitHub — and found no reference to a php.net Discord anywhere he searched.&lt;/p&gt;

&lt;p&gt;Gina P. Banyard's &lt;strong&gt;Deprecations for PHP &lt;code&gt;8.6&lt;/code&gt;&lt;/strong&gt; — the annual bundle that spent June on fire — reached its quiet milestone: the list is locked. Gina declared the RFC "frozen", with only minor amendments still allowed, and put dates on everything: "I will initiate a call to vote next week on Monday (the 20th) for the following Monday (the 27th) so that the vote is done by the 10th of August." Because items were still being added in the final week, the policy's 2-week discussion clock is what sets that gap — and the timing is deliberate, so accepted proposals can land in &lt;code&gt;8.6.0&lt;/code&gt; &lt;strong&gt;beta 1&lt;/strong&gt;. The week's lightest subplot: Garrett W. wants the deprecation notices themselves copy-edited — those commas are comma &lt;em&gt;splices&lt;/em&gt;, and he'd use semicolons. Tim Düsterhus explained the house style comes from PHP error messages, and added: "The deprecation messages can still change during PR review (or even later), there is explicitly no BC guarantees for those."&lt;/p&gt;

&lt;p&gt;Paul M. Jones's &lt;strong&gt;function autoloading&lt;/strong&gt; — attempt number 5 — got smaller this week, on purpose. The &lt;code&gt;declare(strict_namespace=1)&lt;/code&gt; directive he added last week drew a structural objection from Tim Düsterhus, who argued: "I believe the strict_namespace=1 directive is a sufficiently unrelated concern - with enormous bikeshedding potential on its own, but also sufficient usefulness on its own - such that I feel it should be its own RFC that is a prerequisite to this one. It should not be piggy-backed onto function autoloading." Paul didn't fight it. He replied: "I'm good with that. I'll prepare a separate RFC and remove that from the function-autoloading one." — and by Tuesday night it existed: &lt;code&gt;strict-namespace&lt;/code&gt; is now its own RFC on the wiki, and mark 5 will reference it instead of carrying it. Tim also showed his cards: he built the &lt;em&gt;inverse&lt;/em&gt; directive as an experiment a year ago, and he's firmly on team fully-qualify-everything.&lt;/p&gt;

&lt;p&gt;Tim Düsterhus and Derick Rethans' &lt;code&gt;Time\Duration&lt;/code&gt; class is days from the ballot box — and it picked up its first declared no. Pierre Joye spent the week pressing on &lt;code&gt;fromSeconds()&lt;/code&gt; and its capped nanoseconds argument, and landed here: "I like that RFC, but it adds confusions and limitations from what is supposed to be a simple first step. As it stands now, despite the fact that I would love to see it, I tend towards a no." Tim's defense reached for the stopwatch — it's natural, he argued, to say Usain Bolt broke the 100 m world record with "9 seconds 58 hundreths" — exactly the fixed-point form &lt;code&gt;fromSeconds()&lt;/code&gt; uses. Pierre countered: "It is just as common in the real world to have duration information in one unit only and decimal. F.e. 234.54ms. or 3.4 hours, etc." Neither moved — and per Tim, that's fine: "All discussions have been resolved (some of them with an “agree to disagree”), so we plan to open voting at the end of this or early next week." The 14-day cooldown runs out Friday evening, European time.&lt;/p&gt;

&lt;p&gt;A first-time author had a very good week. Caleb White got RFC karma from Ilija Tovilo, and his first proposal — the &lt;strong&gt;pipe assignment operator&lt;/strong&gt;, &lt;code&gt;|&amp;gt;=&lt;/code&gt; — went through review polish at speed. The idea: &lt;code&gt;$x |&amp;gt;= trim(...)&lt;/code&gt; pipes &lt;code&gt;$x&lt;/code&gt; through and puts the result back, just like every other modify-assign operator. Tim Düsterhus liked the shape, saying: "Conceptionally I like the idea of having an “in-place modification operator” for function calls and the semantics of the operator seem to be consistent with the existing “modify-assign” operators we have, particularly also with regard to operand order. Nice idea!" Tim also caught a precedence claim that was &lt;em&gt;almost&lt;/em&gt; right — assignment operators are not the lowest; the infamous &lt;code&gt;or die()&lt;/code&gt; pattern depends on it — and Caleb fixed the RFC the same day, both times. The list's real energy went to naming. Ben Ramsey offered: "I like to think of |&amp;gt; as the volcano operator, while |&amp;gt;= is the erupting volcano operator."&lt;/p&gt;

&lt;p&gt;Then last night — hours before we hit record — Liam Hammett published &lt;strong&gt;Native Markup Expressions&lt;/strong&gt;: JSX-style markup as first-class PHP expressions. Write a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tag straight into an expression, and it compiles to &lt;code&gt;new \Markup\Element(...)&lt;/code&gt; — escaped by default, with capitalized tags becoming components. Liam headed off the obvious reading, writing: "Despite appearances, this is not a template language grafted onto the engine - the syntax is pure compile-time sugar." First reviewer Garrett W. questioned that capitalization heuristic — PSR-4 isn't binding, and lowercase class names are legal. Liam pushed back: "Fallback resolution turns typos into silent bugs. With the capitalisation rule,  fails loudly with a class-not-found error. With fallback resolution, it silently renders as a literal  element and you find out in the browser, if you find out at all." This is the &lt;em&gt;ambitious&lt;/em&gt; RFC Liam requested wiki karma for on July 10 — Ilija Tovilo granted it Monday: "RFC karma was granted. Good luck!"&lt;/p&gt;

&lt;p&gt;Marc Henderkes wants to end PHP's double life. His pre-RFC: make &lt;strong&gt;ZTS&lt;/strong&gt; — the thread-safe build — the default, deprecate the rest, and drop NTS entirely in PHP 9. He summed it up himself: "Tl;dr: nobody wants to maintain two builds and even having a necessary split is making things hard." Distros package only NTS, FrankenPHP needs ZTS, and php-src carries roughly 420 ZTS ifdefs. The performance tax is dissolving too — his numbers: "Worst case performance cost of ZTS in php 8.5 was ~5%, will be ~1.5% in php 8.6, likely ~0.5% after my last open PRs." To be clear, he is &lt;em&gt;not&lt;/em&gt; proposing to deprecate FPM — a single-threaded ZTS run keeps everything NTS does today. 2 of the named blockers — the arm64 macOS JIT and the fuzzer SAPI — were fixed within 2 days of the thread opening; the third, NewRelic's missing ZTS support, isn't Marc's to fix. Benjamin Eberlei backed the initiative, Calvin Buckley volunteered his own PHP distribution as a test subject, and Marc has requested wiki karma to write the full RFC.&lt;/p&gt;

&lt;p&gt;Nicolas Grekas's &lt;strong&gt;serializable closures&lt;/strong&gt; spent the week absorbing a deep review from Tim Düsterhus — and then ran into a wall. Tim was candid: "While reading the RFC initially and now the updated version, I got the feeling that it was “overfitted” to solve the specific use case and deployment scenario that you consider a “best practice”, which I feel results in “weird” behavior when one leaves that happy path." Still, the 2 converged on real changes: Nicolas adopted Tim's tagged-union serialization format, and — after an off-list suggestion from Arnaud — replaced the fragile line-number check with a compile-time &lt;strong&gt;hash of the closure body&lt;/strong&gt;, so a shifted &lt;code&gt;use&lt;/code&gt; import can't silently break payloads. Then Tuesday night, Ilija Tovilo weighed in against — questioning whether attributes need caching at all, and finding the format and implementation too complex. He closed with: "Overall, I'm sadly not in favor of this RFC."&lt;/p&gt;

&lt;p&gt;No ballot box was open this week — instead, the queue got dates. Eric Norris's &lt;strong&gt;minimum supported versions&lt;/strong&gt; opens voting &lt;em&gt;tomorrow&lt;/em&gt;, July 16 — the earliest the policy allows. &lt;code&gt;Duration&lt;/code&gt; clears its cooldown Friday evening and opens late this week or early next. The deprecations list calls its vote Monday the 20th, with ballots open the 27th. And Khaled Alam's const-object-property-write RFC is cleared to open July 25 — no later than the 28th to make &lt;code&gt;8.6&lt;/code&gt;. All of it backs into the release managers' reminder from Monday. Matteo Beccati wrote: "Any RFC intended for inclusion in PHP 8.6 must have its discussion concluded and its voting closed before August 13." Soft feature freeze: August 11. Beta 1: August 13.&lt;/p&gt;

&lt;p&gt;Quick hits, round 1. Máté Kocsis revived his &lt;strong&gt;query parameters&lt;/strong&gt; RFC with a simplification: he's cutting the array API down to 2 — &lt;em&gt;maybe&lt;/em&gt; 3 — methods, &lt;code&gt;fromArray()&lt;/code&gt; and &lt;code&gt;toArray()&lt;/code&gt; with &lt;code&gt;withArray()&lt;/code&gt; on the bubble, plus an options class with security limits on parsing; League-of-URI maintainer Ignace Nyamagana Butera answered with naming notes and an enum for null handling. Nick Sdot's readonly-property defaults — &lt;em&gt;zero&lt;/em&gt; replies when we covered it last week — got its replies: Tim Düsterhus found an unserialization wrinkle, Nick fixed it the same day, Larry Garfield is skeptical, and Tim plans to abstain. Holly Schilling — the same Holly Schilling from our top story — found that non-public asymmetric setters run roughly &lt;strong&gt;4x&lt;/strong&gt; slower than public ones, posted a fix, and then a formal RFC for it — with Ilija Tovilo reviewing the PR, she's giving the list a few days to weigh in on &lt;code&gt;8.6&lt;/code&gt; versus waiting; Marc Henderkes and Calvin Buckley both questioned whether an internal change needs an RFC at all. And Osama Aldemeery's &lt;code&gt;PREG_THROW_ON_ERROR&lt;/code&gt; settled its naming on Tim's advice: an unnamespaced &lt;code&gt;PregException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Round 2. Sjoerd Langkemper showed that newlines in &lt;code&gt;CURLOPT_HTTPHEADER&lt;/code&gt; values inject extra headers — even over HTTP/2 — and opened a fix; upstream curl is adding its own check, and curl's own Daniel Stenberg confirmed CRLF is disallowed. Xavier Leune bumped his curl socket-callbacks PR — pitching it as the missing tool against SSRF to localhost — and is still waiting on a reply. The bundled-GD sync to libgd &lt;code&gt;2.4&lt;/code&gt; drew its first pushback: Giovanni Giacobbi says the upstream code is too young and &lt;code&gt;8.6&lt;/code&gt; too far along, while Pierre Joye, Jakub Zelenka, and Ilia Alshanetsky want it landed before beta 1 — Jakub's condition being that the security-review findings get addressed first — and Kamil Tekiela says wait for the next version. And the DTLS experiment in the &lt;code&gt;openssl&lt;/code&gt; extension became a real draft PR; Jakub Zelenka confirmed the direction and is already sketching the generalization it needs.&lt;/p&gt;

&lt;p&gt;So that's the week: a brand-new &lt;code&gt;extension&lt;/code&gt; keyword that rewrote itself mid-thread; a frozen deprecations list with ballots set for the 27th; function autoloading shedding a prerequisite RFC; a &lt;code&gt;Duration&lt;/code&gt; vote opening within days, carrying its first declared no; and a JSX-flavored surprise landing the night before we filmed. Nothing was voted on this week — and the ballot queue starts moving tomorrow. Links to every thread are below. Thanks again to &lt;code&gt;Tideways.com&lt;/code&gt; for supporting this week's episode. We're Artisan Build. See you next week.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>news</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
