Symfony UX 2.35 Released
https://symfony.com/blog/symfony-ux-2-35-released?utm_medium=feed&utm_source=Symfony%20Blog%20Feed
https://redd.it/1skpbh7
@r_php
https://symfony.com/blog/symfony-ux-2-35-released?utm_medium=feed&utm_source=Symfony%20Blog%20Feed
https://redd.it/1skpbh7
@r_php
Symfony
Symfony UX 2.35 Released (Symfony Blog)
Symfony UX 2.35 is out with smarter HTML attribute merging for Twig components, a new ``reset_on_focus`` option for Autocomplete, a brand new Flowbite 4.0 kit, and more.
Twenty Years Since My First PHP Script
https://iampavel.dev/blog/twenty-years-since-my-first-php-script
https://redd.it/1skppkm
@r_php
https://iampavel.dev/blog/twenty-years-since-my-first-php-script
https://redd.it/1skppkm
@r_php
Asaduzzaman Pavel
Twenty Years Since My First PHP Script • Asaduzzaman Pavel
It has been 20 years since I wrote my first PHP script in 2006. The code was terrible, the forum worked anyway, and here is what I wish I knew then.
Laravel Privacy Agent Skills (feedback is welcome!)
Hey guys, I’ve been working for the past few months on an app in the healthcare industry that requires strong compliance with user data protection and retention policies.
I recently went to Tropical Rails in Sao Paulo and I attended Talysson Oliveira’s talk, "Privacy on Rails - pragmatically complying to data protection laws". They built an Agent Skill for their privacy-by-design approach to help Rails developers ensure their DX is aligned with these policies from the conception of a Rails app.
However, the app I’ve been working on is built with Laravel, and I thought it would be a great idea to take what they built for Rails and apply a similar concept to Laravel. That’s why I decided to create https://github.com/sairojgg/laravel-privacy-skills as a Laravel alternative.
This is my first time sharing something publicly, let alone an Agent Skill, so any feedback is more than welcome.
This project is heavily inspired by their work, and I want to give full credit to the original creators.
https://redd.it/1skpyyj
@r_php
Hey guys, I’ve been working for the past few months on an app in the healthcare industry that requires strong compliance with user data protection and retention policies.
I recently went to Tropical Rails in Sao Paulo and I attended Talysson Oliveira’s talk, "Privacy on Rails - pragmatically complying to data protection laws". They built an Agent Skill for their privacy-by-design approach to help Rails developers ensure their DX is aligned with these policies from the conception of a Rails app.
However, the app I’ve been working on is built with Laravel, and I thought it would be a great idea to take what they built for Rails and apply a similar concept to Laravel. That’s why I decided to create https://github.com/sairojgg/laravel-privacy-skills as a Laravel alternative.
This is my first time sharing something publicly, let alone an Agent Skill, so any feedback is more than welcome.
This project is heavily inspired by their work, and I want to give full credit to the original creators.
https://redd.it/1skpyyj
@r_php
GitHub
GitHub - sairojgg/laravel-privacy-skills: Agent Skills for privacy by design implementation, assessment, and change review in Laravel…
Agent Skills for privacy by design implementation, assessment, and change review in Laravel apps. - sairojgg/laravel-privacy-skills
laravel-nova-multifilter: Combine multiple filter columns into a single Nova filter panel
https://github.com/degecko/laravel-nova-multifilter
https://redd.it/1sl1xox
@r_php
https://github.com/degecko/laravel-nova-multifilter
https://redd.it/1sl1xox
@r_php
GitHub
GitHub - degecko/laravel-nova-multifilter: Combine multiple filter columns into a single Nova filter panel
Combine multiple filter columns into a single Nova filter panel - degecko/laravel-nova-multifilter
I used multiple Claude Code instances to build and test a Laravel package across 3 production codebases
I posted recently on Reddit about building a fluent validation rule builder for Laravel (laravel-fluent-validation). Since then I also released a Rector companion package for automated migration. Instead of the usual pre-release-and-wait cycle, I ran Claude Code on the package repo and on three production Laravel codebases simultaneously and let the Claude instances work together.
# The workflow
claude-peers is an MCP server for Claude Code. Each instance running on your machine can discover other instances, see what they're working on, and send messages. They don't share context. Each has its own conversation with full codebase access.
In practice it works like this: the package peer tags a new release. It sends a message to the three codebase peers saying "0.4.5 tagged, fixes the parallel-worker race, please re-verify." Each codebase peer receives the message, pulls the new version, runs the migration, runs their tests, and sends back results. If something breaks, the response includes the exact error, the file, and usually a theory about why. The package peer reads that, asks follow-up questions if needed, fixes the issue, and the loop continues.
One thing I didn't expect was how quickly the peers developed their own review dynamic. They would challenge each other's assumptions, ask for evidence, and sometimes reach consensus before coming back with a recommendation.
I had four terminals open:
The package repo, building features, writing tests, shipping releases
Three production codebases, each a real Laravel app with its own validation patterns, framework integrations, and test suites
Everything runs locally. Claude Code works on local clones of each codebase, with the same filesystem access you'd have in your terminal. No production servers, no remote environments, no secrets exposed to AI.
The interesting part was what the peers caught that tests and synthetic fixtures couldn't:
One app has 108 FormRequests and uses `rules()` as a naming convention on Actions and Collections. The skip log grew to 2,988 entries / 777KB. On a smaller codebase you'd never notice.
Another app runs 15 parallel Rector workers. The skip log's truncate flag was per-process, so every worker wiped the others' entries. Synthetic fixtures run single-process. This bug doesn't exist there.
The same app runs Filament alongside Livewire. Five components use Filament's `InteractsWithForms` trait which defines its own `validate()`. Inserting the package's trait would have been a fatal collision on first render.
A third app found that 5/7 of its Livewire files had dead
Wrote up the full workflow, what worked, and when I'd use it (link in comments).
https://redd.it/1sl3ckm
@r_php
I posted recently on Reddit about building a fluent validation rule builder for Laravel (laravel-fluent-validation). Since then I also released a Rector companion package for automated migration. Instead of the usual pre-release-and-wait cycle, I ran Claude Code on the package repo and on three production Laravel codebases simultaneously and let the Claude instances work together.
# The workflow
claude-peers is an MCP server for Claude Code. Each instance running on your machine can discover other instances, see what they're working on, and send messages. They don't share context. Each has its own conversation with full codebase access.
In practice it works like this: the package peer tags a new release. It sends a message to the three codebase peers saying "0.4.5 tagged, fixes the parallel-worker race, please re-verify." Each codebase peer receives the message, pulls the new version, runs the migration, runs their tests, and sends back results. If something breaks, the response includes the exact error, the file, and usually a theory about why. The package peer reads that, asks follow-up questions if needed, fixes the issue, and the loop continues.
One thing I didn't expect was how quickly the peers developed their own review dynamic. They would challenge each other's assumptions, ask for evidence, and sometimes reach consensus before coming back with a recommendation.
I had four terminals open:
The package repo, building features, writing tests, shipping releases
Three production codebases, each a real Laravel app with its own validation patterns, framework integrations, and test suites
Everything runs locally. Claude Code works on local clones of each codebase, with the same filesystem access you'd have in your terminal. No production servers, no remote environments, no secrets exposed to AI.
The interesting part was what the peers caught that tests and synthetic fixtures couldn't:
One app has 108 FormRequests and uses `rules()` as a naming convention on Actions and Collections. The skip log grew to 2,988 entries / 777KB. On a smaller codebase you'd never notice.
Another app runs 15 parallel Rector workers. The skip log's truncate flag was per-process, so every worker wiped the others' entries. Synthetic fixtures run single-process. This bug doesn't exist there.
The same app runs Filament alongside Livewire. Five components use Filament's `InteractsWithForms` trait which defines its own `validate()`. Inserting the package's trait would have been a fatal collision on first render.
A third app found that 5/7 of its Livewire files had dead
#[Validate] attributes coexisting with explicit validate([...]) calls. Nobody anticipated that pattern.Wrote up the full workflow, what worked, and when I'd use it (link in comments).
https://redd.it/1sl3ckm
@r_php
GitHub
GitHub - SanderMuller/laravel-fluent-validation: Fluent and extremely fast validation for Laravel
Fluent and extremely fast validation for Laravel. Contribute to SanderMuller/laravel-fluent-validation development by creating an account on GitHub.
I used multiple Claude Code instances to build and test a Laravel package across 3 production codebases
/r/laravel/comments/1sl3ckm/i_used_multiple_claude_code_instances_to_build/
https://redd.it/1sl3d4l
@r_php
/r/laravel/comments/1sl3ckm/i_used_multiple_claude_code_instances_to_build/
https://redd.it/1sl3d4l
@r_php
Reddit
From the PHP community on Reddit: I used multiple Claude Code instances to build and test a Laravel package across 3 production…
Posted by Rhinnii - 0 votes and 0 comments
Composer 2.9.6: Perforce Driver Command Injection Vulnerabilities (CVE-2026-40261, CVE-2026-40176)
https://blog.packagist.com/composer-2-9-6-perforce-driver-command-injection-vulnerabilities/
https://redd.it/1sl4z6i
@r_php
https://blog.packagist.com/composer-2-9-6-perforce-driver-command-injection-vulnerabilities/
https://redd.it/1sl4z6i
@r_php
Private Packagist
Composer 2.9.6: Perforce Driver Command Injection Vulnerabilities (CVE-2026-40261, CVE-2026-40176)
Please immediately update Composer to version 2.9.6 or 2.2.27 (LTS) by running composer.phar self-update. The new releases include fixes for two command injection security vulnerabilities in the Perforce VCS driver. CVE-2026-40261 was reported by Koda Reef…
The NativePHP Masterclass with Shruti Balasa
https://www.youtube.com/watch?v=HO9zbS2dM7M
https://redd.it/1sl6d3q
@r_php
https://www.youtube.com/watch?v=HO9zbS2dM7M
https://redd.it/1sl6d3q
@r_php
YouTube
The NativePHP Masterclass - Teaser
We've enlisted one of the Laravel Community's best teachers to help us create the NativePHP Masterclass.
Let Shruti be your guide (and Shane and Simon too) on your journey to building great native apps.
In this in-depth course, we're going to take you through…
Let Shruti be your guide (and Shane and Simon too) on your journey to building great native apps.
In this in-depth course, we're going to take you through…
Is EasyAdmin still worth it with a lot of customisation?
Hey all!
I've used EasyAdmin to quickstart a back-office with a ton of (sometimes massive) forms. It works great but the more I customise its appearance, the more I feel I'm working against it.
Question: When does it lose out to plain symfony forms and twig templates? Any experience would be much appreciated!
Here's a handful of examples for context:
- boolean fields replaced with a custom tri-state toggle to track true-false-null values
- choicefields displayed as a row of buttons row to view all options at once and pick in one click
- collections of images with an extra link to view the existing file in a new tab
- collection displayed as a custom matrix (properties as rows, objects as columns, values in cells)
Some of these rely on Stimulus, ultimately I may even switch to Turbo.
https://redd.it/1sl6aci
@r_php
Hey all!
I've used EasyAdmin to quickstart a back-office with a ton of (sometimes massive) forms. It works great but the more I customise its appearance, the more I feel I'm working against it.
Question: When does it lose out to plain symfony forms and twig templates? Any experience would be much appreciated!
Here's a handful of examples for context:
- boolean fields replaced with a custom tri-state toggle to track true-false-null values
- choicefields displayed as a row of buttons row to view all options at once and pick in one click
- collections of images with an extra link to view the existing file in a new tab
- collection displayed as a custom matrix (properties as rows, objects as columns, values in cells)
Some of these rely on Stimulus, ultimately I may even switch to Turbo.
https://redd.it/1sl6aci
@r_php
Reddit
From the symfony community on Reddit
Explore this post and more from the symfony community
Laravel 13.4: Better Queue Tools and Stricter Form Requests
https://youtu.be/MsxZvxWSRGg
https://redd.it/1sl7dut
@r_php
https://youtu.be/MsxZvxWSRGg
https://redd.it/1sl7dut
@r_php
YouTube
Laravel 13.4: Better Queue Tools and Stricter Form Requests
Laravel 13.4 brings improvements to queuea, and stricter FormRequesta.
➡️ Queued #[Delay] attribute improvements https://github.com/laravel/framework/pull/59514
➡️ Queue inspection methods https://github.com/laravel/framework/pull/59511
➡️ FormRequest…
➡️ Queued #[Delay] attribute improvements https://github.com/laravel/framework/pull/59514
➡️ Queue inspection methods https://github.com/laravel/framework/pull/59511
➡️ FormRequest…
25 years to the day !! of my first surviving open source PHP project: PHP-Egg, born 13 April 2001. FIrst PHP Daemon. First RFC PHP client (IRC). First long-running (months on end) PHP process.
https://github.com/hopeseekr/phpegg
https://redd.it/1sl89rw
@r_php
https://github.com/hopeseekr/phpegg
https://redd.it/1sl89rw
@r_php
GitHub
GitHub - hopeseekr/phpegg: The first IRC bot + IRC client / server + CLI daemon in PHP.
The first IRC bot + IRC client / server + CLI daemon in PHP. - hopeseekr/phpegg
Symfony_Live Berlin: "Build Applications that Welcome Change"
https://symfony.com/blog/symfony-live-berlin-build-applications-that-welcome-change?utm_medium=feed&utm_source=Symfony%20Blog%20Feed
https://redd.it/1slcok7
@r_php
https://symfony.com/blog/symfony-live-berlin-build-applications-that-welcome-change?utm_medium=feed&utm_source=Symfony%20Blog%20Feed
https://redd.it/1slcok7
@r_php
Symfony
Symfony_Live Berlin: "Build Applications that Welcome Change" (Symfony Blog)
Change is inevitable — but your architecture can make it easier. In “Build Applications that Welcome Change”, Alexander M. Turek shares how to design Symfony apps built for long-term evolution.
SymfonyLive Berlin 2026: "AI Culture in Open Source — The Sylius Way"
https://symfony.com/blog/s?utm_medium=feed&utm_source=Symfony%20Blog%20Feed
https://redd.it/1sl57gb
@r_php
https://symfony.com/blog/s?utm_medium=feed&utm_source=Symfony%20Blog%20Feed
https://redd.it/1sl57gb
@r_php
SymfonyConnect
Join the Community - SymfonyConnect
SymfonyConnect is a developer social network. Join the community, create your developer profile, and start earning achievements for your community involvement and commitment.
I built a modern and clean PHP wrapper for Android ADB (xvq/php-adb)
**Hi Reddit,**
**I built this a while back** when I was working on some Android automation projects. At the time, I found that the PHP ecosystem lacked native ADB (Android Debug Bridge) libraries. I was forced to switch to Python or Go for device interactions, but the context-switching cost was too high for my workflow.
So, I developed **xvq/php-adb**. This library is **heavily inspired by the Python** [**openatx/adbutils**](https://github.com/openatx/adbutils) **library**, aiming to bring that same ease of use to PHP.
**Features:**
* **Device Management:** List, connect, and switch between devices (supports wireless ADB).
* **Shell Commands:** Execute adb shell commands and get output as strings or arrays.
* **Input Control:** Support for screen taps (clicks), key events, and text input.
* **Port Forwarding:** Manage forward and reverse port mapping.
* **File Transfer:** Built-in `push` and `pull` support.
* **App Management:** Install, uninstall, and clear app data.
* **Screenshots:** Capture screen directly to local files.
**Quick Example:**
PHP
use Xvq\PhpAdb\Adb;
$adb = new AdbClient();
$device = $adb->device('emulator-5554');
// Tap at coordinates
$device->input->tap(500, 1000);
// Press Home button
$device->input->keyEvent(KeyCode::KEY_HOME);
// Screenshot
$device->screenshot('./debug.png');
I hope this helps anyone doing Android automation within the PHP ecosystem. Feedback and bug reports are welcome!
**GitHub:** [https://github.com/xvq/php-adb](https://github.com/xvq/php-adb)
https://redd.it/1sl81xx
@r_php
**Hi Reddit,**
**I built this a while back** when I was working on some Android automation projects. At the time, I found that the PHP ecosystem lacked native ADB (Android Debug Bridge) libraries. I was forced to switch to Python or Go for device interactions, but the context-switching cost was too high for my workflow.
So, I developed **xvq/php-adb**. This library is **heavily inspired by the Python** [**openatx/adbutils**](https://github.com/openatx/adbutils) **library**, aiming to bring that same ease of use to PHP.
**Features:**
* **Device Management:** List, connect, and switch between devices (supports wireless ADB).
* **Shell Commands:** Execute adb shell commands and get output as strings or arrays.
* **Input Control:** Support for screen taps (clicks), key events, and text input.
* **Port Forwarding:** Manage forward and reverse port mapping.
* **File Transfer:** Built-in `push` and `pull` support.
* **App Management:** Install, uninstall, and clear app data.
* **Screenshots:** Capture screen directly to local files.
**Quick Example:**
PHP
use Xvq\PhpAdb\Adb;
$adb = new AdbClient();
$device = $adb->device('emulator-5554');
// Tap at coordinates
$device->input->tap(500, 1000);
// Press Home button
$device->input->keyEvent(KeyCode::KEY_HOME);
// Screenshot
$device->screenshot('./debug.png');
I hope this helps anyone doing Android automation within the PHP ecosystem. Feedback and bug reports are welcome!
**GitHub:** [https://github.com/xvq/php-adb](https://github.com/xvq/php-adb)
https://redd.it/1sl81xx
@r_php
GitHub
GitHub - openatx/adbutils: pure python adb library for google adb service.
pure python adb library for google adb service. Contribute to openatx/adbutils development by creating an account on GitHub.
Shopper: Announcing the Livewire Starter Kit
https://laravelshopper.dev/blog/announcing-the-livewire-starter-kit
https://redd.it/1slkefv
@r_php
https://laravelshopper.dev/blog/announcing-the-livewire-starter-kit
https://redd.it/1slkefv
@r_php
Shopper
Announcing the Livewire Starter Kit // Shopper
A production-ready storefront built with Livewire 3, Flux UI, and Tailwind CSS v4. Product browsing, variant selection, multi-step checkout with Stripe, customer accounts. One command to install.
Bootgly v0.13.0-beta — Pure PHP HTTP Client (no cURL, no Guzzle, no ext dependencies) + Import Linter
Hey r/PHP,
I just released v0.13.0-beta of Bootgly, a base PHP 8.4+ framework that follows a zero third-party dependency policy.
Just install
This release adds two main features:
# 1. HTTP Client CLI — built from raw sockets
Not a cURL wrapper. Not a Guzzle fork. This is a from-scratch HTTP client built on top of
All standard methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
RFC 9112-compliant response decoding — chunked transfer-encoding, content-length, close-delimited
100-Continue two-phase requests (sends headers first, waits for server acceptance before body)
Keep-alive connection reuse
Request pipelining (multiple requests queued per connection)
Batch mode (
Event-driven async mode via `on()` hooks
SSL/TLS support
Automatic redirect following (configurable limit)
Connection timeouts + automatic retries
Multi-worker load generation (fork-based) for benchmarking
The whole client stack is \~3,700 lines of source code (TCP layer + HTTP layer + encoders/decoders + request/response models) plus \~2,000 lines of tests. No magic, no abstraction astronautics.
Why build an HTTP client from scratch instead of using cURL? Because the same event loop (`Select`) that powers the HTTP Server also powers the HTTP Client. They share the same connection management, the same non-blocking I/O model. The client can be used to benchmark the server with real HTTP traffic without any external tool.
# 2. Import Linter (bootgly lint imports)
A code style checker/fixer for PHP `use` statements:
Detects missing imports, wrong order (const → function → class), backslash-prefixed FQN in body
Auto-fix mode (`--fix`) with `php -l` validation before writing
Dry-run mode
AI-friendly JSON output for CI integration
Handles comma-separated
Built on
# Benchmarks (self-tested, WSL2, Ryzen 9 3900X, 12 workers)
Numbers below reflect *v0.13.1-beta*, a patch release with HTTP Client hot-path optimizations (+29.6% throughput) and cache isolation tests.
Scenario: 1 static route (Response is 'Hello, World!'), 514 concurrent connections, 10s duration.
|Runner|Req/s|Latency|Transfer/s|
|:-|:-|:-|:-|
|Bootgly TCP_Client_CLI|629,842|553μs|81.69 MB/s|
|WRK (C tool)|595,370|—|—|
|Bootgly HTTP_Client_CLI|568,058|1.07ms|56.95 MB/s|
Three different benchmark runners, all built-in (except wrk). The TCP client sends raw pre-built HTTP packets — that's the theoretical ceiling. The HTTP client builds and parses real HTTP requests/responses with full RFC compliance — that's the realistic throughput. WRK sits in between. All three confirm the server sustains 568k–630k req/s on a single machine with pure PHP + OPcache/JIT.
To provide context: Workman at TechEmpower Round 23 — the fastest pure PHP framework there — achieved approximately 580,000 requests per second on dedicated hardware. Bootgly reaches that level, with a difference of about 3% (a technical tie).
Why this absurd performance?
I tried replacing
The C → PHP callback dispatch via
Hey r/PHP,
I just released v0.13.0-beta of Bootgly, a base PHP 8.4+ framework that follows a zero third-party dependency policy.
Just install
php-cli, php-readline, and php-mbstring for PHP 8.4, and you'll have a high-performance HTTP server and client (see Benchmarks bellow)! No Symfony components, no League packages, nothing from Packagist in the core.This release adds two main features:
# 1. HTTP Client CLI — built from raw sockets
Not a cURL wrapper. Not a Guzzle fork. This is a from-scratch HTTP client built on top of
stream_socket_client with its own event loop:All standard methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
RFC 9112-compliant response decoding — chunked transfer-encoding, content-length, close-delimited
100-Continue two-phase requests (sends headers first, waits for server acceptance before body)
Keep-alive connection reuse
Request pipelining (multiple requests queued per connection)
Batch mode (
batch() → N × request() → drain())Event-driven async mode via `on()` hooks
SSL/TLS support
Automatic redirect following (configurable limit)
Connection timeouts + automatic retries
Multi-worker load generation (fork-based) for benchmarking
The whole client stack is \~3,700 lines of source code (TCP layer + HTTP layer + encoders/decoders + request/response models) plus \~2,000 lines of tests. No magic, no abstraction astronautics.
Why build an HTTP client from scratch instead of using cURL? Because the same event loop (`Select`) that powers the HTTP Server also powers the HTTP Client. They share the same connection management, the same non-blocking I/O model. The client can be used to benchmark the server with real HTTP traffic without any external tool.
# 2. Import Linter (bootgly lint imports)
A code style checker/fixer for PHP `use` statements:
Detects missing imports, wrong order (const → function → class), backslash-prefixed FQN in body
Auto-fix mode (`--fix`) with `php -l` validation before writing
Dry-run mode
AI-friendly JSON output for CI integration
Handles comma-separated
use, multi-namespace files, local function tracking (avoids false positives)Built on
token_get_all() — no nikic/php-parser dependency.# Benchmarks (self-tested, WSL2, Ryzen 9 3900X, 12 workers)
Numbers below reflect *v0.13.1-beta*, a patch release with HTTP Client hot-path optimizations (+29.6% throughput) and cache isolation tests.
Scenario: 1 static route (Response is 'Hello, World!'), 514 concurrent connections, 10s duration.
|Runner|Req/s|Latency|Transfer/s|
|:-|:-|:-|:-|
|Bootgly TCP_Client_CLI|629,842|553μs|81.69 MB/s|
|WRK (C tool)|595,370|—|—|
|Bootgly HTTP_Client_CLI|568,058|1.07ms|56.95 MB/s|
Three different benchmark runners, all built-in (except wrk). The TCP client sends raw pre-built HTTP packets — that's the theoretical ceiling. The HTTP client builds and parses real HTTP requests/responses with full RFC compliance — that's the realistic throughput. WRK sits in between. All three confirm the server sustains 568k–630k req/s on a single machine with pure PHP + OPcache/JIT.
To provide context: Workman at TechEmpower Round 23 — the fastest pure PHP framework there — achieved approximately 580,000 requests per second on dedicated hardware. Bootgly reaches that level, with a difference of about 3% (a technical tie).
Why this absurd performance?
I tried replacing
stream_select with libev or libuv and it got worse — the bottleneck is in the C ↔️ PHP bridge, not in the syscall.The C → PHP callback dispatch via
zend_call_function() is approximately 50% more expensive than a direct PHP method call. Many people don't know this, but stream_selectGitHub
Release v0.13.0-beta · bootgly/bootgly
Focus: HTTP Client CLI + Linter (Imports Formatter)
🆕 MINOR version
Changes
WPI — Web Programming Interface
HTTP Client CLI (WPI/Nodes/HTTP_Client_CLI)
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIO...
🆕 MINOR version
Changes
WPI — Web Programming Interface
HTTP Client CLI (WPI/Nodes/HTTP_Client_CLI)
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIO...
Bootgly v0.13.0-beta — Pure PHP HTTP Client (no cURL, no Guzzle, no ext dependencies) + Import Linter
Hey r/PHP,
I just released [v0.13.0-beta](https://github.com/bootgly/bootgly/releases/tag/v0.13.0-beta) of [Bootgly](https://github.com/bootgly/bootgly), a base PHP 8.4+ framework that follows a zero third-party dependency policy.
Just install `php-cli`, `php-readline`, and `php-mbstring` for PHP 8.4, and you'll have a high-performance HTTP server and client (see Benchmarks bellow)! No Symfony components, no League packages, nothing from Packagist in the core.
This release adds two main features:
# 1. HTTP Client CLI — built from raw sockets
Not a cURL wrapper. Not a Guzzle fork. This is a from-scratch HTTP client built on top of `stream_socket_client` with its own event loop:
* All standard methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
* RFC 9112-compliant response decoding — chunked transfer-encoding, content-length, close-delimited
* 100-Continue two-phase requests (sends headers first, waits for server acceptance before body)
* Keep-alive connection reuse
* Request pipelining (multiple requests queued per connection)
* Batch mode (`batch()` → N × `request()` → `drain()`)
* Event-driven async mode via `on()` hooks
* SSL/TLS support
* Automatic redirect following (configurable limit)
* Connection timeouts + automatic retries
* Multi-worker load generation (fork-based) for benchmarking
The whole client stack is \~3,700 lines of source code (TCP layer + HTTP layer + encoders/decoders + request/response models) plus \~2,000 lines of tests. No magic, no abstraction astronautics.
**Why build an HTTP client from scratch instead of using cURL?** Because the same event loop (`Select`) that powers the HTTP Server also powers the HTTP Client. They share the same connection management, the same non-blocking I/O model. The client can be used to benchmark the server with real HTTP traffic without any external tool.
# 2. Import Linter (bootgly lint imports)
A code style checker/fixer for PHP `use` statements:
* Detects missing imports, wrong order (const → function → class), backslash-prefixed FQN in body
* Auto-fix mode (`--fix`) with `php -l` validation before writing
* Dry-run mode
* AI-friendly JSON output for CI integration
* Handles comma-separated `use`, multi-namespace files, local function tracking (avoids false positives)
Built on `token_get_all()` — no nikic/php-parser dependency.
# Benchmarks (self-tested, WSL2, Ryzen 9 3900X, 12 workers)
*Numbers below reflect* [*v0.13.1-beta*](https://github.com/bootgly/bootgly/releases/tag/v0.13.1-beta)*, a patch release with HTTP Client hot-path optimizations (+29.6% throughput) and cache isolation tests.*
Scenario: 1 static route (Response is 'Hello, World!'), 514 concurrent connections, 10s duration.
|Runner|Req/s|Latency|Transfer/s|
|:-|:-|:-|:-|
|**Bootgly TCP\_Client\_CLI**|**629,842**|553μs|81.69 MB/s|
|**WRK** (C tool)|**595,370**|—|—|
|**Bootgly HTTP\_Client\_CLI**|**568,058**|1.07ms|56.95 MB/s|
Three different benchmark runners, all built-in (except wrk). The TCP client sends raw pre-built HTTP packets — that's the theoretical ceiling. The HTTP client builds and parses real HTTP requests/responses with full RFC compliance — that's the realistic throughput. WRK sits in between. All three confirm the server sustains **568k–630k req/s** on a single machine with pure PHP + OPcache/JIT.
To provide context: [Workman at TechEmpower Round 23](https://www.techempower.com/benchmarks/#section=data-r23&test=plaintext&l=zik073-pa7) — the fastest pure PHP framework there — achieved approximately 580,000 requests per second on dedicated hardware. Bootgly reaches that level, with a difference of about 3% (a technical tie).
Why this absurd performance?
I tried replacing `stream_select` with `libev` or `libuv` and it got worse — the bottleneck is in the C ↔️ PHP bridge, not in the syscall.
The C → PHP callback dispatch via `zend_call_function()` is approximately 50% more expensive than a direct PHP method call. Many people don't know this, but `stream_select`
Hey r/PHP,
I just released [v0.13.0-beta](https://github.com/bootgly/bootgly/releases/tag/v0.13.0-beta) of [Bootgly](https://github.com/bootgly/bootgly), a base PHP 8.4+ framework that follows a zero third-party dependency policy.
Just install `php-cli`, `php-readline`, and `php-mbstring` for PHP 8.4, and you'll have a high-performance HTTP server and client (see Benchmarks bellow)! No Symfony components, no League packages, nothing from Packagist in the core.
This release adds two main features:
# 1. HTTP Client CLI — built from raw sockets
Not a cURL wrapper. Not a Guzzle fork. This is a from-scratch HTTP client built on top of `stream_socket_client` with its own event loop:
* All standard methods (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
* RFC 9112-compliant response decoding — chunked transfer-encoding, content-length, close-delimited
* 100-Continue two-phase requests (sends headers first, waits for server acceptance before body)
* Keep-alive connection reuse
* Request pipelining (multiple requests queued per connection)
* Batch mode (`batch()` → N × `request()` → `drain()`)
* Event-driven async mode via `on()` hooks
* SSL/TLS support
* Automatic redirect following (configurable limit)
* Connection timeouts + automatic retries
* Multi-worker load generation (fork-based) for benchmarking
The whole client stack is \~3,700 lines of source code (TCP layer + HTTP layer + encoders/decoders + request/response models) plus \~2,000 lines of tests. No magic, no abstraction astronautics.
**Why build an HTTP client from scratch instead of using cURL?** Because the same event loop (`Select`) that powers the HTTP Server also powers the HTTP Client. They share the same connection management, the same non-blocking I/O model. The client can be used to benchmark the server with real HTTP traffic without any external tool.
# 2. Import Linter (bootgly lint imports)
A code style checker/fixer for PHP `use` statements:
* Detects missing imports, wrong order (const → function → class), backslash-prefixed FQN in body
* Auto-fix mode (`--fix`) with `php -l` validation before writing
* Dry-run mode
* AI-friendly JSON output for CI integration
* Handles comma-separated `use`, multi-namespace files, local function tracking (avoids false positives)
Built on `token_get_all()` — no nikic/php-parser dependency.
# Benchmarks (self-tested, WSL2, Ryzen 9 3900X, 12 workers)
*Numbers below reflect* [*v0.13.1-beta*](https://github.com/bootgly/bootgly/releases/tag/v0.13.1-beta)*, a patch release with HTTP Client hot-path optimizations (+29.6% throughput) and cache isolation tests.*
Scenario: 1 static route (Response is 'Hello, World!'), 514 concurrent connections, 10s duration.
|Runner|Req/s|Latency|Transfer/s|
|:-|:-|:-|:-|
|**Bootgly TCP\_Client\_CLI**|**629,842**|553μs|81.69 MB/s|
|**WRK** (C tool)|**595,370**|—|—|
|**Bootgly HTTP\_Client\_CLI**|**568,058**|1.07ms|56.95 MB/s|
Three different benchmark runners, all built-in (except wrk). The TCP client sends raw pre-built HTTP packets — that's the theoretical ceiling. The HTTP client builds and parses real HTTP requests/responses with full RFC compliance — that's the realistic throughput. WRK sits in between. All three confirm the server sustains **568k–630k req/s** on a single machine with pure PHP + OPcache/JIT.
To provide context: [Workman at TechEmpower Round 23](https://www.techempower.com/benchmarks/#section=data-r23&test=plaintext&l=zik073-pa7) — the fastest pure PHP framework there — achieved approximately 580,000 requests per second on dedicated hardware. Bootgly reaches that level, with a difference of about 3% (a technical tie).
Why this absurd performance?
I tried replacing `stream_select` with `libev` or `libuv` and it got worse — the bottleneck is in the C ↔️ PHP bridge, not in the syscall.
The C → PHP callback dispatch via `zend_call_function()` is approximately 50% more expensive than a direct PHP method call. Many people don't know this, but `stream_select`
GitHub
Release v0.13.0-beta · bootgly/bootgly
Focus: HTTP Client CLI + Linter (Imports Formatter)
🆕 MINOR version
Changes
WPI — Web Programming Interface
HTTP Client CLI (WPI/Nodes/HTTP_Client_CLI)
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIO...
🆕 MINOR version
Changes
WPI — Web Programming Interface
HTTP Client CLI (WPI/Nodes/HTTP_Client_CLI)
GET, POST, PUT, DELETE, PATCH, HEAD, OPTIO...
has absurd performance and the call is 50% faster than a C ↔️ PHP bridge.
# Stats
* 37 commits, 467 files changed, +13,426 / −3,996 lines
* PHPStan level 9 — 0 errors
* 331 test cases passing (using Bootgly's own test framework, not PHPUnit)
# The "why should I care" part
I know r/PHP sees a lot of "my framework" posts. Here's what makes Bootgly different from Yet Another Framework™:
1. **Zero third-party deps in core.** The vendor folder in production has exactly one package: Bootgly itself. This isn't ideological — it means the HTTP server boots in \~2ms and the entire framework loads in a single autoboot.php.
2. **I2P architecture (Interface-to-Platform).** Six layers (ABI → ACI → ADI → API → CLI → WPI) with strict one-way dependency. CLI creates the Console platform, WPI creates the Web platform. Each layer can only depend on layers below it. This is enforced by convention and static analysis, not by DI magic.
3. **One-way policy.** There is exactly one HTTP server, one router, one test framework, one autoloader. No "pick your adapter" indirection. This makes the codebase smaller and easier to audit.
4. **Built for PHP 8.4.** Property hooks, typed properties everywhere, enums, fibers-ready. No PHP 7 compatibility baggage.
It's still beta — not production-ready. But if you're tired of frameworks where `composer install` downloads 200 packages to serve a JSON response, take a look.
GitHub: [https://github.com/bootgly/bootgly](https://github.com/bootgly/bootgly)
Release: [https://github.com/bootgly/bootgly/releases/tag/v0.13.0-beta](https://github.com/bootgly/bootgly/releases/tag/v0.13.0-beta)
Patch: [https://github.com/bootgly/bootgly/releases/tag/v0.13.1-beta](https://github.com/bootgly/bootgly/releases/tag/v0.13.1-beta)
Happy to answer questions and take criticism.
https://redd.it/1slnw50
@r_php
# Stats
* 37 commits, 467 files changed, +13,426 / −3,996 lines
* PHPStan level 9 — 0 errors
* 331 test cases passing (using Bootgly's own test framework, not PHPUnit)
# The "why should I care" part
I know r/PHP sees a lot of "my framework" posts. Here's what makes Bootgly different from Yet Another Framework™:
1. **Zero third-party deps in core.** The vendor folder in production has exactly one package: Bootgly itself. This isn't ideological — it means the HTTP server boots in \~2ms and the entire framework loads in a single autoboot.php.
2. **I2P architecture (Interface-to-Platform).** Six layers (ABI → ACI → ADI → API → CLI → WPI) with strict one-way dependency. CLI creates the Console platform, WPI creates the Web platform. Each layer can only depend on layers below it. This is enforced by convention and static analysis, not by DI magic.
3. **One-way policy.** There is exactly one HTTP server, one router, one test framework, one autoloader. No "pick your adapter" indirection. This makes the codebase smaller and easier to audit.
4. **Built for PHP 8.4.** Property hooks, typed properties everywhere, enums, fibers-ready. No PHP 7 compatibility baggage.
It's still beta — not production-ready. But if you're tired of frameworks where `composer install` downloads 200 packages to serve a JSON response, take a look.
GitHub: [https://github.com/bootgly/bootgly](https://github.com/bootgly/bootgly)
Release: [https://github.com/bootgly/bootgly/releases/tag/v0.13.0-beta](https://github.com/bootgly/bootgly/releases/tag/v0.13.0-beta)
Patch: [https://github.com/bootgly/bootgly/releases/tag/v0.13.1-beta](https://github.com/bootgly/bootgly/releases/tag/v0.13.1-beta)
Happy to answer questions and take criticism.
https://redd.it/1slnw50
@r_php
GitHub
GitHub - bootgly/bootgly: Base PHP Framework for Multi Projects
Base PHP Framework for Multi Projects. Contribute to bootgly/bootgly development by creating an account on GitHub.
Instant view switches with Inertia v3 prefetching
https://freek.dev/3087-instant-view-switches-with-inertia-v3-prefetching
https://redd.it/1slyo1i
@r_php
https://freek.dev/3087-instant-view-switches-with-inertia-v3-prefetching
https://redd.it/1slyo1i
@r_php
freek.dev
Instant view switches with Inertia v3 prefetching | freek.dev
Over the past few months we've been building There There at Spatie, a support tool shaped by the two decades we've spent running our own customer support. The goal is simple: the helpdesk we always wished we had.
We care about using AI in a particular way.…
We care about using AI in a particular way.…
Why Projections Exist — Your First Read Model
https://medium.com/@dariuszgafka/why-projections-exist-your-first-read-model-ceaab247bc2b
https://redd.it/1slz17q
@r_php
https://medium.com/@dariuszgafka/why-projections-exist-your-first-read-model-ceaab247bc2b
https://redd.it/1slz17q
@r_php
Medium
Why Projections Exist — Your First Read Model
Event Sourcing gives you a complete history of everything that happened in your system. What it does not give you is a way to query it.
Is Claude my permanent co-author?
I wanted to migrate an old PHP web app that I wrote by hand to a modern framework, and chose Symfony. I prepared some docs, watched some symfony youtubes, and resisted getting started for months. Finally, I decided to see if Claude code could get me over the hump. Well, I'm astounded by the result. Completely rebuilt in a solid Symfony framework in about 10 days. Works beautifully. I had claude build documentation as well, but now I have a site whose internal wiring is really beyond my ability to manage responsibly. I can invoke Claude in the code base, and pick up work at any time, but I couldn't maintain the system without Claude. I feel peculiar about it now: I'm the (human) author but I have an AI partner that has to be part of the "team" going forward. I can't be the first person to get here. Any words of advice?
https://redd.it/1slxyp7
@r_php
I wanted to migrate an old PHP web app that I wrote by hand to a modern framework, and chose Symfony. I prepared some docs, watched some symfony youtubes, and resisted getting started for months. Finally, I decided to see if Claude code could get me over the hump. Well, I'm astounded by the result. Completely rebuilt in a solid Symfony framework in about 10 days. Works beautifully. I had claude build documentation as well, but now I have a site whose internal wiring is really beyond my ability to manage responsibly. I can invoke Claude in the code base, and pick up work at any time, but I couldn't maintain the system without Claude. I feel peculiar about it now: I'm the (human) author but I have an AI partner that has to be part of the "team" going forward. I can't be the first person to get here. Any words of advice?
https://redd.it/1slxyp7
@r_php
Reddit
From the PHP community on Reddit
Explore this post and more from the PHP community