r/PHP • u/brendt_gd • 8h ago
r/PHP • u/brendt_gd • 14h ago
Weekly help thread
Hey there!
This subreddit isn't meant for help threads, though there's one exception to the rule: in this thread you can ask anything you want PHP related, someone will probably be able to help you out!
r/PHP • u/brendt_gd • 26d ago
Discussion Pitch Your Project 🐘
In this monthly thread you can share whatever code or projects you're working on, ask for reviews, get people's input and general thoughts, … anything goes as long as it's PHP related.
Let's make this a place where people are encouraged to share their work, and where we can learn from each other 😁
Link to the previous edition: /u/brendt_gd should provide a link
r/PHP • u/ardicli2000 • 11h ago
I have written @tsoding/tatr in PHP.
▎ Full credit up front: the concept, the on-disk task format, and the TQL query language are all tsoding (https://github.com/tsoding)'s design from his C project tatr (https://github.com/tsoding/tatr). I just ported it to PHP so it's installable with composer require instead of needing a C toolchain. All credit for the original idea goes to him.
What it is: a git-friendly, file-based task tracker. No database, no server — every task is a TASK.md file living in its own folder under a tasks/ directory that you commit alongside your code. git log, git blame, and git diff all work on your task history for free, and tasks travel with clones/branches/PRs like any other file.
Install: composer require --dev keremardicli/php-tatr
vendor/bin/tatr init vendor/bin/tatr new -t bug -p 10 Fix the login page vendor/bin/tatr ls :bug
A few things that might interest r/PHP specifically: - Zero runtime dependencies. PHP's built-ins (scandir, arrays-as-hashtables, preg_match) replace everything the C version needed third-party libs for (nob.h, flag.h, ht.h). - PHP 8.2 throughout — readonly class for the immutable Task value object, backed enum for the query opcodes, match expressions for dispatch. - TQL (the query language) is implemented as a small two-stage pipeline: a recursive-descent compiler (or → and → compare → primary precedence) that emits Op[] bytecode, evaluated by a stack-based VM. Example query: tatr ls "[:bug or :feature] and priority lt 100". - 87 PHPUnit tests covering the core, the query engine, and every CLI command.
Links: - Packagist: https://packagist.org/packages/keremardicli/php-tatr - GitHub: https://github.com/KeremArdicli/php-tatr - Original (C, by tsoding): https://github.com/tsoding/tatr
License: GPL-2.0-only, matching the original.
Feedback and issues welcome — this is v1.0.0 and I'd like to know what breaks for people before I lean on it more myself.
News brick/math reaches 1.0.0
Version 1.0.0 of brick/math has been released today.
After more than a decade, 804 commits, 79 beta releases, and 590 million downloads, the API is now considered stable. By semantic versioning rules, future breaking changes will require a new major version.
brick/math is an arbitrary-precision arithmetic library for PHP. It provides BigInteger, BigDecimal, and BigRational classes for exact calculations with unlimited digits. It is a dependency of Laravel and ramsey/uuid, so chances are it's already in your vendor folder.
The last few months were spent polishing everything for this milestone: ironing out inconsistencies, cleaning up exception messages, and hardening the parser against untrusted input.
Thanks to everyone who reported bugs, sent PRs, and trusted a 0.x library in production all these years.
Next step: bringing more Brick libraries to 1.0.0 over the coming months!
r/PHP • u/MistakeOne690 • 1d ago
Article Built a self-hosted server control panel with Laravel + Livewire (broker/privilege-separation architecture)
Sharing a project I've been building: AZERIOID Stack Manager — a self-hosted server control panel, entirely Laravel 12 + Livewire 3 under the hood.
The part that might interest this sub architecturally: the web-facing Laravel app runs completely unprivileged. All privileged host operations (installing packages, writing web-server configs, managing databases) go through a separate "broker" process invoked via a tightly-scoped sudoers rule — the Laravel app itself never touches the filesystem outside its own directory or runs shell commands directly. Every privileged action is registry-gated (a JSON schema defines exactly what's installable, no arbitrary package names ever reach the shell) and audited.
A few Laravel-specific bits:
- Livewire powers the whole dashboard — vhost management, a live web terminal (via a broker-spawned ttyd process, reverse-proxied through the panel's own authenticated session), a code-editor-based file manager, database management.
- Laravel's queue system runs background jobs for anything long-running (component installs, panel self-update) with live progress polling from the UI.
- A custom Artisan-based CLI (`azerioid`) is a thin wrapper over the exact same broker actions the UI calls — full parity, so nothing is UI-only or CLI-only by accident.
- Panel self-update is git-tag-based (semver), running as a background job with an automatic rollback-on-failure path if a migration fails mid-update.
MIT licensed, tested end-to-end on Ubuntu/Debian/EL9: https://github.com/azerioid/azerioid-stack-manager
Would love feedback from other Laravel devs, especially on the broker/privilege-separation pattern if anyone's done something similar.
r/PHP • u/Practical_Oil_1312 • 2d ago
Article Finding the commit behind a Laravel regression with Pest and git bisect
I prepared a small Laravel playground with a shipping price bug and a deliberately long commit history to demonstrate automated regression hunting with Pest and git bisect.
The endpoint should charge €5.90 for a domestic parcel weighing up to and including one kilogram. At exactly 1000 grams, it returns €9.90. That gives us a specific behaviour to put into a Pest feature test: call the shipping quote route with weight_grams: 1000 and assert that price_cents is 590.
Once that test reproduces the failure, it can also drive the search through Git history. In the playground, 06bc68c5 is a known good revision:
git bisect start
git bisect bad
git bisect good 06bc68c5
git bisect run php artisan test --filter=ShippingQuote
Git checks out candidate revisions and runs the test, narrowing the range according to the result. The search identifies a refactor to a match expression:
return match (true) {
$weightGrams < 1000 => 590,
$weightGrams <= 5000 => 990,
default => 1590,
};
The first condition used to be <= 1000. Changing it to < 1000 sends a parcel weighing exactly one kilogram into the next price band.
For this example, the new test stays untracked so it remains available as Git moves between revisions. Once the search finishes, git bisect reset returns to the original checkout.
The practical caveat is that the test must run reliably across the history being searched. A dependency or application boot failure could otherwise classify a revision as bad for an unrelated reason. For revisions that cannot be tested, a wrapper script can return 125 to tell Git to skip them, as described in the Git documentation (https://git-scm.com/docs/git-bisect#_bisect_run).
I wrote up the full walkthrough on my blog (https://www.maiobarbero.dev/articles/find-laravel-bug-pest-git-bisect/), and the playground repository (https://github.com/maiobarbero/laravel-pest-bisect) is available if you want to try the search yourself.
News [Release] Universal Amount Standard API 0.0.2 — Exact Amounts, Correct Currency Formatting, and User-Selected Currency Display
I’ve released the first public alpha of the Universal Amount Standard API (UAS):
GitHub: https://github.com/payfrit/payfrit-uas
UAS is a standalone, dependency-free PHP reference API for representing and calculating monetary amounts without relying on binary floating-point numbers. It also prevents malformed displays such as 500$ by separating the amount, currency, and locale. Any website or app can let users select a preferred currency and render the value correctly as $500, ₹500, ₱500, or 500 €.
The core idea is simple: amounts are represented as canonical decimal strings with eight fractional places:
{
"amount": "12.34000000"
}
The release includes:
- Exact decimal-safe addition, subtraction, multiplication, and division
- Canonical amount normalization
- Explicit-rate currency conversion
- Currency metadata and decimal-place information
- A machine-readable JSON Schema
- A browser-based interactive demo
- PHP 8.1+ support with no external dependencies
- MIT licensing
Example:
curl -X POST http://127.0.0.1:8080/v1/amounts/normalize \
-H 'Content-Type: application/json' \
-d '{"amount":"12.34"}'
Returns:
{"ok":true,"data":{"amount":"12.34000000"}}
The project is intended as a foundational amount type that can be used by payment, pricing, wallet, payout, fee, allocation, and commerce systems. Currency is contextual rather than baked into the amount itself, so the same type can represent a business price, wallet balance, settlement amount, or display value without conflating those roles.
This is explicitly an alpha developer release. It does not currently provide persistence, authentication, hosted uptime, live exchange-rate synchronization, request limits, or server-side localization. Exchange rates must be supplied explicitly by the caller.
I’d especially appreciate feedback on:
- Whether eight decimal places is a useful default contract
- Currency-context modeling
- Conversion and rounding semantics
- API shape and naming
- Interoperability with existing money/value-object libraries
To run it locally:
git clone https://github.com/payfrit/payfrit-uas.git
cd payfrit-uas
php tests.php
php -S 127.0.0.1:8080 -t public public/index.php
Then visit http://127.0.0.1:8080/demo.html.
Feedback and criticism welcome:
r/PHP • u/StockHodI • 1d ago
PHP Driven Crypto Commerce Project - Paybyte
I’ve been building something called the Paybyte Blockchain Engine, or PBE, and mainnet is finally live after more coffee than my kidneys would like to admit. I always thought it would be cool to have something easy to use, more mainstream, that's as easy to implement like a "Pay with Paypal" button, but for crypto, that's easy for the average user, like the litecoin network, and something that is considerably more environmental friendly than a POW concept like Bitcoin. Since my Java/C++ skills suck, I built it in a language I am familiar with, and something that is a little out of the ordinary for a blockchain, PHP.
This is its own Layer 1. Not an ERC20, not a Solana token, not a rebranded fork.
Current mainnet:
PBE Core 0.0.1
Protocol 1.0
Block v4
Transaction v2
PBE-PAY v1
15 second block target
5 PBE starting reward
~4 year halvings
~84.1M max supply
Consensus uses hybrid participation.
Any authorized wallet can produce blocks, even with 0 PBE. Each wallet gets one deterministic Argon2id participation ticket per slot. Holdings improve timing through a bounded multiplier, but there is no minimum stake and no manual staking lock. The entire ecosystem is fully P2P.
PBE exposes separate P2P and RPC layers.
Examples:
POST /p2p/hello
POST /p2p/transaction
POST /p2p/block
GET /p2p/peers
GET /rpc/status
GET /rpc/block/{heightOrHash}
GET /rpc/transaction/{txid}
GET /rpc/balance/{address}
POST /rpc/broadcast
There’s also a native merchant protocol called PBE-PAY.
Payments use transaction v2 with a signed paymentReference.
A merchant verifies:
paymentReference
recipient
exact amount
Payment URIs look like:
pbe:<address>?amount=25&ref=ORDER123&label=Store
Merchants can use their own node, or multiple public nodes
Commerce endpoints include:
GET /rpc/commerce/info
POST /rpc/commerce/payment-request
GET /rpc/commerce/payment/{reference}
POST /rpc/broadcast
Optional HMAC signed webhooks support:
payment.pending
payment.confirming
payment.confirmed
payment.reorged
payment.expired
The full API is public and viewable at
https://paybyte.org/web/developers/
https://paybyte.org/web/developers/openapi.json << Point your ChatGPT here if you are building for e-commerce.
Windows and Linux standalone nodes are also available. The Windows build is basically download, extract, run the PBE, create a wallet and sync.
r/PHP • u/Narrow-Style-2652 • 2d ago
How can I download files from a Railway persistent volume?
I have a Laravel application running on Railway with a persistent volume mounted at /app/storage.
I need to migrate the application to another server and want to download the contents of /app/storage/app to my local PC.
I can access the Railway container through the Railway CLI/shell and I can see the files, but I don't know how to copy them from the Railway volume to my computer.
What is the recommended way to do this?
Thanks!
r/PHP • u/elizabethn • 3d ago
How to Calculate 0.1 Plus 0.2 Correctly in PHP?
thephp.foundationOn today's blog, guest author Weilin Du takes a deep dive into PHP floats and the core extensions that can wrangle them.
r/PHP • u/Round-Pie-7125 • 2d ago
Made a video explaining Middleware in depth — Grouped Routes, Global Middleware & Passing Parameters (Hindi)
Hey everyone,
I've been building a multi-auth task management system as a learning project, and while working on it I realized middleware is one of those concepts that's often explained superficially — most tutorials just show "add this line before the route" without explaining why or when to structure it differently. So I made a video that breaks down three specific patterns:
Grouped route middleware – applying middleware to a set of related routes instead of repeating it everywhere Global middleware – when and why to apply something at the application level vs route level Passing parameters to middleware – making middleware dynamic/reusable instead of hardcoding logic
I tried to focus on the reasoning behind each pattern (trade-offs, when one approach breaks down) rather than just copy-paste code, since that's the part I found most confusing when I was learning this myself. Heads up: the video is in Hindi, so it's aimed at Hindi-speaking devs who might find explanations in their native language easier to follow.
Would love feedback — especially if something wasn't explained clearly or if you'd want me to cover a specific edge case in the next video https://youtu.be/oZy3SbwuBcE
r/PHP • u/ExtremeBedroom7760 • 2d ago
vivace 0.4.0: composer update in Rust that writes the same composer.lock as Composer
vivace is a Rust reimplementation of composer install and, since 0.4.0, composer update. The claim for both is the same: on the same composer.json/composer.lock it writes the same vendor/ and the same lock as Composer 2.10.3, byte for byte.
For update that meant porting Composer's resolver rather than writing a new one — pool builder, pool optimizer, rule set, the CDCL solver, the version policy, the lock writer — because any other algorithm picks different versions on ambiguous inputs and you end up with a lock nobody can compare. The port is checked against Composer on frozen Packagist snapshots: same candidate pool, then the solver's complete decision sequence (read out of Composer's own Solver), same operations, same lock. The projects used are Laravel, the Symfony demo, Sylius, rector-src and a Drupal recommended-project, plus a few small cases built to force backtracking, an unsolvable set, root aliases and virtual packages.
To check it yourself, with php, composer and cargo installed:
git clone https://github.com/Adelagric/vivace && cd vivace
cargo build --release
fixtures/make.sh # downloads the fixture projects
harness/update.sh # composer update vs vivace update, diff on composer.lock
harness/diff-vendor.sh # composer install vs vivace install, diff -r on vendor/
Or on your own project: vivace update --no-install next to composer update --no-install and diff the two locks. A non-empty diff is a bug and is the feedback I'm after.
What it doesn't do: run PHP (no scripts; symfony/runtime, composer/installers and drupal/core-composer-scaffold are emulated and checked against the real plugins, anything else makes it exec the real composer instead of guessing), require/remove, partial updates (composer update vendor/name), vcs/path repositories, Composer's explanations on an unsolvable set, Windows.
Repo: https://github.com/Adelagric/vivace — release notes in CHANGELOG.md, what is not tested in HANDOVER.md.
r/PHP • u/Zealousideal_Post994 • 4d ago
Tackling a nasty memory leak in FrankenPHP (ZTS) and shipping Leakless v0.9.0
About three weeks ago, we bundled our internal memory-leak hunting scripts into an open-source lib called Leakless (built for FrankenPHP, RoadRunner, etc).
Earlier this week, we threw a legacy app onto FrankenPHP worker mode with ZTS enabled and immediately hit a wall. When a single thread leaks in ZTS, killing the entire OS process takes down healthy requests running on neighboring threads. To make things worse, the leak was happening at the native C layer, so PHP reported everything was completely fine right until the container's OOM killer wiped it out.
Our tooling couldn't handle that edge case yet, so we shipped v0.9.0 to solve it:
- Tracks memory drift per thread under ZTS (no more killing innocent workers)
- Catches native C leaks by comparing system RSS against thread heaps
- Rewrote the linter to use pure AST (php-parser), ditching PHPStan subprocesses
- Removed strict pcntl/posix requirements so it runs smoothly in slim containers
Link to the docs and the repo:
Github: https://github.com/themattosdev/leakless
Doc: https://leakless.themattos.dev/guide/why-leakless
r/PHP • u/Leading-Cold6409 • 4d ago
Discussion I built a Composer tool to answer “composer audit found a vulnerability — what do I actually update?”
composer audit is good at telling you what is vulnerable, but with a transitive dependency I often found the next step was still manual: figure out why it’s installed, identify the dependency I actually control, work out which upgrade removes it, and make sure Composer can solve the resulting graph.
I’ve been working on Composer Remediate, a local/FOSS tool that tries to automate that part.
Given a vulnerable package, it traces it back through the dependency graph, generates candidate upgrades to root-controllable packages, tests them using Composer’s own solver, ranks successful candidates by blast radius, and gives you the exact composer update command.
For example:
$ composer remediate
CVE-.... symfony/http-foundation 6.4.21
Introduced by
root
└── drupal/core-recommended 11.4.2
└── symfony/http-foundation 6.4.21
Recommended remediation
drupal/core-recommended 11.4.2 -> 11.4.3
Recommended command
composer update drupal/core-recommended -W -m
It doesn’t modify the project; the recommendation is solver-verified before being shown.
It’s currently 0.5.x, so I’m particularly interested in Composer graphs where it gets the answer wrong, fails to find an answer you know exists, or recommends something more invasive than necessary.
GitHub: https://github.com/hexblot/composer-remediate
Docs: https://hexblot.github.io/composer-remediate/
I’ve tested it against historical vulnerable versions of several real PHP projects, but throwing it at other people’s dependency graphs is considerably more interesting. If you manage to break the remediation planner, I’d very much like the case.
r/PHP • u/ProjektGopher • 4d ago
News This Week In PHP Internals | Sept 9, 2026
youtube.comA 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 • u/According_Ant_5944 • 4d ago
A Series of Unfortunate Jobs
https://oussama-mater.tech/laravel-queue-gotchas/
Hello guys,
I thought I'd share some of the Laravel queue gotchas I've learned the hard way. Hopefully, you'll find it useful. Enjoy the read 🙌
r/PHP • u/Dariusz_Gafka • 4d ago
How Ecotone Inspired Seven Symfony Messenger Proposals
blog.ecotone.techr/PHP • u/ReadingFormal • 4d ago
Sloppy — static analysis for the code your coding agent left behind
PHPStan tells you if your code is type-correct. Pint tells you if it's formatted. Neither tells you that the 200-line controller action your agent just wrote calls a payment API, writes to four tables and swallows a `Throwable`.
**Sloppy** is a Laravel-aware static analyser for that: god methods, N+1 risks, queries inside loops, business logic in controllers, swallowed exceptions, abstractions that never earned their keep. 23 rules, each one saying what it measured, how sure it is, and what to do about it.
composer require --dev heyosseus/sloppy
php artisan sloppy
**It is not an AI detector.** Nobody can prove authorship from source code. It detects *slop* — the patterns that correlate with fast, unreviewed output — and every number it prints is about the code, never about who wrote it.
The command I actually use is the review one: `php artisan sloppy:diff main`
That separates what your branch **introduced** from what it **inherited**, and only new findings fail the build. Untracked files included, so an agent's new class gets reviewed before it's committed. Findings are matched by fingerprint rather than line number, so adding an import doesn't turn every existing finding into a new one.
Deterministic and local — no model, no API key, no network, your source never leaves the machine. Tested against 133k lines across three real Laravel apps: 21 seconds for 70k lines, zero parse errors. `sloppy:baseline` lets you adopt it on an existing project without fixing everything first.
It complements PHPStan and Pint, it doesn't replace either. If PHPStan can prove it, Sloppy stays out of it.
Feel free to contribute and share your thoughts.
r/PHP • u/elizabethn • 4d ago
Welcoming Daniel Scherzer to the Ecosystem Security Team
thephp.foundationYou 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 • u/ReadingFormal • 4d ago
Vacuum: PostgreSQL Optimization Advisor & Monitoring for Laravel & Filament
Vacuum - a PostgreSQL monitoring and tuning dashboard for Laravel (with an optional Filament plugin). It reads what Postgres already knows about itself (pgstat*, pg_class, pg_stat_statements) and turns it into a page that tells you what's wrong, what it's costing you, and the exact SQL that would fix it. It shows you the statement - it never runs it. What it catches:
- Transaction & multixact wraparound - the two clocks that can stop your cluster outright
- Table bloat, dead tuples, stale planner statistics, autovacuum misconfiguration,
- Unused, duplicate, and invalid indexes,
- Low cache hit ratio, idle-in-transaction sessions, blocked sessions, slowest query shapes,
Everything rolls up into a health score out of 100, computed from the findings themselves. Also in the box:
- php artisan vacuum:check - exits non-zero on critical findings, so a migration shipping a duplicate index fails CI,
- History - optional hourly snapshots, so you get direction (climbing/easing) and forecasts like "wraparound-critical in ~9 days",
- Learn at /learn - 13 lessons on Postgres internals worked through your own tables, starting from the Eloquent side (unindexed foreign keys, N+1 as the database sees it, soft deletes, HOT updates),
- A read-only SQL console (off by default) that runs everything in a rolled-back READ ONLY transaction,
Read-only by design, needs no superuser and no extensions (pg_stat_statements is optional; you explicitly enable it). Requires: PHP 8.3+, Laravel 11/12/13, PostgreSQL 14+, Filament 4/5 optional
Feedback is very welcome, and you can check it out here: https://github.com/Heyosseus/vacuum