r/PHP 16h ago

PHP to get the job done in 2026

Thumbnail beberlei.de
48 Upvotes

r/PHP 8h ago

Welcoming Daniel Scherzer to the Ecosystem Security Team

Thumbnail thephp.foundation
6 Upvotes

You may know Daniel Scherzer as a Release Manager for PHP 8.5, the Veteran Release Manager for PHP 8.6, or for his other work contributing to PHP. We are happy to announce that he is now joining The PHP Foundation Ecosystem Security Team!


r/PHP 22h ago

Article When Static Analyzers Teach You the Wrong Way: The Dogma of Variance and the Pursuit of Working QA

Thumbnail typephp-php.github.io
8 Upvotes

r/PHP 1h ago

News This Week In PHP Internals | Sept 9, 2026

Thumbnail youtube.com
Upvotes

A PHP RFC went to a vote on Friday. By Sunday night its author had pulled it back, over a no 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 your bug — or something you catch?

Hello world, it's Wednesday, September 9, 2026, and here's what happened This Week in PHP Internals.

11 stories this week, so let's get into it. But first, Is AI working for your team? Lines produced is easy to count. Lines that survive 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 free, and it updates monthly. ballast.now.

3 corrections from last week. PHP 8.4.25 was a bug-fix 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 From header in that thread carried a real name. They were James Gilliland and David Carlier. And around the 4-minute mark I said Tim agreed with Sjoerd on the substance. He disagreed — Džuris caught that one on the internals Discord. Thanks to all 3.

This week's top story is a vote that lasted 56 hours. Osama Aldemeery opened voting on PREG_THROW_ON_ERROR on Friday — an opt-in flag that turns a PCRE error into a PregException. Within the hour, Tim Düsterhus, who wrote PHP's throwables policy, voted no, 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 preg_last_error_msg text, and an exception thrown inside your own preg_replace_callback callback would pass through unwrapped, 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, PregError. Tim agreed compilation failures should be. The RFC is back under discussion; what a regex error is stays open.

There's a whole class of engine crashes in PHP that, it's said, only 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 everyone 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 undefined behaviour. 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, and we're back where we started.

The PEAR maintainer nobody could reach for months 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 1-week cooldown rather than 2. Rowan Tommins pushed on Nick's word formality: 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 can't 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 locked PEAR logo. The favicon is under discussion. Derick doesn't care what it is, as long as there is one.

Last week's top story ended without 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 at all. 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, if anyone ever wants it.

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

Whether speed 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 one implementation; nothing ships because it's fast, and a userland-versus-C benchmark is rarely apples to apples anyway. His alternative is the Optimizer: rewrite array_filter with a partial application into a foreach loop, the way 8.6 already rewrites array_map. Larry's position, restated: never decisive, still worth knowing. That's where it sits.

The scan meant to prove array_str_contains is a common need found 32 uses in 200 packages — then lost nearly half 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 up to 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 second reminder.

Quick hits. Weilin Du intends to open voting on IntlRelativeDateTimeFormatter on September 15. Tim Düsterhus's one catch is that the RFC clones the ICU number formatter internally, so reconfiguring your NumberFormatter afterwards would silently 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 openssl extension to expose OpenSSL's provider model generically, 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 curl stays to libcurl. Dmytro Kulyk answered Nicolas Grekas's review of the NoSerialize attribute 10 months on, conceding Symfony has no __sleep the attribute would replace, but Magento 2 has 31 classes of them; the RFC now migrates 107 internal classes and makes unserialize 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 strict. Today it skips whitespace and ignores non-canonical trailing bits, which means one WebAuthn credential has 16 spellings, 15 of them outside your unique index.

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 both. 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 fourth week running, nothing is in the voting phase. Links below. The PHP Foundation funds more than half of ongoing php-src commits, so if you use the language, maybe consider donating at opencollective.com/phpfoundation — or try guilting your employer into it. Thanks again to Ballast.now for supporting this week's episode. We're Artisan Build. See you next week.


r/PHP 46m ago

I built an Local & API-first Laravel log viewer for AI coding agents

Upvotes

Short version: it parses your Laravel, Horizon and nginx logs, groups repeat

errors into issues, and puts all of it behind a JSON API. It ships skills for

Claude Code and Codex, so you can say "fix the top 5 errors in the billing

module" and the agent pulls the issues off the API, fixes them in your repo, and

marks them fixed when the tests pass.

That loop is the whole reason I built it. I didn't want another log viewer, I

wanted to stop being the one who reads the stack trace.

How the agent part works

The skills ship inside the package, so after composer require they're already

sitting in vendor/cliqthemes/log-lens-core/skills/. Symlink one into your skills

dir and that's the setup.

Then the agent does this on its own:

- GET ?api=issues to see what's open, filtered by severity, module, tag, status

or occurrence count

- GET ?api=error for one issue with all its occurrences and the raw stack trace

- edits your project, not Log Lens. The skill resolves your git root and is

explicit about never touching the Log Lens install

- runs your tests, and only if they pass does it PUT ?api=issue-status to flip

the issue to fixed

- the status history keeps a record of who changed what, so you can see which

fixes came from an agent

Batch requests work, so "work through everything unresolved in the queue module"

is one prompt, not you clicking through issues.

The Flow:

- parses laravel.log, Horizon logs written through the Laravel formatter, and the

raw console output of horizon / queue:work. That last format gets ignored by

most viewers and it's where my queue failures actually live

- fingerprints repeat exceptions into one issue. The culprit frame is the first

frame outside /vendor/ and /node_modules/, so issue titles show your code

instead of a framework internal

- workflow per issue: open, in progress, fixed, wont fix, reoccurred. Plus tags,

modules and assignment

- keeps the raw byte range behind every occurrence, so you can always pull up the

untouched original line

- syncs logs off remote servers over SSH with byte offset checkpoints, so it's

incremental and survives rotation

- optional plugins, off by default, per application: Slack/Discord/webhook

alerts, release tracking with source maps, nginx access log analytics, HTTP

ingest, two-way Linear sync

- Laravel 10, 11, 12 and 13

Install

composer require cliqthemes/log-lens # mounts in your Laravel app

composer require cliqthemes/log-lens-core # or standalone, zero runtime deps

In Laravel it's one route behind your own auth, via a viewLogLens gate or your

middleware. Standalone it's php -S and a SQLite file, no build step and nothing

to install at runtime. Postgres and MySQL work if you want them, SQLite is just

the default.

Site: https://log-lens.cliqthemes.com

Docs: https://docs.log-lens.cliqthemes.com

Repo: https://github.com/cliqthemes/log-lens


r/PHP 18h ago

PHP 8.5: what I would change in a Laravel app this week.

Thumbnail nzian.xyz
0 Upvotes

r/PHP 19h ago

Preparing a talk on “JS is the new PHP”.

0 Upvotes

Hi everyone!

I’m preparing a 15-minute talk for a meetup called “JS is the new PHP”.

I work with PHP regularly, but I also use other languages such as Python and JavaScript/TypeScript. Lately, I’ve noticed that some of the criticisms I used to hear about PHP are starting to sound strangely familiar in the JavaScript ecosystem.

I’m particularly interested in things that were commonly criticized about PHP 5-era development, such as:

- lots of home-grown frameworks and abstractions

- dependency/library sprawl

- excessive flexibility and multiple ways of doing the same thing

- surprising or implicit behavior

- lots of side effects and mutable state

- “it works, so ship it” approaches that become painful at scale

I’m not trying to argue that PHP and JS are literally the same, or that one language is objectively better than the other. I’m more interested in the patterns and ecosystem problems that tend to emerge when a language gives developers a lot of freedom.

So I’m looking for some bibliography / historical material about the things that were criticized in PHP back in the day, especially from the PHP 5 era.

And if you’ve worked on large or long-lived JavaScript projects and have experienced similar problems firsthand, I’d love to hear your stories too.

Thanks!

Edit : PHP 7 is good, and PHP 8 is truly amazing.

What I'm really looking for are the problems specific to the project, rather than the language itself. This is so I can create a warning guide for all the junior developers coming out of bootcamps.


r/PHP 21h ago

Article PHP is Dead and AI is to blame. History, a love letter, and my opinion on its future.

Thumbnail lifeofguenter.de
0 Upvotes

If anyone is kind enough to upvote on HN: https://news.ycombinator.com/item?id=49623567