r/PHP

▲ 0 r/PHP

We added a test that fails if anyone injects a tenant-scoped service into a singleton

I build Teradion, practice management software for French accounting firms. The app runs in FrankenPHP worker mode, and each firm brings its own Brevo API key.

In that setup, a singleton holding one firm's key would stay alive while requests for other firms are handled. The code avoids that: tenant-scoped providers are not constructor dependencies. A factory creates a fresh client for each operation from the account passed as an argument. The key is stored encrypted and only decrypted inside the factory.

We have two tests around this rule. MultiTenantKeyIsolationTest runs two accounts in sequence and checks that the second does not receive the first account's key.

ProviderNotInjectedAsServiceTest is more direct. It scans src/Service, src/MessageHandler and src/Controller, then fails when a constructor takes NewsletterProviderInterface. It reads the source, so the Symfony container is not involved.

It is an architectural decision encoded as a grep, which feels a little blunt. Still, if someone adds that constructor dependency later, the test points at the class immediately.

Has anyone used this kind of structural test in a Symfony codebase?

reddit.com
u/These_Reality519 — 20 hours ago
▲ 16 r/PHP

The Secret Life of "Magic Null" in PHP

Some situations where you can use NULL instead of 0, or no arguments and it provides a nice feature that you could use every day.

exakat.io
u/exakat — 1 day ago
▲ 8 r/PHP

Pitch Your Project 🐘

In this monthly thread you can share whatever code or projects you're working on, ask for reviews, get people's input and general thoughts, … anything goes as long as it's PHP related.

Let's make this a place where people are encouraged to share their work, and where we can learn from each other 😁

Link to the previous edition: /u/brendt_gd should provide a link

reddit.com
u/brendt_gd — 1 day ago
▲ 8 r/PHP

Symfony: Experimenting with Issue-First Open Source Contributions (Symfony Blog)

Symfony experiment starting with their Language Tools library

symfony.com
u/equilni — 23 hours ago
▲ 0 r/PHP

PHP And Ai

Am I the only one who barely uses AI for PHP? except from occasional chat prompt or some prototypes or small bug fixes,Like I don't use full agentic tools like MCP, Codex, or even Claude CLI. I know LLMs seem to work find in other languages like Python or TypeScript,But in PHP’s Has dynamic features, and magic methods and it confuse AI to have absolute AI slop.
Or i am missing something

Note: English isn't my first language, so apologies for any mistakes!

reddit.com
u/Advanced_Egg4625 — 1 day ago
▲ 0 r/PHP+1 crossposts

PHP

I have an old Embarcadero PHP IDE version 3

I wanted to use it. Obviously, it does not work on my site as it now has PHP 8

So what I did I gave Claud the RPCL components PHP files to fix.

After 2 iterations, including showing the error file, it worked.

Now I can develop PHP with the old IDE.

reddit.com
u/WeightOdd5643 — 1 day ago
▲ 13 r/PHP

Enforce Runtime Generics on Third-Party Collections Libraries (Doctrine, Ramsey, Laravel Collections) with TypePHP

More than a week ago, I posted an introduction to TypePHP. Thanks to Michael Telgmann, a core maintainer at Shopware, TypePHP has been tested against Shopware’s massive codebase. So far, it has identified many DocBlock lies in the codebase PR, while also uncovering many edge cases on TypePHP’s end.

Today, I’d like to share a article guide on how to make existing third-party collection libraries, such as Doctrine Collections or Ramsey Collections, capable of enforcing reified collections without modifying their source code.

reified generics proof: Symfony Integration

typephp-php.github.io
u/rc0604 — 2 days ago
▲ 0 r/PHP

A Docker Compose environment for local PHP development — supporting PHP 5.6 through 8.5

Hi everyone!

I’d like to share docker-compose-php, an open-source Docker environment that I originally created seven years ago and still actively maintain and use in my daily work.

Its main purpose is to make it easy to run multiple local PHP projects—even projects that require different PHP versions—without installing PHP, a web server, or a database directly on your machine.

Key features:

  • PHP versions from 5.6 through 8.5
  • PHP-FPM with Nginx or Apache with mod_php
  • Multiple local domains using different PHP versions
  • Automated configuration through a Python management script
  • HTTP and HTTPS support with automatic self-signed certificate generation
  • Mailpit for testing outgoing emails
  • Adminer for database management
  • MariaDB, optional Node.js tooling, MyCLI, and MySQLTuner
  • Makefile commands for common operations
  • Optional Unix socket communication between Nginx and PHP-FPM

Repository: https://github.com/rhamdeew/docker-compose-php

I’d appreciate any feedback, feature suggestions, bug reports, or contributions. I’m especially interested in hearing how other developers manage local environments for projects that still depend on older PHP versions.

u/rhamdeew — 2 days ago
▲ 15 r/PHP

NCache v1.0.0 — a multi-driver caching library for PHP 8.1+

I’ve released the first stable version of NCache, an open-source caching library I’ve been building for PHP.

It provides a unified API across JSON, PHP Array, serialized PHP, SQLite, Redis and Memcached, with PSR-6 and PSR-16 adapters.

It also includes TTL management, isolated profiles/namespaces, cache tags with lazy invalidation, signatures, callable values, atomic file writes and a transactional registry.

The project is tested on PHP 8.1–8.5 with PHPUnit, PHPStan level 9 and PHP-CS-Fixer through GitHub Actions.

I’d particularly appreciate feedback on the API design, cache invalidation model and overall architecture.

GitHub: github.com/Noga-ng/NCache

Install: composer require noga-ng/ncache

u/Cultural-Yard-1598 — 3 days ago
▲ 0 r/PHP

Leaf 5 released: a PHP framework built for humans and AI agents

We just released Leaf 5, the biggest release in the framework's history. It rethinks what a PHP framework looks like when half your team is an AI assistant: error screens that explain their own fix, docs structured to burn fewer tokens, and a .leaf/CONTEXT.md file that gives agents persistent project memory. Around 30 modules shipped stable alongside it, plus framework-agnostic tools like Alchemy (full QA setup in one YAML file) that work in any PHP app.

Announcement: https://blog.leafphp.dev/posts/leaf-5

Love, Michael Darko Creator of Leaf (leafphp.dev)

Edit: Thanks for all the love, and the AI callouts 😂 We had a pretty good launch yesterday and we’re back to building.

Under all the paint, Leaf is just PHP, think a Lite version of Laravel with batteries separate but still first-party. We’ve got a whole lot more to publish for both Leaf and the PHP community and we’ll be back

u/mychidarko — 3 days ago
▲ 2 r/PHP

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!

reddit.com
u/brendt_gd — 3 days ago
▲ 0 r/PHP

Looking for a PHP Laravel course recommendation

Hey everyone, I'm looking for a course covering PHP basics, OOP, and Laravel. I struggle to stay focused during self-study, so I'd really appreciate it if someone could recommend a good course on Udemy (or elsewhere) where I can learn PHP and Laravel well enough to start building applications. For context, my background is in Software QA, and I have a basic understanding of web development and design.

#PHP #Laravel #WebDevelopment #LearnToCode #Udemy #BackendDevelopment #SoftwareQA #OOP

reddit.com
u/IndependenceNo6857 — 4 days ago
▲ 71 r/PHP

We moved a Symfony app to FrankenPHP worker mode. Got maybe 20%, not 3.5x.

Number in the title so nobody has to read to the end: about 20%. And I should say up front that this is from memory, I didn't keep the before and after. So take it as one guy telling you it felt meaningfully faster, not as a benchmark.

Context: I work on Teradion, practice management software for French accounting firms. Symfony, and most of what it does all day is pull filings and deadlines out of six systems we don't control. We were on nginx plus PHP-FPM, we're now on FrankenPHP in worker mode.

The reason I bothered writing any of this down is the 3.5x on the FrankenPHP homepage. I went looking for where that number comes from and there's no methodology published anywhere that I could find. The benchmarks in the demo repo are from October 2022. They measure latency at low load, there's a sleep in the script, no RPS figure at all, and classic mode comes out slower than FPM in them (if I'm misreading that, tell me, genuinely). The issue asking for reproducible benchmarks is #481 and it's been open since January 2024.

What actually reframed it for me was the Tideways comparison from September 2025, methodology published, Hetzner CCX33, Vegeta, and they found essentially no performance or throughput difference between PHP-FPM and FrankenPHP in classic mode. Which fits what our 20% is. None of it comes from the server. It comes from the worker not rebooting your app on every single request. Swap nginx for Caddy and stay in classic mode and you've done a migration for nothing.

Stuff that cost us time, in no particular order.

The first one is just dumb. After the switch a pile of files came out 0600, JWT private key included, so login 500'd and the logs said nothing at all.

Then the runtime env var in systemd, which wants doubled backslashes in Environment. Single ones get rejected outright, and if you go through EnvironmentFile instead they get stripped on the way in. The official doc says otherwise. Worker just wouldn't boot.

And then state surviving between requests, which is the one that actually hurt. A filter stayed active from one request into the next and broke logins intermittently, which is the worst way for anything to break. In our defence it's documented to death: FrankenPHP says static state persists by design and that $_ENV isn't reset, Symfony says any state captured by the kernel or its services may leak across requests unless the relevant services implement ResetInterface. I'd read both. Shipped it anyway.

Two things made that hunt much longer than it needed to be. PrivateTmp, so the debug logging we added to /tmp went somewhere we couldn't see it. And getSubscribedEvents is compiled, so restarting does nothing, you have to clear the cache.

I'm glad we did it, but if I'm honest the payoff is one binary and one config instead of nginx plus php-fpm, and not thinking about certs anymore. Speed was a bonus. Even the Tideways piece that finds no perf difference says moving to FrankenPHP can reduce operations complexity.

If anyone has real production numbers, post them. I looked and couldn't find a single public case study with figures.

reddit.com
u/These_Reality519 — 6 days ago
▲ 10 r/PHP

Controversial opinion: spatie/laravel-permissions doesn't help a whole lot with authorization.

... so I decided to write my own permissions library. https://laravel-warrant.dev

A while back I was adding permissions to an app and a friend told me to just use spatie/laravel-permission, since everyone does. So I read through it and... I kind of walked away confused about what it was actually doing for me. As far as I could tell it mostly gives you some tables and methods to track which roles and permissions a user has. Basically inserting and deleting rows.

Which is fine, but that was never the part I was stuck on. My hard part was stuff like "a user can edit a document if it's theirs, or if they manage the team it's in, but not once it's locked, unless they're an admin." A permission string like edit documents can't say any of that.

So I still have to hand-write a Policy for it. And then write the same logic AGAIN as a query scope so my list pages could show only the rows they're allowed to touch. Two copies of one rule that slowly drift apart.

So Spatie handles the easy 10% (storing the assignment) and leaves me the 90% that's actually annoying.

So I built Laravel Warrant for the 90%. You write the rule once as text and it compiles to SQL:

if is_self or manages_team they can update
if is_locked and not is_admin they cannot update
if is_admin they can *

And that one rule answers all three of the questions I would have had to rewrite by hand:

$document->hasAbility('update');                       // can they?
Document::query()->hasAbility('update')->paginate();    // which rows?
Document::query()->selectAbilities()->get();            // what can they do to each row?

The "which rows" one is just a WHERE clause, so the database does the filtering instead of me loading every row into PHP.

It's still in beta and I'm actively testing it, so the API might change. Honestly I'm mostly posting to see if this resonates with anyone else or if I'm just weird. Do you think you would want to use something like this and would it solve a real pain point for you? Any ideas on how to make this better?

Docs: https://laravel-warrant.dev GitHub: https://github.com/patrickjames242/laravel-warrant

Would love any feedback.

laravel-warrant.dev
u/ObligationLoose3913 — 6 days ago
▲ 73 r/PHP

Is PHP a good first language for learning backend development in 2026?

Hi everyone,

I’m a complete beginner looking to learn programming purely as a hobby. I’m mainly interested in backend development, building APIs, working with databases, and eventually projects like the backend for a small chat application.
I’ve been looking at a few languages, and PHP is one of the options I’m seriously considering, probably followed by Laravel once I understand the language itself.

I’m not concerned about the job market. What matters more to me is learning programming and backend development properly rather than just getting something working as quickly as possible.

I’m also considering Ruby/Rails and Elixir/Phoenix. Elixir in particular interests me because of functional programming and the BEAM

If you were starting from zero today with backend development as a hobby, would you consider PHP a good first choice?

reddit.com
u/Intelligent_Role_824 — 7 days ago
▲ 2 r/PHP

Need help with my developing a digital workflow management system for small accounting, taxation, payroll business

Hi there, I have a final year IT group project,we have choosen to develop a full stack website

So we had to go to a local business and investigate their current system and how we can work on it.

HTML,Css(bootstrap), javascript,chart.js,php(laravel),mysql,xampp these languages could please advise me if these are we as group have no prior experience with the twoframeworks larvae and bootstrap.bit we know the other languages.

It is a digital workflow management system for a small accounting, taxation,payroll. It will deal with the workflow only not the calculation. I would like improve on functional requirements but I dont we think we have proper knowledge to create accounting software from scratch.The business was using sage as the accounting software would an accountant in April 2026 and Now august over the past month, they have developed their own software system , so we are still going ahead with the workflow , even though they have a software system. What advice would you give me moving forward?I would love to share my project proposal.Planning and analysis , but as far as this information please advise me , thank you kind regards .

reddit.com
u/Ordinary_Corner_2415 — 6 days ago
▲ 32 r/PHP

Why are Canadian timezones are gone in PHP 8.5?

After upgrading to PHP 8.5 the timezone changed to UTC. After working through this, I discovered that the only closest timezone left is "America/Vancouver" but this is the wrong timezone because it has timezone changes that are not the same.

Why was "Canada/Pacific" removed from PHP? We're not part of America, and our timezones are not the same.

Thanks.

reddit.com
u/RandolfRichardson — 8 days ago
▲ 0 r/PHP

PHPTUI - Terminal user interfaces for PHP

Every feature has a reference page and a runnable, self-contained example in playground/:

  • 🧩 16 fields
  • 🔀 Conditional fields
  • 🏗️ Builder-driven
  • 🗺️ Full-screen and multi-column layouts
  • 🎛️ Interactive or unattended
  • 🎨 Themes and dark/light modes
  • ⌨️ Key bindings
  • 🌍 Translations
  • 🧪 Test harness for your project

​

use DrevOps\PhpTui\Builder\Form;
use DrevOps\PhpTui\Builder\PanelBuilder;
use DrevOps\PhpTui\Tui;

$form = Form::create('Quick start')
  ->panel('order', 'New order', function (PanelBuilder $p): void {
    $p->text('name', 'Order name')->required();
    $p->select('fruit', 'Fruit')->default('banana')->options([
      'apple' => 'Apple',
      'banana' => 'Banana',
      'cherry' => 'Cherry',
    ]);
    $p->select('veg', 'Vegetables')->multiple()->default(['carrot'])->options([
      'carrot' => 'Carrot',
      'tomato' => 'Tomato',
      'spinach' => 'Spinach',
    ]);
    $p->number('quantity', 'Quantity')->min(1)->max(99)->default(6);
    $p->confirm('organic', 'Organic only?')->default(FALSE);
  });

// Interactive on a terminal, non-interactive otherwise. 
$answers = (new Tui($form))->run();
phptui.dev
u/AlexDrevOps — 7 days ago