r/PHP 4d ago

Weekly help thread

2 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 16d ago

Discussion Pitch Your Project 🐘

14 Upvotes

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 4h ago

Article No more issues

Thumbnail stitcher.io
24 Upvotes

r/PHP 21h ago

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

17 Upvotes

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!


r/PHP 1h ago

Laravel Middleware in Hindi: Create, Alias & Apply to Routes

Upvotes

I’ve made a Hindi tutorial on Laravel 12 Middleware covering the complete flow from creating Middleware to applying it on routes.

In this video: • Create custom Middleware • Understand the handle() method • Register Middleware • Create Middleware aliases • Apply aliases to routes • Practical route examples

🎥 Tutorial: https://youtu.be/USOjYgaKUDk

For those learning Laravel 12, hope this helps clear up how Middleware actually works.


r/PHP 1h ago

flatbb: a free, open-source PHP forum designed to be extended by AI assistants (no framework, SQLite/MySQL, plugin marketplace)

Upvotes

I've just released Flatbb 0.1.4, a flat, lightweight forum written in plain PHP 8.1. MIT licensed, free.

  • No framework, no Composer, no build step. Upload, open the installer, done in 2 minutes. Runs on the cheapest shared hosting or a 1 GB VPS.
  • SQLite or MySQL 5.7+. Start on SQLite, move to MySQL later with one command.
  • Built for AI-assisted development. The repo ships CLAUDE.md / AGENTS.md and docs written for AI tools. Open the folder in Claude Code or Cursor, say "add a badge plugin", and it knows the hooks, the rules and how to publish.
  • Plugin marketplace with one-click install from the admin panel; publish your own plugin with php flatbb plugin:publish.
  • Discourse-style three-column layout, dark mode, Markdown editor with image upload, full-text search, 7 interface languages.

The interesting part is the developer story: every hook, region and API function is documented in generated Markdown, plugins are plain prefixed functions with a manifest, and the repo includes instruction files for Claude Code / Cursor / Copilot. In practice you describe a plugin in one sentence and the AI writes it, checks it (php flatbb plugin:check) and publishes it to the marketplace.

Download: https://www.flatbb.com/download - Plugins: https://www.flatbb.com/market

It's early (0.1.x) and I'd love feedback, bug reports and plugin ideas.


r/PHP 1d ago

I'm selling my 37+ ElePHPant Collection

60 Upvotes

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


r/PHP 7h ago

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

Thumbnail github.com
0 Upvotes

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)


r/PHP 8h ago

Laravel 12 + Breeze + Spatie Permissions — Complete Role & Permission Setup

0 Upvotes

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.


r/PHP 1d ago

Digital Sovereignty Is Written in PHP

Thumbnail thephp.foundation
127 Upvotes

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.


r/PHP 1d ago

This Week In PHP Internals | Sept 2, 2026

Thumbnail youtube.com
9 Upvotes

Hello world, it's Wednesday, September 2, 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? You can measure the code it produces, but the number that matters is how much of it survives. Ballast reads your git history — never your code — and gives you stable velocity plus a durability score between 300 and 850. Updated monthly, and it's free. ballast.now.

This week's top story starts with a rule most of us never read. Luca Rodenhäuser opened Wednesday with the line in the scanner that defines a PHP identifier — in bytes, not characters. Every byte at or above hex 80 is accepted, so $x followed by a no-break space is a second variable that looks identical. He proposed a per-file declare to pin that down, then scanned the 250 most-installed Packagist packages and found exactly one identifier that would break.

Larry Garfield suggested skipping the opt-in and having PHP 9 enforce it, since Symfony fixes its one class and 99.99% of developers never notice. So Luca reran it against the top 5,000 packages. Half a million files turned up fourteen hundred forty-seven non-ASCII identifiers, 91% of them in math-php, where the variable names spell the formula. He reported the result himself, writing: "So the honest answer to '99.99 % won't notice' is that one library would notice 888 times, and its author chose that style deliberately and has shipped it for years." Then came 3 questions. Derick Rethans asked whether 13.7 kilobytes of tables in every PHP process is worth it. Juliette Reinders Folmer asked what it does to variable variables. And Rowan Tommins asked how much of this is rejecting names and how much normalising them. Each sent him back to measure, and he split his proposal into 3: a diagnostic, a well-formedness rule, and a conformance rule. He says he owes the thread a problem statement.

Nick Sdot opened an RFC on Thursday to end PHP's endorsement of PEAR. He started about three months ago, going back through every previous discussion and every unvoted attempt, and he's already built a static mirror so the command-line tool keeps working. His case is that PEAR is partly broken, spammed, barely active and now unmaintained. Rowan Tommins backed it. On the argument that PEAR deserves more time to be revived, he wrote: "If that's not long enough, how long is? If the site stays alive in its current state for 10 years, it will continue to be exploited by spammers and probably worse. That's not in anyone's interest." Nick then put a number on the whole thing. 6 packages are still publishing to PEAR. 3 of them are PEAR's own infrastructure. 2 more were recently marked unmaintained. Which leaves exactly one independent package still being maintained, and that's Net_SMTP. Nick gave its maintainer a one-word aside in the thread, and the word was legend.

Sjoerd Langkemper told the list on Friday he intends to open a vote on making the number-base functions throw. His RFC makes octdec, hexdec, bindec and base_convert throw a ValueError on invalid input. His framing was that this isn't controversial — the list agreed to it in an earlier base_convert proposal — and that the RFC is mostly procedure. Tim Düsterhus disagreed on the substance. He argued that passing untrusted input to these functions is an expected use case, which means developers will want to catch what comes back, and drew the line firmly: "The Error hierarchy is not intended to be caught, though. It should thus use something from the Exception hierarchy." Sjoerd asked whether that distinction is written down anywhere. It is. Tim pointed him at the throwables section of the coding standards policy, and quoted it: "The Error hierarchy MUST NOT be used for errors that are expected to be thrown (and caught) during normal operation of a PHP program. … a parsing function that is expected to be used with untrusted input must not throw an Error if the input is malformed." Base conversion, Tim argues, is parsing.

The array-filtering function we covered last week came back on Sunday, renamed array_str_contains and retargeted at 8.7. Sepehr Mahmoudi's case is that filtering an array by substring is common enough to deserve C, instead of paying for a closure on every element. Seifeddine Gmati went first and went broad. He couldn't remember ever writing that code, said the same argument would justify array_str_starts_with and a few hundred more combinations, and pointed out that nothing in the name tells you it filters. He called it redundant. Bruce Weirdan turned the performance claim around, asking whether the closure overhead itself should be fixed, since that would speed up every builtin that takes a callable. Kamil Tekiela asked what the numbers actually are, and said he'd never hit it as a bottleneck. Sepehr then walked back his own strongest claim, agreeing that a filter has to read the whole array rather than stopping at the first match. He's promised static analysis across Packagist to back the frequency claim.

Last week's top story was the list arguing about machine-written mail in the abstract. This week it stopped being abstract. Juris was the one who did the work, drafting the guideline text he thinks a newcomer should get. It says to write the message yourself rather than rephrase yourself with an LLM, and that there's no requirement to have perfect English on that list — plenty of productive contributors are more fluent in C and PHP than in English. Then he demonstrated it instead of asserting it. He wrote his next 3 paragraphs in Latvian, machine-translated them, and sent both versions in the same message, arguing the imperfect translation stays closer to what he meant than anything a chatbot would phrase for him. Then Sepehr Mahmoudi acknowledged that he had been having AI write his replies. Weilin Du asked the thread to stop naming people, saying it had become a place to point fingers rather than a place for technical debate. Yuya Hamada apologised for going too hard, and it stopped there. There's still no written policy.

Théo Attali introduced himself on Saturday with a first contribution and a small, well-argued gap. PHP's DATE_RFC3339_EXTENDED gives you milliseconds with a numeric offset, but a lot of systems expect the same instant with a Z on the end, which is what JavaScript's toISOString produces. He proposed a constant for it, and flagged the flaw in his own idea before anyone else could. A format string containing a literal Z can't force the value into UTC. Andreas Heigl agreed, with unusual standing to do it — he added the extended constants. He wouldn't add any more now, since a constant only helps people who've already upgraded, and pointed Théo at a userland formatter built on one line that has worked since PHP 5.3. Théo revised on the spot, proposing an instance method instead. Then Tim Düsterhus redirected it. He pointed out that PHP 8.6 ships the first piece of a new date and time API, and that the proposed Time\Instant is deliberately timezone-less — which makes a Zulu-format method an obvious thing to add there.

An offer arrived on Saturday from a name the list hadn't seen before. Riaan de Beer has written libxml-rs, a native-Rust reimplementation of libxml2 that's compatible at the C ABI level, and he asked whether php-src would be open to a test build against it. He says xmllint and xmlcatalog come out byte-identical against libxml2 2.15.3 across eleven hundred ten tests, and he's careful about the ask — an experimental alternative provider, not a default. What the list answered was his opening sentence. He'd said libxml2 has been unmaintained since December 2025, and Pierre replied that the repository has had many commits since, and that a mature XML library not cutting frequent releases isn't an abandoned one. 2 more contributors agreed. One wrote that libxml2 was only briefly unmaintained before new maintainers stepped up, and the other added that one of those maintainers helps php-src out directly. Nobody has answered the actual question yet.

The question of whether RFCs should ship a userland polyfill got 2 substantial answers this week. Nicolas Grekas answered from the Symfony side, which is the side that does the work. Every polyfillable feature ends up in the symfony/polyfill monorepo anyway, and the one that ships is often not the one in the RFC. Polyfills, he concluded, need a separate workflow. Then Tim Düsterhus answered the other argument for them, which was Larry Garfield's suggestion that a polyfill gives you something to benchmark the C against. Tim wrote: "I believe performance should not be a factor in deciding what should be part of the stdlib and what should not: Performance is a moving target and what might be true today might no longer be true tomorrow… Once we add something to the stdlib we need to maintain it for the next 15+ years. (Broad) usefulness and good API design must be the deciding factors…" He added that PIE has made building a private extension easier than it's ever been.

Quick hits. 3 releases landed in 3 days. Calvin Buckley put out 8.4.25, a security release, so that one's worth doing today. Daniel Scherzer released 8.5.10, a bugfix. And Matteo Beccati has 8.6.0beta2 up for testing. Last night Nick Sdot replied to the nameof RFC to say he'd like to see it in 8.7 — and the message he was replying to was posted in May of 2023. 3 years and 3 months is a long time to keep a browser tab open. And on the named parameter lists thread, somebody answered Larry Garfield's question from a fortnight ago about why people treat a small data structure as unworthy of being a class. The answer wasn't performance. It's cognitive cost — returning 2 values as an array and unpacking them at the call site is easier to hold in your head than a dedicated object, and static analysis can describe that array well enough that you don't lose much.

So that's the week. No RFC has been in the voting phase for 3 weeks running. Somebody scanned half a million PHP files to work out what a PHP identifier is, and came back having split his own proposal into 3. There's an RFC to end PHP's endorsement of PEAR, which has one maintained package left on it. There's a real disagreement about whether base conversion counts as parsing, which decides which kind of throwable it gets. A new array function has 4 people against it and nobody for it. And the argument about who writes the mail on that list got a concrete answer. 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 15h ago

How I used AI to migrate a 10k-line PHP 5.6 monolith to Laravel in 14 days.

Thumbnail
0 Upvotes

r/PHP 2d ago

Sponsoring opensource: need your input

20 Upvotes

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/


r/PHP 1d ago

Sponsor @swoole on GitHub Sponsors

Thumbnail github.com
0 Upvotes

I just sponsored @swoole. Go Sponsor your open source dependencies!

TypePHP


r/PHP 2d ago

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

7 Upvotes

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?


r/PHP 2d ago

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

5 Upvotes

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


r/PHP 1d ago

Laravel CSV Upload: How do you identify the exact row and field causing an error?

0 Upvotes

When importing CSV files in Laravel, handling validation errors can become frustrating—especially when you need to know exactly which row and which field caused the problem.

For example, instead of getting a generic database/validation error, you can identify something like:

Row 27 → email field is invalid Row 43 → date_of_birth has an incorrect format Row 58 → employee_id already exists

I recently worked through a Laravel approach for identifying the exact CSV row and field responsible for an import error.

I explained the implementation and error-handling flow here:

👉 YouTube: https://youtu.be/__IglcnI5d4

Curious how others handle CSV import errors in Laravel. Do you validate the entire file first, or process and report errors row-by-row?


r/PHP 1d ago

Discussion TapHost: Static and PHP local server host from mobile with git, tunnel (Testing phase)

0 Upvotes

Hello, my name is Suprio Paul. I'm from India. I have built an app named Taphost. My app just recently approved in Google Play Store.

Features:

  1. Static/PHP local server host from mobile

  2. Github integration, you can login with a browser or paste your access token to access all the repositories you have.

  3. PHP servers are DATABASE supported, with a clean interface to manage your database.

  4. FTP file access

  5. Host your website to the world with local tunnel (loca.lt) (ngrok will be added in upcoming updates)

  6. Import / export project to share your projects with everyone.

  7. Internal file Exposed: so that any external code editor can access the project files (like acode)

If you want to test my app, dm me your email, i will add you to the testers list and i will send you the testing link(Google Play Store Testing Link).

Thank you.


r/PHP 1d ago

News Community Corner Podcast: Longhorn PHP 2026 with Ian Littman

Thumbnail phparch.com
0 Upvotes

Hello all!

I'm the host of the Community Corner Podcast, and I'm trying to help the Longhorn PHP 2026 organizers get the word out about the conference (Austin, TX, October 15–16, 2026). I did an interview with Ian Littmann and think it's worth a listen. They have a ton of great speakers this year and tickets are available now.


r/PHP 1d ago

Laravel 12 – “Target Class [X] Does Not Exist” Error? Here’s How to Fix It

0 Upvotes

I recently came across the Laravel error:

Target class [X] does not exist.

This usually means Laravel is unable to resolve the class you're trying to use. Depending on the situation, the cause can be:

Wrong namespace or missing use statement Incorrect class name Middleware/controller not found Incorrect middleware registration or alias Cached configuration/routes

I put together a short 4-minute walkthrough showing how to identify the actual cause and fix the error in Laravel 12.

YouTube: https://youtu.be/z4IrG8CCOsY

If you've encountered "Target class [X] does not exist" in Laravel, what was causing it in your case?


r/PHP 2d ago

Article Safer Sign in with Apple Library for PHP

Thumbnail medium.com
10 Upvotes

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


r/PHP 2d ago

Roman Pronskiy Leaves The PHP Foundation Board and Brent Roose Joins

Thumbnail thephp.foundation
95 Upvotes

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! ❤️🐘


r/PHP 2d ago

Another PDF library has entered the chat.

17 Upvotes

The Pop PDF library has been around for a while and just got a major facelift to support a wider range of built-in features in v6. Personally, for most of my career, working with PDFs has been a crucial part of what I do daily. This library started as my own little project years ago, but like many out there it was suited for a small set of features. If you work with PDFs in any extensive capacity, you might find yourself reaching for multiple libraries to solve you problems. Some write, but don't read. Some read, but don't write. Some just do the HTML-to-PDF thing. Others just do the merge thing.

The Pop PDF attempts to roll all of those features into one component, plus some.

Main Website: https://www.poppdf.org/

Docs Website: https://docs.poppdf.org/


r/PHP 2d ago

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

4 Upvotes

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?


r/PHP 2d ago

Laravel Breeze, but for the layers underneath your controllers

0 Upvotes

Your Laravel API and your Blade UI should not own two copies of your

authorization rules.

One command scaffolds one set of services, repositories and policies —

then a versioned JSON API, a Blade UI, or both on top. The stack flag

only changes the transport.

It's not a framework. It copies real code into your app, then you can

delete the package and everything keeps working.

Policies actually enforced, no unscoped repository queries, a login

endpoint that can't be used to enumerate accounts, two CSP profiles,

no npm. Security defaults mapped to the OWASP Top 10:2025.

Laravel 10–13, PHP 8.2+, MIT. Tell me what's wrong with it.

Install

composer require cachewraith/laravel-template-structure

php artisan cachewraith:install --stack=both

Link

https://packagist.org/packages/cachewraith/laravel-template-structure