❌

Normal view

I built a Laravel package to replay Stripe billing lifecycles offline

I built Cashier Dunning because testing failed-payment flows in Laravel is surprisingly difficult.

It records a real Stripe billing lifecycle once and replays it offline through your application's actual webhook route, including signature verification and real listeners.

It can replay trial expiration, failed payments, retries, cancellation and resubscription in about a second.

It also tests duplicate and out-of-order webhook delivery.

No Stripe account, API keys in CI, or network access during replay.

It's MIT licensed and currently supports Laravel 11–13.

GitHub: https://github.com/impruthvi/cashier-dunning

I'd especially appreciate feedback from anyone running Stripe/Cashier in production. What billing edge cases would you want something like this to test?

submitted by /u/impruthvi to r/PHP
[link] [comments]

I built Phphone: Full PHP 8.4 runtime and CLI for Android and iOS

​Hi Reddit, ​I built Phphone, an open-source mobile runtime and anti-framework designed to run full PHP 8.4 directly on mobile devices with zero mandatory cloud dependencies. ​Instead of writing apps in Dart (Flutter) or relying on heavy JavaScript runtimes (React Native), Phphone embeds the complete Zend Engine into a lightweight native C++ chassis, fully functional across both Android and iOS. ​Architecture & Low-Level Highlights: ​Full Native Binaries: Cross-compiled PHP 8.4 (dynamic library on Android, static library on iOS) paired with embedded SQLite3, full libcurl, and OpenSSL. It supports standard PHP libraries, outgoing HTTPS calls, and complex local data pipelines right out of the box. ​IP Protection (AES-256): To prevent source code extraction from decompilation, all application files in src/ are cryptographically encrypted using AES-256 derived from the project's build keystore. Decryption occurs on-the-fly directly in memory inside the C++ runtime. ​Hardware-Accelerated UI: The frontend runs inside the platform's native hardware-accelerated WebView over an in-memory micro-server loop (localhost), guaranteeing smooth 60 FPS transitions via standard HTML/CSS/JS. ​Minimal Footprint: Base Android APK is ~19MB with near-zero idle CPU usage and low RAM consumption. ​Cross-Platform Ready: Full Android and iOS support is completed. The CLI toolchain automates local scaffolding and builds for both platforms, and our first production app is currently queued for release on both Google Play and the iOS App Store. ​Live APK Demos Available: To demonstrate that this is a production-ready application engine and not just a theoretical experiment, the website hosts 3 pre-built APKs you can download and test: ​System & Hardware Demo: A showcase app interacting directly with 14+ native phone APIs and sensors, plus an interactive gradient generator. ​2D Gaming Demo: A high-performance 2D game running on PixiJS, powered by local logic. ​3D Gaming Demo: A fully interactive 3D scene built with Babylon.js, demonstrating hardware-accelerated WebGL graphics backed by the native PHP engine. ​Whether for enterprise offline-first software, edge compute nodes, multimedia apps, or 2D/3D games, Phphone proves that modern PHP and standard web technologies can build fast, sovereign mobile apps. ​Documentation, CLI & APK Downloads: https://phphone.xyz ​I’d love to hear your thoughts on the low-level C++ embedding, binary optimizations, or the anti-framework approach to mobile architecture.

submitted by /u/Efficient-Zone-7374 to r/PHP
[link] [comments]

I built an attendance tool in 2023 to escape a paper register. I rewrote it last week, and past me made four real mistakes.

In 2022 I started teaching programming to schoolchildren. On the first day I was handed the curriculum for the web track. Nobody could tell me who had written it. After a full year of lessons, the students were supposed to produce an HTML page with a background image and some pictures on it.

I threw it out and wrote a new one.

The other half of the job was the register. Paper, one sheet per child. On every sheet you marked attendance, wrote in the topic of the lesson and the number of hours. That was every group, every week, by hand.

At some point I had enough and built something. It was 2023, I knew PHP, and I wrote it the way you write things at eleven at night: procedural, one file per action. Some colleagues started using it too. Five commits in a single day, two of them named "Add files via upload".

Last week I opened that repository for the first time in three years.

What past me got right

More than I expected. Passwords went through password_hash and password_verify. Eighty-nine prepared statements, and not one place where $_GET was pasted into SQL. For something written to stop filling in paper, that is not bad.

What past me got wrong

htmlspecialchars appears zero times in the whole codebase. Every value from the database goes straight into the page.

The upload handler takes the extension from the filename the browser sent and writes the file into a served directory. You can upload a .php file and then request it. That is remote code execution.

Attendance was stored as (student_id, date, status). No group. A student who came to two different tracks was one row per day, and there was no way to say which of the two they had missed.

A student had a single group_id, so anyone attending two tracks could not be recorded at all.

Teachers and students lived in two tables with two separate login handlers. Anything that concerned both had to be written twice.

The rewrite

Laravel 13 and Postgres. The domain survived and nothing else did.

The interesting part is what the 2023 version never had: tasks that grade themselves.

I do not run student code. It goes to Wandbox, which has been running untrusted code for years and does nothing else. On a project this size, running my own sandbox would mean one person keeping isolation correct in their spare time, and I would rather that person were not me.

I expected to stitch several backends together, the way these things usually go: Wandbox for most languages, the Go playground for Go, the Rust playground for Rust. Then I read the Go playground's compile endpoint. It takes the program body and a version. There is no field for standard input. I posted stdin and input alongside the program anyway, in case the field simply went undocumented, and the program read EOF both times.

Without stdin there is no test case with input data, and without that there is no assessment worth the name. Every task collapses into "print this constant". So I use one backend. Wandbox covers fourteen languages, Rust, Pascal and SQL included.

Grading runs on a queue, because I measured it. One Go build on Wandbox takes about twenty seconds. Five test cases one after another would be a minute and a half. I send them in parallel, four at a time, which got it down to sixty-two seconds. Still far too long to hold an HTTP request open, so submitting queues the work and the page polls for the result.

Some test cases are hidden. For open cases the student sees the input and the expected answer. For hidden ones they see only whether it passed. Show everything and the solution gets fitted to the known answers instead of made to work.

Three findings that cost me an afternoon each

Wandbox's Rust compiler rejects the warning option set, and does not say so. It returns exit status 1 with empty output, which is indistinguishable from a program that printed nothing.

Mono prints non-ASCII as question marks until you set Console.OutputEncoding, and once you do, it prefixes the output with a byte order mark. Comparing that against the expected answer fails on an invisible character. The dotnetcore image on Wandbox does not build at all, so mono is the only option.

Laravel's trans_choice() falls back to the fallback locale in cases where __() returns the key unchanged. My source language is Russian and my fallback was English, so Russian pages rendered English text in exactly the places where a count was involved. No test caught it; I saw it in a screenshot.

What I am not sure about

Leaning on a free public service at the moment a student submits an exam is the obvious weak point, and I do not have a good answer for the day Wandbox is down. My reasoning is that the alternative is worse for a project this size. If you have run the other way and maintained your own isolation, I would like to hear how that went.

MIT, Laravel 13, PHP 8.3+, Postgres, no keys or accounts needed to try it. The seed builds a demo school with four tracks and a month of attendance.

https://github.com/dripips/ItCube

submitted by /u/Successful_Mode8468 to r/PHP
[link] [comments]

YouMeOS Microverse: Running FrankenPHP + SQLite as an embedded, zero-Docker desktop runtime

Hey r/PHP, I wanted to share a practical implementation of FrankenPHP and native SQLite powering a self-hosted personal WebTop: YouMeOS Microverse. A major problem with self-hosted PHP applications is distribution: telling non-technical users to install Docker, Nginx, and MySQL creates massive friction.

How We Utilized FrankenPHP:

  • Embedded Desktop Engine: In addition to standard Docker Compose, our Electron desktop app bundles a portable FrankenPHP binary with SQLite.
  • Zero External Dependencies: Users download the .exe, .dmg, or .AppImage, and it runs a local Caddy + PHP 8.3 server process in the background without Docker or local PHP installations.
  • Resource Footprint: Cold starts take ~1 second, with idle RAM usage significantly lower than traditional Apache/Nginx + PHP-FPM + MySQL stacks.
  • Caddy Worker Integration: Takes advantage of FrankenPHP's fast application handling directly from local storage.

Livesite: www.youmeos.com but the microverse can be ran locally using our docker container or binaries.

Source code and configs: https://github.com/YouMeOS/youmeos-microverse
Release builds: https://github.com/YouMeOS/youmeos-microverse/releases

Feedback on our FrankenPHP runner and Caddyfile setup is welcome.

submitted by /u/DoItForTheXP to r/PHP
[link] [comments]

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!

submitted by /u/brendt_gd to r/PHP
[link] [comments]

GitHub - eznix86/laravel-analytics: Data Build Tool the eloquent way

At work, I kept writing the same thing: a few analytics tables, a cron job to rebuild them, and the same SQL copy-pasted into three models. Change one definition, forget to update one copy, and suddenly two dashboards quietly disagree.

There’s `dbt`, which solves this problem for data teams, but it means bringing Python and a second toolchain into a Laravel project. So I tried the same idea in PHP.

An analytics model is an Eloquent model with one query on it:

```php
class Revenue extends Model implements AnalyticsModel
{
use Analytics;

public function computes(): Query
{
return $this->from(Order::class)
->where('status', '<>', 'cancelled')
->per('customer_id')
->measure('total', 'sum(amount)');
}
}
```

Then `php artisan analytics:sync` works out what depends on what and builds everything in the right order.

After that, it’s just Eloquent:

```php
Revenue::query()->where('total', '>', 1000)->get();
```

A few things it does:

* The `GROUP BY` comes from the dimensions you declare, so you never have to write them twice.
* it has Incremental, microbatch, and snapshot buildsthe, same ideas as dbt.
* Runs on PostgreSQL, MySQL, and SQLite with the same commands.

### What it does not do

Every model in a dependency chain has to use the same connection.

That means you can’t, for example, import a SQLite query directly into a PostgreSQL query. This could be solved with an import mechanism, and I am still thinking about a better way to make that work in an Eloquent-like way.

### Why not just use a query class with dependency injection?

A query class, like the action pattern in `App\Queries`, that you inject wherever you need it is perfectly fine.

If the aggregate is fast, you need live numbers, and you only have one or two of them, write the class and skip this package.

The issue is that it computes on every read and you have zero indexes.

Cache the query? Now you’re stuck dealing with stale data.

There’s another problem: each layer (CTEs, subqueries, etc.) gets re-run instead of being reused.

You can use query classes can be composable by calling each other, but a shared subquery is still recomputed inside every caller. This package composes by reference.

For example, you can have a `StgOrder` model representing a transformed version of the `Order` table. It gets built once, and the models that depend on it simply select from the finished table.

This package can append the rows that arrived since the last run, rebuild one day at a time, or keep one row per version with `valid_from` and `valid_to`.

This package will make a built table that can carry the indexes your read patterns need.

A helper like `Revenue::isStale()` can tell you when the data has passed its freshness window.

### Why not just write a job that rebuilds the table?

That’s essentially what the package does.

The difference is that the queries are reusable, and dependencies are propagated through the entire chain of downstream aggregates.

TLDR; You write reusable queries as a data person but in PHP.

Repo: https://github.com/eznix86/laravel-analytics

Read more about DBT: https://en.wikipedia.org/wiki/Data\_build\_tool

the real dbt guys: https://github.com/dbt-labs/dbt-core (for the curious folks)

submitted by /u/Eznix86 to r/PHP
[link] [comments]

Laravel 12 + Breeze + Spatie Permissions β€” Complete Role & Permission Setup

If you're working with Laravel 12 and want to implement proper roles and permissions, I put together a complete tutorial using Laravel Breeze + Spatie Laravel Permission.

In the video, I cover:

Laravel 12 + Breeze authentication setup Installing and configuring Spatie Permissions Creating Roles & Permissions Assigning permissions to users Checking roles and permissions Protecting routes with middleware Role-based access control Practical examples with Admin / Manager / Employee roles

πŸŽ₯ Full tutorial: https://youtu.be/vX46YQprMho Language:Hindi

Hope this helps anyone currently implementing RBAC in Laravel.

submitted by /u/Round-Pie-7125 to r/PHP
[link] [comments]

Long-term university system in PHP, microservices or modular monolith, given high staff turnover?

Hi everyone,

I work for a Brazilian federal university, and we're starting to plan a new integrated system that will serve the whole university community (from teaching-related services to internal administration). Expected usage is high (many requests across several domains), and the system needs to last many years.

One challenge specific to our context: being public sector, we have high staff turnover on the dev team, so whoever joins later needs to ramp up quickly.

We were initially leaning toward microservices, mostly to keep things scalable and modular over the long run, but after reading some older threads here I'm second-guessing that. Given a small-ish team, high turnover, a long lifespan, and multiple domains, would you recommend starting with a well-structured modular monolith instead of going straight to microservices?

And if microservices do make sense for a project like this, which PHP frameworks/tools would you suggest for building the actual APIs: Laravel, Symfony, Slim, Lumen, something else?

Genuinely trying to learn from people who've been through this. Any experience, even 'don't do it', is welcome!

submitted by /u/phumacinha to r/PHP
[link] [comments]

I'm selling my 37+ ElePHPant Collection

I'm parting with my ElePHPant collection after 13 years of collecting them. I'm raising money for my startup and also will need open heart surgery in the next 5 years. As the UG leader of PHP Vegas for over 10 years, its been a hell of a run. I still love PHP and my startup is built in it, but I also need funds as I'm quitting my full time to do all this. If we crossed paths before, thank you for all the fish. You can find my collection for sell here: https://www.ebay.com/sch/i.html?_dkr=1&iconV2Request=true&_blrs=recall_filtering&_ssn=pokemastercenter&store_cat=0&_nkw=elephpant&store_name=pokemastercenter&_oac=1

submitted by /u/ogprogrammer to r/PHP
[link] [comments]

Digital Sovereignty Is Written in PHP

Germany is spending €108 million to move its federal websites onto a TYPO3-based platform. The European Commission runs 770 sites on Drupal. Around 300,000 German federal users work on Nextcloud. All PHP.

Across Europe, when governments say "digital sovereignty," what they're describing is very often a PHP application. In our latest blog post, Sebastian Bergmann looks at where PHP runs in the public sector, why so little of that support reaches the maintainers underneath it, and three practical changes to procurement that could fix it.

submitted by /u/elizabethn to r/PHP
[link] [comments]

How do you ship CSS in a PHP package with a UI? Tailwind's content scanning makes it awkward

Building a Filament plugin with several admin pages. Wrote them with Tailwind utilities. Looked perfect locally, completely unstyled on a fresh install.

Obvious in hindsight: Tailwind generates only the classes it finds in configured content paths. A host app doesn't scan your vendor package's Blade files, so your utilities never get compiled. My dev panel scanned everything, which is why I didn't catch it.

The documented answer is to have consumers register a custom theme and add your package path to their Tailwind config. That's a build-step dependency you're imposing on everyone who installs your package, plus a support channel full of "did you run npm run build".

What I did instead: rebuilt on the framework's own components, plus a small hand-written stylesheet using the framework's CSS custom properties (`var(--gray-950)` rather than hex). That gets light mode, dark mode, and custom palettes for free. It's inlined once per process via a render hook, no asset publishing, no build step.

Then a test that fails if a utility class shows up in any package Blade file, because otherwise future me will absolutely reach for `text-sm`.

Genuinely curious what others do here. Ship a compiled CSS file? Require the theme? Avoid custom UI entirely?

submitted by /u/usamamuneer to r/PHP
[link] [comments]

I spent a full day on a "five-minute" Docker migration β€” PHP-FPM exit 139 on Colima

We moved off Docker Desktop to Colima ahead of the licensing changes. The migration was supposed to be boring. Then PHP-FPM started dying with exit code 139 (SIGSEGV) about a second after start β€” no logs, no core dump, no error. PHP CLI was fine, six thousand unit tests passed. Only the FPM master crashed.

The cause, three layers down:

  • OPcache asks the kernel for huge pages when its shared memory size is a multiple of 2 MB β€” mmap() with MAP_HUGETLB.
  • Docker Desktop's kernel rejects that cleanly, and OPcache just falls back to normal memory. Nothing to see.
  • Colima's kernel has huge page support compiled in. It starts the mapping, unmaps the old range, and then fails with ENOMEM. A correct kernel should never do this β€” a failed mmap() is supposed to leave the old memory untouched.
  • Under Rosetta 2, that hole isn't empty. The process touches it and dies.

The fix: a seccomp profile that returns EPERM for any mmap() carrying the huge-page flag β€” the same clean "no" Docker Desktop's kernel already gives. Two rules on top of Docker's default seccomp profile, applied machine-wide in colima.yaml, so there's no need for per-repo overrides.

A few things that do not help, in case you go looking: JIT settings, vm.overcommit_memory, ASLR. Enabling huge pages properly inside the VM is a trap too β€” php-fpm stops crashing and starts hanging instead, which is arguably worse.

Full write-up with the seccomp profile, a two-line curl+jq snippet that builds it from Docker's default, and the smaller escape hatches (opcache.memory_consumption=65, preferred_memory_model=shm):

https://blog.crazy-goat.com/en/colima-php-fpm-segfault-exit-139/?utm_source=reddit

submitted by /u/halaspiotr to r/PHP
[link] [comments]

Sponsoring opensource: need your input

Hi folks! Last year I started an initiative at PhpStorm to sponsor around 5 open source projects for a year. The first year has almost come to an end, and so I'm looking for 5 new projects to sponsor.

So I'm doing an open call to anyone who wants to nominate an open source PHP project they think is worth sponsoring. It could be large, it could be small, it could be something you built yourself. The only criteria is that it is open source and not a commercial product itself; and that it has something to do with PHP.

Just for reference, this was last year's announcement: https://www.reddit.com/r/PHP/comments/1nwd6hs/moving_php_open_source_forward/

submitted by /u/brendt_gd to r/PHP
[link] [comments]

Safer Sign in with Apple Library for PHP

An article about a defensive, framework-neutral PHP implementation of Apple Sign in with bounded JWKS fetching, modern JWT verification, full OAuth lifecycle support.

I recently reviewed a PHP application whose Sign in with Apple flow depended on an old library. The package had helped many developers, but its implementation reflected a different time in the PHP ecosystem. It included a frozen copy of JWT code and downloaded Apple’s public signing keys during every login using an unbounded network call. Hoping this article and repo would be useful to someone implementing apple sign in with php

github repo - https://github.com/binuka200/apple-sign-in-php

submitted by /u/No_Wedding2230 to r/PHP
[link] [comments]

Roman Pronskiy Leaves The PHP Foundation Board and Brent Roose Joins

As Roman Pronskiy's term on The PHP Foundation Board comes to an end, he is replaced by the wonderful Brent Roose, from a unanimous vote. Welcome Brent! πŸš€ And thank you for your years of dedication and commitment to The PHP Foundation, Roman! ❀️🐘

submitted by /u/elizabethn to r/PHP
[link] [comments]

I released PHPStreamServer 0.9: dynamic workers, native OS integration, and a redesigned message bus

Last year I shared PHPStreamServer here.

PHPStreamServer is an event-loop-based application server and process manager built entirely in PHP. It brings HTTP serving, worker supervision, scheduled tasks, logging, and metrics into a unified runtime.

Applications remain loaded between requests, with asynchronous execution powered by Revolt event loop and AMPHP.

I've been quiet publicly since my last post. During that time, I've continued using it as the primary runtime for my personal projects and improving it based on the experience. I've now released version 0.9, the project's biggest update yet.

One of the biggest architectural changes in 0.9 is that PHPStreamServer now requires FFI. This allows it to call native OS APIs directly for capabilities such as Unix-socket peer credential verification, parent-death signaling, and native file monitoring.

Some highlights:

  • Workers and scheduled tasks can now be registered and removed dynamically at runtime.
  • Message-bus commands are now a public API, allowing workers to send requests directly to the master process, for example, to start or stop on-demand workers dynamically.
  • The Unix-socket message bus was redesigned with security as a major focus. It now validates peer credentials and enforces source authorization, preventing unprivileged local users from managing a server running under a privileged account. Deserialization is also restricted to reject unsafe payloads.
  • File monitoring now uses native inotify on Linux and FSEvents on macOS, with polling as a fallback.
  • On Linux and FreeBSD, workers now use OS-level parent-death signaling, so they terminate instead of continuing as orphaned processes if the master process crashes or is killed.
  • Daemon startup now waits for the master process to initialize before reporting success.
  • Worker startup, shutdown, crash reporting, and log delivery are now more reliable.
  • The supervisor now reports non-zero worker exits and termination by operating-system signals.
  • The scheduler now supports named weekdays and months, presets such as @daily, and uses fractional-second delays for more accurate execution.
  • The public API now uses consistent worker terminology across all components.
  • Console and log output were redesigned to give PHPStreamServer a distinct and consistent visual identity.
  • Per-process network traffic monitoring now batches and sends only traffic deltas through the message bus, reducing inter-process communication overhead.

I also refreshed the documentation website with a redesigned landing page. You can check it out here:

Documentation:
https://phpstreamserver.dev/

GitHub:
https://github.com/phpstreamserver/phpstreamserver

Version 0.9 release notes:
https://github.com/phpstreamserver/phpstreamserver/releases/tag/v0.9.0

PHPStreamServer is still experimental and not yet recommended for production use.

I'd especially like feedback from developers working with long-running PHP applications, async PHP, FrankenPHP, RoadRunner, or OpenSwoole. What would you need to see before considering an application server like this for one of your projects?

submitted by /u/luzrain to r/PHP
[link] [comments]
❌