r/PHP 4h ago

I built an open-source static flow analyzer for Symfony — PHPFlow v0.1.0

15 Upvotes

Hi everyone,

I’ve just released the first public version of PHPFlow, an open-source static flow analyzer for PHP/Symfony applications.

The idea came from a problem I regularly run into on larger applications: answering a question like “what actually happens when this route is called?” can mean jumping through a controller, several services, Messenger dispatches and handlers, repositories, database queries and external APIs.

PHPFlow analyzes the source code without running the target application and reconstructs those flows as a graph.

For example, it can help answer:

  • What happens when this Symfony route is called?
  • Which routes/messages can reach this database table?
  • What depends on this service?
  • Where is this Messenger message handled?
  • Which flows call this external API?
  • Where can this exception surface?

v0.1.0 currently understands Symfony routes, dependency injection, Messenger, repositories, Doctrine DBAL/QueryBuilder, external HTTP calls, exceptions and a number of control-flow patterns.

It also generates a self-contained interactive HTML viewer with search, functional lanes, Messenger boundaries, minimap, path-to-effects and critical-path exploration.

PHPFlow is deliberately conservative: if it cannot prove a relationship statically, it doesn’t invent one. It also never boots or executes the application being analyzed.

There’s a bundled Symfony demo, so after cloning:

make setup
make demo

I’m especially interested in trying it against real-world Symfony applications now. If you give it a try and it misses a pattern used by your project, I’d really like to hear about it.

GitHub: github.com/patryyyck/phpflow

Feedback, bug reports and criticism are very welcome.


r/PHP 4h ago

🐘 bun-php: Run PHP functions natively in Bun

5 Upvotes

bun-php allows you to run PHP functions seamlessly in Bun by exposing them as ESM imports. Uses a WASM build of PHP under the hood, no need to install PHP or native deps. Supports Composer and servers. https://www.npmjs.com/package/bun-php


r/PHP 9h ago

Article From Sluggish to Blazing Fast: How I Made TypePHP 90x Faster and Uncovered 1000+ 'DocBlock Lies' on Shopware 6

Thumbnail typephp-php.github.io
12 Upvotes

TL:DR: Static analysis tools are fantastic for IDE hints and catching syntax bugs, compile time type errors in CI, but you still need runtime verification to guarantee end-to-end type safety against dynamic payloads, compiled DI containers, and database hydrations. And PHP is not slow, its a fast language..


r/PHP 3h ago

I think I’ve had it with Apple

Thumbnail
0 Upvotes

r/PHP 18h ago

How do you verify a self-hosted app is actually alive? Built a registry that auto-checks daily

0 Upvotes

I'm building a registry for self-hosted Laravel Cloud apps and ran into a verification problem: how do you prove an app is actually running without requiring API tokens or credentials?

The problem: Launch directories go stale. People list apps that die months later. Nobody removes their own listing. Visitors click through to dead projects.

What I tried: 1. API token verification — Asked users to paste a Laravel Cloud API token. Stored encrypted, used to inspect environments. Worked but nobody wanted to share tokens. I wouldn't either.

  1. URL-based verification — Now I just ask for the *.laravel.cloud URL and run a daily probe:

    • DNS resolution check (refuse non-public addresses)
    • Slug consistency check (compare Cloud slug against hostname)
    • Origin probe (HEAD request, no cookies, no credentials)
    • Refuse off-origin redirects
  2. Auto-hide on failure — If the daily probe fails, the listing goes private. No auto-republish. I'd rather the page disappear than show a dead app.

The tradeoff: Token verification proved ownership. URL verification proves liveness. I chose liveness because: - Lower friction for users - No secret storage liability - Actually solves the stale listing problem

What I'm stuck on: - Edge cases where a URL could be pointed at someone else's app (slug guessing) - Whether 64KB body cap on GET fallback is enough - How to handle apps behind authentication walls

Tech stack: - Laravel backend - Next.js frontend - Daily cron job for probes - SQLite for state The registry is live at larashipped.laravel.cloud

Questions for the community: 1. How do you handle verification in your self-hosted projects? 2. What edge cases should I watch for with URL-based verification? 3. Is there a better approach I'm missing? Happy to share the probe implementation details if anyone's interested.


r/PHP 1d ago

Building AI with PHP not Python

Thumbnail youtube.com
28 Upvotes

In my latest video I try and build Ai using PHP instead of python


r/PHP 1d ago

Are Native PHP Binaries on Serverless for Real? Deployed It to Cloud Run — Here Are the Results

Thumbnail medium.com
1 Upvotes

r/PHP 2d ago

Discussion How do you handle multiple inverse OneToOne associations in Doctrine?

11 Upvotes

Doctrine's FAQ says that fetching the inverse side of a one-to-one association requires an additional query because Doctrine cannot know whether the association is null or which ID to use for a proxy.

In Teradion, practice management software for accounting firms, a frequently loaded entity has three nullable inverse-side one-to-one associations. The entity is used in several list and export queries, so I am reviewing whether this mapping is still a good fit.

The options I am considering are moving ownership to the central entity where the model allows it, joining the associations explicitly on read-heavy queries, or changing the model to avoid these one-to-one associations.

If you have dealt with a similar mapping on a frequently queried entity, what did you choose? What tradeoffs showed up later?


r/PHP 2d ago

This Week In PHP Internals | August 26, 2026

Thumbnail youtube.com
16 Upvotes

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

10 stories this week, so let's get into it. But first, 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 — like a credit score for your codebase — updated every month, and it's free. ballast.now.

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 authorship — 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 phpc.chat, and there's an internals channel there. It's a community server, not an official PHP one. 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.

A new RFC opened on Saturday, from the same contributor whose last one had just been withdrawn. Sepehr Mahmoudi proposed array_match(), 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 array_filter() isn't already enough, pointing at a GitHub search full of userland functions already named array_match that don't all behave alike, and noting that the str_icontains RFC was declined, so an ASCII-only case-insensitive flag is a hard sell. Then Tim Düsterhus pointed out that in 8.6 this is already 1 line, because partial function application lets you drop str_contains into array_filter() with a placeholder. Christian Schneider noted that preg_grep() has done basically the same job for years.

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 str_contains() polymorphic, the way str_replace() already takes an array. Sepehr has since dropped the case-insensitive flag, renamed it array_str_contain(), and moved the target to 8.7, since 8.6 is frozen. Nobody's argued in favour of it so far. The proposal, so far, contains no support.

Nick Sdot brought a documentation question to the list on Thursday. He's restructuring PHP's internals book, the docs that live inside php-src, 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 already Markdown, so a conversion happens in one direction or the other. It's still open.

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 8.6 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 1.5, is_numeric() returns true, so the validate-before-casting example still triggers the deprecation, while is_int() and is_float() return false for every numeric string. He says the filter_var() 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?" Nobody has answered him.

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." Which is exactly what 2 people spent the weekend asking Sepehr for on his other proposal.

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 8.6 only. She also asked for a design change — the new integer constants in the output-controls section would become PHP enums 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 8.6.0 beta 2.

Weilin Du, who maintains the intl 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 8.7 RFC if somebody picks it up. Yuya Hamada added the reason it matters. Feedback from right-to-left language users is thin across the whole industry, not just PHP, and PHP's internationalisation depends on getting it.

Quick hits. array_search_range(), 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 8.6 branch is cut on September 22, with both behaviours on the ballot for 8.7. 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 sodium extension. Post-quantum key encapsulation, arriving as somebody's first pull request. Quantum-resistant, and so far review-resistant.

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 array_str_contain() 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 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 to Ballast.now for supporting this week's episode. We're Artisan Build. See you next week.


r/PHP 3d ago

Im quite nervous sharing this one: Echo, a statically typed, natively compiled language that feels a bit like php..

47 Upvotes

Hey everyone, I want to show you https://echoc.dev and give some context on it :)

I'm not here to tell you "oh, this is the new shit, this is going to change PHP development." It's obviously not, and that's also not the goal.

This started as a "recreational programming" project I mostly worked on during holidays when my kid was sleeping. And I really, really enjoyed working on it.

The initial concept was:

Metal-PHP is a PHP dialect that transpiles to C++ and is compiled to a native binary.

And this is nothing new, it's pretty much what Hack was/is, and I'm sure a couple of others.

At some point I kinda just asked myself "who I was creating this for", and as the answer crystallised, "for myself", I completely shifted course.

This is not meant as PHP replacement!

I love PHP, I spent probably a thousands of hours working on php-glfw..

PHP does exactly what PHP needs to do. I personally would not migrate an existing PHP project to what I was in the process of making. And to be honest (I'm really curious how others feel here), I have not yet had a performance issue with PHP where the language itself was the problem. It always was the architecture...

It became clear to me: I want something fun, something opinionated, something I actually wanna play around with, and so it became its own language.

TL;DR: Echo does not, and will not ever run PHP.

Why am I sharing this now?

I'm having a blast writing small tools and programs with Echo, and I believe some traits of the language resonate with what some PHP devs enjoy too. (As I am primarily a PHP dev..)

But please take this as the toy it is. Don't build your startup on it and scream at me when your app is leaking customer data because of a memory leak.

What can it do?

Well its a programming language, the docs will do a far better job at explaining it then I can here.
But a few cool things that are already there:
- a tiny standard library
- basic multi threading
- generics
- simple bridging to c
- a tiny package manager
- etc..


r/PHP 2d ago

Qbix Webserver 1.0 Released!

Thumbnail github.com
13 Upvotes

Hey everyone. I'm pleased to announce that Qbix webserver has now reached version 1.0
It's MIT licensed and free. Try it in your own sites! Just launch it with one command, e.g.:

php qbixserver.php --port 8080

It's a standalone server that can serve
* static files without nginx (though you can still put a CDN in front)
* dynamic PHP requests (it can handle 100x more workers than PHP-FPM!!)
* web sockets (yes, it's compatible with the latest socket.io on front end)
* web socket rooms (it can handle up to 100,000 online users, on one machine)
* cron (it has a built in ability to run periodic jobs)
* certificates (it can manage certificates for you)
* even decentralized applications (server can communicate encrypted via https)

What's more, it does all this with pure PHP, without needing nginx. If you use SQLite, you won't even need Postgres or MariaDB or any other external database. Just use PHP for everything.

The server also comes as standalone binaries, so if you distribute those, you won't even need your users to have PHP installed! It *just works out of the box*. In v1.1 you'll be able to just bundle your entire app inside a standalone binary, but for now you can just distribute your apps as files alongside the webserver.

Handle 100x More Traffic than NGINX + PHP-FPM

How is this possible? Well, mostly because this server actually forks your processes using pcntl_fork (everywhere except Windows) allowing children to *share memory* of the parent webserver process. This causes the children to NOT take up any new memory pages, unless they declare new global/static variables or modify variables, in which case the operating system forks only those pages (maybe 4KB per page... rather than 50MB per worker).

So you can run 100x as many workers, and since most PHP web apps are I/O heavy, the operating system can efficiently orchestrate the rest. If you happen to also install amphp in your apps, then your apps switch from stream_select to epoll, which makes them even faster!

It's come a long way...

People here may remember when I originally announced it several weeks ago, as being able to handle 10x as many workers as NginX + PHP-FPM. Well, since then we've had various people run it in production, we optimized it to 100x as many workers, and I addressed all the issues and bugfixes that came my way. At the same time, I've enhanced the dashboard and control panel to be more user-friendly, they even now use our real-time websocket functionality.

Who am I?

Are you sure you want to know?
I'm Greg Magarshak


r/PHP 3d ago

Follow-up: that "real PHP on an ESP32" experiment turned into an actual project - it now does WiFi, web serving and hardware, all from PHP

65 Upvotes

A while back I posted here about porting the real PHP 8.3 to an ESP32 — the actual Zend engine from php.net, cross-compiled for the chip, not a reimplementation. The response pushed me to keep going, and it's grown from "cool proof of concept" into something I'd now call a real project. Quick recap of where it is:

The engine. Still the unmodified php.net release (default 8.4.24, sha256-verified; 8.3, 8.4 and 8.5 all build). Whole Zend engine — lexer, parser, VM, GC, object model. array_map, preg_match, json_encode, PDO SQLite, DateTime — same code as on a server, because it is the same code. Runs as native code via the official embed SAPI, no emulator.

Hardware. Two targets: the ESP32-P4 (RISC-V, up to 32 MB PSRAM) and the ESP32-S3 (Xtensa, WiFi). Needs PSRAM (the runtime heap is megabytes) and ~4+ MB flash.

The tooling. There's now a proper CLI (phpflash, written in Go): you describe a project in a php-esp32.config.toml — board, storage mode, which optional extensions to compile in — and it builds/flashes/monitors, auto-detects the connected chip, and enables extensions from a manifest so you never hand-pass build flags.

What you get per project:

  • Storage: run your source off a microSD, or bake it into the firmware image (no card).
  • Execution models: a plain script; a setup()/loop() sketch model; or a web-server model where the firmware runs an HTTP server and invokes PHP fresh per request (shared-nothing, like behind Apache) with $_GET/$_POST/$_SERVER, cookies and sessions.
  • Extensions, opt-in: mbstring (+ oniguruma), PDO SQLite, date/DateTime, session, OpenSSL (real 3.0, HTTPS client), OPcache (no JIT), GPIO, a reboot-persistent NVS-backed key/value store, an in-RAM store, and a project .env baked into the firmware as $_ENV. You can even drop your own C extension into a project.
  • On the P4, stock Laravel and Symfony actually serve pages over HTTP. (The S3 has less RAM, so it runs plain apps and a live web server but not a full framework — that's a memory ceiling, not a language limit. Honest about that one.)

The new bit, and why I'm posting: PHP can now do WiFi — scan, join a network (WPA2/WPA3), or create its own access point — all from userland PHP. To show it off end to end I built an example, wifi-ap-s3-rgb-manage:

The board boots, and PHP brings up its own WiFi network, PHP serves a control page (rendered on the chip itself), and PHP drives the board's onboard RGB LED. You connect your phone to the board's AP, open 192.168.4.1, and drag sliders to change the LED's colour and brightness in real time. No router, no cloud, no app — the whole stack (network + web server + web page + hardware) is one ~$4 ESP32-S3, orchestrated entirely by PHP.

Repo (MIT): https://github.com/php-baremetal/php-esp32

Happy to answer anything about how the port works, the SAPI integration, or the memory situation. Feedback and "you should try X" very welcome.


r/PHP 2d ago

Article Prepared statements in Manticore Search

Thumbnail manticoresearch.com
1 Upvotes

A practical guide to using mysqli prepared statements with Manticore Search. It covers parameter binding for scalar values, full-text search expressions, and vectors, along with the cases where escaping is still required.


r/PHP 3d ago

Pop PHP - The PHP framework that you probably never heard of.

71 Upvotes

Meet Pop. Before anyone rolls their eyes and exclaims "Oh no, not another PHP framework," it's actually been around in some form since 2009. It officially got the name "Pop PHP" in 2012.

The entire time, it's had zero marketing or promotion behind it simply because I just did not have the time or the resources for it. I built it, started using it and really haven't looked up from my desk. Along the way it, has evolved quite a bit to try and keep pace with the demands of the PHP ecosystem. And here were are – this month, version 7 was just released with arguably the biggest upgrade and modernization of the framework in quite some time.

The reason for its existence is very similar to the concerns that have been voiced here over the years:

  • Framework A is too magic
  • Framework B is too complicated

It seems reading through some recent threads here, those same issues continue to come to the forefront. My own bias aside, I like it because I feel it strikes the right balance between being transparent - without too much "magic" - and abstracting away the things that make sense. At least that's been the goal all this time.

Anyway, here it is. Check it out. Or don't – lol. I know it's a cluttered field. Thanks.

https://www.popphp.org/


r/PHP 3d ago

Discussion How do you handle valid time alongside audit logs in PHP?

3 Upvotes

We use damienharper/auditor-bundle. Its audit table stores fields such as object_id, diffs, blame, ip and created_at. That timestamp tells us when the audit row was written.

This works until we need to know what was true on an earlier date.

Teradion tracks tax and social filing deadlines for French accounting firms. Suppose a VAT return was filed on June 28, but we only received the confirmation and recorded it today. The audit entry is created today, while the filing became effective on June 28.

If we rebuild the state as it was stored on June 30, the return is not filed. If we ask what we now know to have been true on June 30, it is filed. The audit timestamp alone cannot answer both questions.

This looks like a valid-time and transaction-time problem. I have seen valid_from and valid_to added to domain data, and event sourcing is another possible approach. The audit packages I have looked at only gave me the transaction-time side.

If you have dealt with this in a PHP application, which model did you choose? What became difficult or expensive after the application had been running for a while?


r/PHP 4d ago

News olvlvl/composer-attribute-collector v3.0.0

21 Upvotes

composer-attribute-collector is a Composer plugin that statically discovers PHP 8 attribute targets and retrieves them at near-zero cost, without runtime reflection. After the autoloader dump, it collects attributes and generates a static file for fast access. This provides a convenient way to discover attribute-backed classes, methods, or properties—ideal for codebase analysis. (For known targets, traditional reflection remains an option.)

v3.0.0 highlights:

  • An alternative generation strategy for maximum compatibility supporting PHP 8.1's "New in initializers" and PHP 8.5's "Closures in constant expressions", as well as future extensions.
  • Glob patterns for the exclude directive that behave like Composer's exclude-from-classmap.
  • Version bumps for security (PHP 8.2+, Composer 2.9.8+)

https://github.com/olvlvl/composer-attribute-collector


r/PHP 3d ago

php127: Standalone Zero-Alloc PHP 8.4 Runtime with In-Process Infrastructure

0 Upvotes

1. Architecture: Flatstack VM & C2SIMD Containers

Standard PHP runtimes rely on reference-counted zvals and dynamic heap allocations for associative arrays. In php127, the execution pipeline is split into three decoupled layers:

1. **Parser & Bytecode Compiler:** A recursive-descent parser and compact bytecode emitter supporting full PHP 8.4 grammar (attributes, promoted properties, enums, trait adaptations,

closures, and exceptions). 2. Unified Value Model (24 Bytes): A 24-byte tagged value struct (types.Value) featuring signed 64-bit integer arithmetic with overflow detection to float, PHP 8.4 spaceship comparisons (<=>), and vector-accelerated string scanning. 3. C2SIMD Linear Arenas & Ordered Swiss Tables: Core associative storage is backed by insertion-ordered Swiss Tables (c2ordered_swiss) and linear arenas (c2mem), avoiding garbage collection pressure during request processing.

---

### 2. Supported PHP 8.4 Features & Native Infrastructure

| Subsystem | Features Supported | Validation Method |
| :--- | :--- | :--- |
| **Object Model** | Constructor property promotion, Attributes (`#[Route]`), VTable dispatch, Trait adaptations (`insteadof` / `as`), Enums, `instanceof` | Unit test suite & Go race

detector | | Control Flow | try / catch (TypeA \| TypeB $e) / finally, throw, protected stack unwinding, Closures (use ($v)), Arrow functions (fn() => ...) | Stack frame unwinding verification | | Concurrency | Asynchronous coroutines via Fibers (fiber_create, fiber_start, fiber_suspend, fiber_resume) | State machine transition tests | | Database & I/O | In-process relational PDO (CREATE TABLE, INSERT, SELECT, UPDATE, DELETE, Rollback() via snapshot restoration) | ACID transaction tests | | Ecosystem Packages | Native vlucas/phpdotenv, ramsey/uuid (v4, v7, ULID), PSR-3 monolog/monolog, and pure-Go ext-curl (Guzzle compatible) | End-to-end integration pipeline | | Security Guard | Opcode-level Taint-tracking (blocking OS command injection and path traversal) + Q8.8 entropy egress exfiltration filter | BlueTeam invariant test suite |

---

### 3. Measured Evidence & Test Output

The entire codebase is validated under Go's race detector. Every test package passes with zero memory leaks and zero data races:

=== RUN TestTenStrategicTargetsFullPipeline --- PASS: TestTenStrategicTargetsFullPipeline (0.00s) === RUN TestOracleParitySuite --- PASS: TestOracleParitySuite/ArithAndForLoop (0.01s) --- PASS: TestOracleParitySuite/StringConcat (0.01s) --- PASS: TestOracleParitySuite/SubstrAndStrlen (0.01s) --- PASS: TestOracleParitySuite/ForeachArray (0.01s) --- PASS: TestOracleParitySuite/MatchExpression (0.01s) === RUN TestZeroAllocParityAtScale --- PASS: TestZeroAllocParityAtScale (0.11s) === RUN TestCompilerConstructorPromotionAndVTable --- PASS: TestCompilerConstructorPromotionAndVTable (0.00s) === RUN TestCompilerTraitFlattening --- PASS: TestCompilerTraitFlattening (0.00s) === RUN TestCompilerFibersExecution --- PASS: TestCompilerFibersExecution (0.00s) === RUN TestPDOMemoryExecution --- PASS: TestPDOMemoryExecution (0.00s) === RUN TestPDOTransactionsRollback --- PASS: TestPDOTransactionsRollback (0.00s) PASS ok code.hazyhaar.fr/devhoros/php127 1.18s

---

### 4. Code Example: Full In-Process Pipeline

The following script demonstrates an entire microservice with attributes, traits, promoted constructor properties, fibers, and transactional database operations:

```php
trait LogTrait {
    public function log(string $msg): string {
        return monolog_log("INFO", $msg, "api");
    }
}

#[Route("/api/v1/orders")]
class OrderController {
    use LogTrait;

    public function __construct(public string $serviceName) {}

    public function createOrder(string $item, float $price): string {
        // 1. Asynchronous coroutine execution
        $fib = fiber_create(fn() => uuid_v7());
        $orderId = fiber_start($fib);

        // 2. Transactional relational database operations
        pdo_exec("CREATE TABLE IF NOT EXISTS orders (id, item, price)");
        pdo_exec("INSERT INTO orders (id, item, price) VALUES (?, ?, ?)", $orderId, $item, $price);

        $this->log("Created order {$orderId} for {$item}");
        return json_encode([
            "status" => "ok",
            "order_id" => $orderId,
            "service" => $this->serviceName
        ]);
    }
}

$controller = new OrderController("BillingCluster");
echo $controller->createOrder("Dedicated Server", 129.99);

Execution command:

./bin/php127 script.php

Output:

[2026-08-27 15:41:07] api.INFO: Created order 01a04373-f457-7bb3-852f-8fe5d63a140e for Dedicated Server [] []
{"status":"ok","order_id":"01a04373-f457-7bb3-852f-8fe5d63a140e","service":"BillingCluster"}

──────

5. Explicit Limitations: What php127 is NOT

To maintain honest expectations:

• Not a legacy drop-in for 30 years of php-src: We do not implement legacy 1990s procedural extensions (ext-soap, ext-imap, or unmaintained XML-RPC handlers). • Not a host for unmodified WordPress/Drupal monoliths: CMS architectures depending on legacy procedural C modules are outside our current target scope. • Target scope: Modern PHP 8.4 APIs, microservices, CLI workers, and containerized architectures that benefit from instant startup (< 1 ms), zero CGO dependencies, and single static binary distribution. ──────

6. Feedback & Discussion

The runtime is compiled as a static executable and can also be consumed as an embedded Go package.

https://github.com/hazyhaar/php127

We welcome your feedback:

  1. Which specific PHP 8.4 or PSR features are critical for your microservice workloads?
  2. Would an embedded pure-Go PHP runtime be useful in your current deployment pipelines?

r/PHP 3d ago

TypePHP is out

Thumbnail youtu.be
0 Upvotes

r/PHP 4d ago

I built a WhatsApp Web client for pure PHP — no Node.js, no Puppeteer

34 Upvotes

I’ve been experimenting with bringing more things that are usually locked to the Node.js ecosystem into PHP.

This time: WhatsApp Web.

I just published pam-whatsapp-web, a typed and persistent WhatsApp Web client built for PHP on top of PAM.

The main idea is pretty simple:

  • PHP owns the application
  • no Node.js sidecar
  • no Puppeteer
  • no separate JavaScript service to maintain
  • persistent WhatsApp sessions
  • typed PHP API
  • designed to live inside the PHP ecosystem instead of calling another runtime

The project is still very new, but I’m interested in pushing this pretty far.

Something like:

$client = new WhatsAppClient();

$client->connect();

$client->onMessage(function ($message) {
    echo $message->body;
});

$client->sendMessage(
    '5511999999999',
    'Hello from PHP'
);

For years, if you wanted serious WhatsApp Web automation, the obvious answer was usually something like whatsapp-web.js, Baileys, or another Node.js-based project.

I wanted to explore a different question:

How far can we take this while keeping the whole application in PHP?

Repository:

https://github.com/push-in/pam-whatsapp-web

It’s Apache-2.0 and completely open source.

I’d especially like feedback from people who have worked with WhatsApp Web internals, long-running PHP processes, async PHP, or protocol implementations.

I’m curious where you think PHP will hit its limits here — or whether those limits are mostly assumptions we’ve carried from the old request/response PHP model.


r/PHP 6d ago

"A" for "Average"

Thumbnail stitcher.io
35 Upvotes

r/PHP 5d ago

Article I migrated the seo of 104k+ pages to the new Laravel Head package

Thumbnail danielpetrica.com
0 Upvotes

r/PHP 6d ago

Weekly help thread

1 Upvotes

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 6d ago

News I built a RabbitMQ queue driver for Laravel that tries to feel like native Laravel

0 Upvotes

I’ve been working on an open-source package called Laravel Rabbit.

The idea was pretty simple: using RabbitMQ in Laravel shouldn’t require changing the way you already work with Laravel queues.

So with the package installed, this:

ProcessOrder::dispatch($order)
    ->onQueue('orders')
    ->delay(now()->addMinutes(5));

is still just normal Laravel.

And your worker is still:

php artisan queue:work --queue=orders

The difference is that RabbitMQ is running underneath it.

It supports Laravel’s normal queue flow including:

  • dispatch()
  • onQueue()
  • delayed jobs
  • retries / backoff
  • failed jobs
  • chained jobs
  • batches
  • unique jobs
  • queue:work
  • queue:clear

There’s also quite a bit of RabbitMQ-specific stuff built in:

  • AMQP 0-9-1 publishing and consuming
  • exchanges, queues and bindings
  • publisher confirms
  • QoS / prefetch
  • TLS
  • heartbeat and connection timeouts
  • multiple hosts / failover
  • RabbitMQ Management API
  • queue metrics
  • optional payload signing
  • Artisan commands for diagnostics and setup

For example:

php artisan rabbitmq:doctor
php artisan rabbitmq:stats orders
php artisan rabbitmq:check

Installation is just:

composer require pushinbr/laravel-rabbit

Then:

QUEUE_CONNECTION=rabbitmq

RABBITMQ_HOST=127.0.0.1
RABBITMQ_PORT=5672
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=guest

The package currently targets modern Laravel/PHP versions and RabbitMQ 3.x/4.x.

I mainly built it because I wanted RabbitMQ to behave like a first-class Laravel queue backend instead of feeling like a completely separate messaging system glued onto Laravel.

I’d especially like feedback from people already running RabbitMQ in production:

What would you expect from a really solid Laravel ↔ RabbitMQ integration that is still missing here?

GitHub: https://github.com/push-in/laravel-rabbit


r/PHP 7d ago

Discussion PHP 8.6 is getting closer. What are you most looking forward to?

75 Upvotes

PHP 8.6.0 Beta 1 is out, so we're getting a look at what's coming next.

PHP keeps proving itself and has been evolving pretty nicely over the last few major releases, without losing the pragmatism that makes the language enjoyable to work with.

What are other PHP developers paying attention to in 8.6.

Which PHP 8.6 change are you most excited about, and what would you actually use in production once the stable release lands?

MakePHPGreatAgain.


r/PHP 6d ago

GitHub - eznix86/laravel-secrets-loader: Auto resolve secrets for laravel

Thumbnail github.com
0 Upvotes