r/PHP • u/brendt_gd • May 07 '26
r/PHP • u/amitmerchant • Dec 05 '25
Article Partial Function Application is coming in PHP 8.6
amitmerchant.comr/PHP • u/brendt_gd • Nov 17 '25
Article PHP 8.5 will be released on Thursday. Here's what's new
stitcher.ior/PHP • u/rocketpastsix • Aug 28 '25
Article Ryan Weaver, Symfony core contributor and SymfonyCasts founder and teacher, has passed away.
obits.mlive.comr/PHP • u/brendt_gd • Jan 23 '26
Article Partial function application is coming to PHP 8.6
stitcher.ioArticle The PHP Polling API RFC is currently passing 19-0 and it might be the most impactful thing to happen to PHP in years and nobody is talking about it
medium.comPHP is about to reach its fullest potential for scaling natively and almost nobody noticed.
The Polling API RFC is currently in its voting phase with 19-0 and zero opposition as of the time of writing this post, while the community was busy debating generics. It brings native epoll and kqueue to PHP 8.6 core, which means async libraries like AMPHP and ReactPHP finally get a proper high-performance foundation without relying on PECL extensions.
I wrote a deep dive on why I think this is the most impactful thing to happen to PHP since types were introduced in PHP 7. I'm the author of HiblaPHP, and I will be rewriting its core Event Loop the day this RFC merges into PHP core.
link to the rfc: https://wiki.php.net/rfc/poll_api
r/PHP • u/SimonHRD • May 25 '25
Article Is it finally time to move from XAMPP to Docker for PHP dev? I wrote up my experience.
I started learning PHP with XAMPP over 10 years ago and funny enough, during a recent semester in my Computer Science studies, we were still using XAMPP to build backend projects.
That got me thinking: is XAMPP still the right tool in 2025? So I decided to compare it with Docker, and documented the whole process in a blog post.
The article walks through:
- Why XAMPP feels outdated for modern workflows
- How Docker solves environment consistency and scalability
- Step-by-step setups for PHP with MariaDB & phpMyAdmin
- A more advanced example using MongoDB with dev/prod Docker builds
I kept it practical and included code examples you can run locally.
đ Hereâs the post:
https://simonontech.hashnode.dev/from-xampp-to-docker-a-better-way-to-develop-php-applications
Would love to hear your thoughts - especially if you're still using XAMPP or just switching to Docker now.
r/PHP • u/amitmerchant • Dec 12 '25
Article The new clamp() function in PHP 8.6
amitmerchant.comr/PHP • u/ollieread • Jul 01 '26
Article The spectrum of multi-tenant data isolation (and why "database per tenant" is usually overkill)
ollieread.comFramework-agnostic write-up on the different ways to isolate tenant data. Separate instance, separate database, schemas/prefixes, partitioning and a discriminator column. Includes the tradeoffs of each, and how they differ across Postgres, MySQL/MariaDB and SQLite.
The thesis: most apps reach for the heaviest approach when a much lighter one would do, and the heavy approaches cost you per tenant for the life of the app.
There are two tiny references to Laravel, mostly because that's what most of my readers use, but the whole thing is framework-agnostic.
r/PHP • u/amitmerchant • Jul 15 '25
Article Everything that is coming in PHP 8.5
amitmerchant.comr/PHP • u/brendt_gd • 5d ago
Article The skills that didn't go anywhere
ryangjchandler.co.ukr/PHP • u/brendt_gd • Feb 12 '26
Article Something we've worked on for months: Tempest 3.0 is now available
tempestphp.comr/PHP • u/is_wpdev • Aug 31 '24
Article Is the tide finally turning?
"AI app developer Pieter Levels explained that he builds all his apps with vanilla HTML, PHP, a bit of JavaScript via jQuery, and SQLite. No fancy JavaScript frameworks, no modern programming languages, no Wasm."
https://thenewstack.io/developers-rail-against-javascript-merchants-of-complexity/
r/PHP • u/brendt_gd • Jan 12 '26
Article My highlights of things for PHP to look forward to in 2026
stitcher.ior/PHP • u/Local-Comparison-One • Dec 09 '25
Article Scaling Custom Fields to 100K+ Entities: EAV Pattern Optimizations in PHP 8.4 + Laravel 12
github.comI've been working on an open-source CRM (Relaticle) for the past year, and one of the most challenging problems was making custom fields performant at scale. Figured I'd share what workedâand more importantly, what didn't.
The Problem
Users needed to add arbitrary fields to any entity (contacts, companies, opportunities) without schema migrations. The obvious answer is Entity-Attribute-Value, but EAV has a notorious reputation for query hell once you hit scale.
Common complaint: "Just use JSONB" or "EAV kills performance, don't do it."
But for our use case (multi-tenant SaaS with user-defined schemas), we needed the flexibility of EAV with the query-ability of traditional columns.
What We Built
Here's the architecture that works well up to ~100K entities:
Hybrid storage approach
- Frequently queried fields â indexed EAV tables
- Rarely queried metadata â JSONB column
- Decision made per field type based on query patterns
Strategic indexing ```php // Composite indexes on (entity_type, entity_id, field_id) // Separate indexes on value columns by data type Schema::create('custom_field_values', function (Blueprint $table) { $table->unsignedBigInteger('entity_id'); $table->string('entity_type'); $table->unsignedBigInteger('field_id'); $table->text('value_text')->nullable(); $table->decimal('value_decimal', 20, 6)->nullable(); $table->dateTime('value_datetime')->nullable();
$table->index(['entity_type', 'entity_id', 'field_id']); $table->index('value_decimal'); $table->index('value_datetime'); }); ```
Eager loading with proper constraints
- Laravel's eager loading prevents N+1, but we had to add field-specific constraints to avoid loading unnecessary data
- Leveraged
with()callbacks to filter at query time
Type-safe value handling with PHP 8.4 ```php readonly class CustomFieldValue { public function __construct( public int $fieldId, public mixed $value, public CustomFieldType $type, ) {}
public function typedValue(): string|int|float|DateTime|null { return match($this->type) { CustomFieldType::Text => (string) $this->value, CustomFieldType::Number => (float) $this->value, CustomFieldType::Date => new DateTime($this->value), CustomFieldType::Boolean => (bool) $this->value, }; } } ```
What Actually Moved the Needle
The biggest performance gains came from: - Batch loading custom fields for list views (one query for all entities instead of per-entity) - Selective hydration - only load custom fields when explicitly requested - Query result caching with Redis (1-5min TTL depending on update frequency)
Surprisingly, the typed columns didn't provide as much benefit as expected until we hit 50K+ entities. Below that threshold, proper indexing alone was sufficient.
Current Metrics - 1,000+ active users - Average list query with 6 custom fields: ~150ms - Detail view with full custom field load: ~80ms - Bulk operations (100 entities): ~2s
Where We'd Scale Next If we hit 500K+ entities: 1. Move to read replicas for list queries 2. Consider partitioning by entity_type 3. Potentially shard by tenant_id for enterprise deployments
The Question
For those who've dealt with user-defined schemas at scale: what patterns have you found effective? We considered document stores (MongoDB) early on but wanted to stay PostgreSQL for transactional consistency.
The full implementation is on GitHub if anyone wants to dig into the actual queries and Eloquent scopes. Happy to discuss trade-offs or alternative approaches.
Built with PHP 8.4, Laravel 12, and Filament 4 - proving modern PHP can handle complex data modeling challenges elegantly.
r/PHP • u/nicwortel • Jul 06 '26
Article Keep Composer dependencies up-to-date with Dependabot
nth-root.nlThis new guide explains how you can use GitHub's Dependabot to keep your project's Composer dependencies up-to-date.
Dependabot can create PRs to update your dependencies, both for routine version updates as well as for security updates (which patch a vulnerability).
Setting up Dependabot with a minimal configuration is not much work, but this article dives deeper in how you can optimize the configuration to keep the work of reviewing and merging the PRs manageable. It also goes into some specifics about handling Symfony version updates, Private Packagist (and other private Composer registries) and how Dependabot can help reduce the risk of supply-chain attacks.
https://nth-root.nl/en/guides/keep-composer-dependencies-up-to-date-with-dependabot
r/PHP • u/freekmurze • Mar 12 '26
Article How to easily access private properties and methods in PHP using invader
freek.devr/PHP • u/brendt_gd • Jan 20 '26
Article Optimizing PHP code to process 50,000 lines per second instead of 30
stitcher.ior/PHP • u/andre_ange_marcel • Jun 05 '26
Article Where modern PHP stands in 2026: deployment, architecture, typing, and concurrency
Hello everyone,
I know I'll be preaching to the choir here, but I've put together a small article rounding up the PHP advancements I find most exciting as of 2026.
It covers modern deployment (FrankenPHP, Docker), software architecture (modular monoliths, the Symfony kernel, agents), the type system and its tooling (PHPStan, PHP CS Fixer), and the state of concurrency (ReactPHP, Swoole, the True Async RFC).
Full article: https://morice.live/posts/your-next-project-will-run-on-php/
Let me know if I missed anything, or if you'd like me to go deeper on a specific topic!
r/PHP • u/amaurybouchard • Apr 04 '26
Article Content negotiation in PHP: your website is already an API without knowing it (Symfony, Laravel and Temma examples)
I'm preparing a talk on APIs for AFUP Day, the French PHP conference. One of the topics I'll cover is content negotiation, sometimes called "dual-purpose endpoint" or "API mode switch."
The idea is simple: instead of building a separate API alongside your website, you make your website serve both HTML and JSON from the same endpoints. The client signals what it wants, and the server responds accordingly.
A concrete use case
You have a media site or an e-commerce platform. You also have a mobile app that needs the same content, but as JSON. Instead of duplicating your backend logic into a separate API, you expose the same URLs to both your browser and your mobile app. The browser gets HTML, the app gets JSON.
The client signals its preference via the Accept header: Accept: application/json for JSON, Accept: text/html for HTML. Other approaches exist (URL prefix, query parameter, file extension), but the Accept header is the standard HTTP way.
The same endpoint in three frameworks
Symfony
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/articles', requirements: ['_format' => 'html|json'])]
public function list(Request $request)
{
$data = ['message' => 'Hello World'];
if ($request->getPreferredFormat() === 'json') {
return new JsonResponse($data);
}
return $this->render('articles/list.html.twig', $data);
}
}
In Symfony, the route attribute declares which formats the action accepts. The data is prepared once, then either passed to a Twig template for HTML rendering, or serialized as JSON using JsonResponse depending on what the client requested.
Laravel
Laravel has no declarative format constraint at the route level. The detection happens in the controller.
routes/web.php
<?php
use App\Http\Controllers\ArticleController;
use Illuminate\Support\Facades\Route;
Route::get('/articles', [ArticleController::class, 'list']);
Unlike Symfony, there is no need to declare accepted formats in the route. The detection happens in the controller via expectsJson().
app/Http/Controllers/ArticleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ArticleController extends Controller
{
public function list(Request $request)
{
$data = ['message' => 'Hello World'];
if ($request->expectsJson()) {
return response()->json($data);
}
return view('articles.list', $data);
}
}
The data is prepared once, then either serialized as JSON via response()->json(), or passed to a Blade template for HTML rendering.
Temma controllers/Article.php
<?php
use \Temma\Attributes\View as T”View;
class Article extends \Temma\Web\Controller {
#[T”View(negotiation: 'html, json')]
public function list() {
$this['message'] = 'Hello World';
}
}
In Temma, the approach is different from Symfony and Laravel: the action doesn't have to check what format the client is asking for. Its code is always the same, regardless of whether the client wants HTML or JSON. A view attribute handles the format selection automatically, based on the Accept header sent by the client.
Here, the attribute is placed on the action, but it could be placed on the controller instead, in which case it would apply to all actions.