{"slug": "this-week-in-php-internals-august-19-2026", "title": "This Week In PHP Internals | August 19, 2026", "summary": "In the PHP internals mailing list this week, a proposal by Sepehr Mahmoudi for an array_search_range() function sparked a design debate, with Rowan Tommins advocating for a more composable lazy array slice approach. Additionally, a proposal to make ini_get_all() case-insensitive was withdrawn after Daniel Scherzer argued for making all extension-name functions case-sensitive instead.", "body_md": "Hello world, it's Wednesday, August 19, 2026, and here's what happened This Week in PHP Internals.\n\n12 stories this week, so let's get into it. *But first,* Is AI working for your team? Ballast answers that for **free**. 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. `ballast.now`\n\n.\n\nThis 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 `array_search_range()`\n\n— an `array_search()`\n\nthat takes an offset and a length, so you can search part of an array without building an intermediate copy with `array_slice()`\n\n. Weilin Du replied the same evening to say the soft feature freeze had already closed `8.6`\n\nto 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 **without copying any of it**.\n\nRowan 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 `ArraySliceIterator`\n\ncomes first, then `iter_search`\n\nand `iter_any`\n\nfunctions that would work with **any** 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 `array_slice()`\n\n, which copies the array. *That is the cost the proposal exists to avoid.* As of this recording the RFC is still a draft, still targeting `8.6`\n\n, and Rowan's GitHub review found the implementation still walking the entire array.\n\nSomething small and irritating went to the list on Saturday. 4 functions take an extension name, and `ini_get_all()`\n\nis the only one of them that's **case-sensitive**. Weilin Du opened a pull request to bring it into line with `extension_loaded()`\n\n, `phpversion()`\n\nand `get_extension_funcs()`\n\n. 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?\" *He also spotted that the manual's lowercase-only note for get_extension_funcs() isn't true. AllenJB traced it to a change back in PHP 5.0.4, and there's a docs issue open now.*\n\nDaniel 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 **withdrew his own proposal**, saying he'd add extension-name case sensitivity to the `8.7`\n\ndeprecations RFC instead. And then 3 people showed up to argue for the thing he'd just withdrawn. Aleksander Machniak listed `PDO`\n\n, `SimpleXML`\n\n, `Xdebug`\n\nand `swoole`\n\n, 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 `composer.json`\n\ngenerally writes its extension requirements in lowercase. Juliette Reinders Folmer had the last word, with the practical cost. Build a version list with `get_loaded_extensions()`\n\nand you'd have to lowercase every name before `phpversion()`\n\nwould take it. Nobody has replied to her yet.\n\nHenrik Skov posted an idea on Tuesday morning. He wants a `params`\n\nkeyword 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 **when the call happens**, not when the compiler first sees them, so a `time()`\n\nin 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. *2 unrelated threads this week, and both of them landed on the word \"lazy.\" Nobody involved was.*\n\nJens 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 `var_export()`\n\nstill print the long `array(...)`\n\nsyntax, 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 `var_export()`\n\nis meant to be **PHP-executable first** 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 — *which is a fair summary of the last 6 years.*\n\nOtar Chekurishvili posted a pre-RFC on Monday for 2 opt-in flags in the `json`\n\nextension, targeting `8.7`\n\n. One is `JSON_ALLOW_COMMENTS`\n\nand the other is `JSON_ALLOW_TRAILING_COMMAS`\n\n, and both would be accepted by `json_decode()`\n\nand `json_validate()`\n\n. **Strict JSON stays the default.** Trailing commas allow exactly 1 after the last element. *That's 1 more than JSON allows today, and exactly as many as most of us have typed by accident.* 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.\n\nAlexander Lisachenko wants to fix something about PHP's FFI. Every C value it hands back comes back as the same final class, `FFI\\CData`\n\n. A string pointer, a zval pointer and a raw `char`\n\npointer are all the same type to PHP. *Which makes FFI strongly typed, in the sense that there is 1 type.* 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 `instanceof`\n\nstill doesn't work. His proposal is an opt-in class map passed as an options array, in the same shape as `SoapClient`\n\ntakes one, so a registered C type comes back as **your** class instead of bare `CData`\n\n. He says it stays inside the `ffi`\n\nextension 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.\"\n\nThe `8.6`\n\ndeprecation vote closed 9 days ago, and one of the items that passed deprecates `SplFileObject`\n\n's CSV methods. In the last days of voting Takuya Aramaki pointed out that the `READ_CSV`\n\nflag was left out, and that `setCsvControl()`\n\nis 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 `READ_CSV`\n\nin place does resolve the original issue, but doesn't achieve the goal of getting CSV handling **out** of SPL. By his reading of the code there's a second problem. When the default escape character for `fgetcsv()`\n\nchanges, code using `READ_CSV`\n\nwill behave differently across PHP versions with no way to pin it. His conclusion is that `READ_CSV`\n\nneeds deprecating too, and that a migration path should have been part of the proposal. *Still no reply.*\n\nEloi 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 `abstract`\n\nkeyword, 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 **2017** 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.\" *He also left a parser problem on the table.* Interfaces already support ordinary constants, so an `abstract`\n\nkeyword may be necessary there regardless.\n\nQuick hits. Sjoerd Langkemper gave its own page to a proposal that missed the `8.6`\n\nwindow. `bindec()`\n\n, `octdec()`\n\n, `hexdec()`\n\nand `base_convert()`\n\nwould throw a `ValueError`\n\nwhen you hand them characters that aren't valid for the base, instead of the deprecation notice they've emitted since `7.4`\n\n. Today `hexdec('z')`\n\nreturns 0. It targets `8.7`\n\nand has no replies yet. Weilin Du also asked for feedback on tightening 2 INI settings. Right now `upload_max_filesize=1GB`\n\ncan be read as **1 byte** by the request parser while `ini_get()`\n\nstill reports the string you wrote, *which is a spectacular way to lose an afternoon*. 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 `PREG_THROW_ON_ERROR`\n\nRFC 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 `8.6.0`\n\nbeta 1, with beta 2 due on August 27, and Calvin Buckley and Daniel Scherzer followed with `8.4.25`\n\nand `8.5.10`\n\nRC 1. *Matteo Beccati mentioned in passing that the 8.6 branch should be cut on September 22.*\n\nHere's the week in short. **No RFC went to a vote**, and nothing is in the voting phase at all. A new contributor's `array_search_range()`\n\nran into a counter-proposal for a general lazy array slice, and is still a draft. A one-line inconsistency in `ini_get_all()`\n\nturned into a question about case sensitivity that ended with the author withdrawing a proposal 3 other people then defended. A `params`\n\nkeyword got talked into being a lazy value. Abstract class constants may pick up interfaces. And PHP `8.6`\n\nbeta 1 is out, with beta 2 due *next week.* Links to every thread are below. Thanks again to `Ballast.now`\n\nfor supporting this week's episode. We're Artisan Build. See you next week.", "url": "https://wpnews.pro/news/this-week-in-php-internals-august-19-2026", "canonical_source": "https://dev.to/projektgopher/this-week-in-php-internals-august-19-2026-6mh", "published_at": "2026-08-21 22:56:58+00:00", "updated_at": "2026-08-21 23:44:36.875607+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Sepehr Mahmoudi", "Rowan Tommins", "Weilin Du", "Daniel Scherzer", "Larry Garfield", "PHP", "Swift"], "alternates": {"html": "https://wpnews.pro/news/this-week-in-php-internals-august-19-2026", "markdown": "https://wpnews.pro/news/this-week-in-php-internals-august-19-2026.md", "text": "https://wpnews.pro/news/this-week-in-php-internals-august-19-2026.txt", "jsonld": "https://wpnews.pro/news/this-week-in-php-internals-august-19-2026.jsonld"}}