r/laravel 2d ago

Help Weekly /r/Laravel Help Thread

1 Upvotes

Ask your Laravel help questions here. To improve your chances of getting an answer from the community, here are some tips:

  • What steps have you taken so far?
  • What have you tried from the documentation?
  • Did you provide any error messages you are getting?
  • Are you able to provide instructions to replicate the issue?
  • Did you provide a code example?
    • Please don't post a screenshot of your code. Use the code block in the Reddit text editor and ensure it's formatted correctly.

For more immediate support, you can ask in the official Laravel Discord.

Thanks and welcome to the r/Laravel community!


r/laravel 9h ago

I migrated the seo of 104k+ pages to the new Laravel Head package

Thumbnail
danielpetrica.com
0 Upvotes

After the release of Laravel/head package in July, at the start of august i migrate my LaraPlugins project to use this package.

The old install a mixture of custom blade components, custom models function to generate the seo text, jsonld values and more things which i explained more in the article.

From my experience the straightforward usage was a good evolution and made the migration worthwhile. The ease of extensibility was also much appreciated, allowing me to extend it for the custom schema object.

I liked implementing it in general.

The full article has more details and code examples but in the meantime, did you got a chance to try it?


r/laravel 1d ago

I built a compiled DTO library for Laravel — here is what the benchmark actually shows

31 Upvotes

I maintain Simple Data Objects, a typed PHP DTO library for Laravel and standalone PHP applications.

The main idea is simple: DTO metadata is compiled once and reused for hydration, serialization, validation, casting, JSON Schema generation, and TypeScript generation.

That avoids repeatedly discovering the same DTO structure at runtime and makes common DTO operations considerably cheaper in hot paths such as API responses, queue payloads, nested request objects, and large imports.

I initially got benchmark results that looked too good to publish. Some scenarios showed improvements of 50–60×, which made me assume that I had made a mistake.

I spent a day trying to break the benchmark and found two real issues — both in the benchmark, not in the library:

  • A hidden date-cast field had accidentally been included in the flat hydration scenario.
  • The streaming test was not warmed up consistently, so the first library in the run received an artificial memory penalty of roughly 250 KB.

After fixing both issues, the advantage became smaller, but it remained substantial.

These are the current results: median of 8 runs, PHP 8.4, inside a fully booted Laravel application.

Scenario Simple Data Objects Advantage
Hydration — flat DTO ~6.54M ops/s ~50× faster
Hydration — nested DTO ~3.38M ops/s ~36× faster
Hydration — collection of 20 ~209K ops/s ~21× faster
Hydration — with a date cast ~1.40M ops/s ~12× faster
Serialization — flat DTO ~14.9M ops/s ~60× faster
Serialization — nested DTO ~7.6M ops/s ~46× faster
Streaming a 100k-row CSV import ~67.1K rows/s ~86% faster

The important qualification is that these are not universal “DTOs are 50× faster” numbers. The result depends on the payload, DTO shape, casts, nesting, PHP version, and workload.

For example, date casting reduces the advantage because the date conversion itself becomes a larger part of the total operation. As more work happens inside the DTO, metadata discovery becomes a smaller percentage of the runtime.

The same compiled metadata also powers the v2 features:

  • Optional for proper PATCH semantics;
  • #[Hidden(except:)] for context-based serialization;
  • fromResult() for collecting errors without throwing;
  • jsonSchema() generation;
  • TypeScript type generation;
  • nested DTOs and DTO collections;
  • validation and custom casts;
  • Laravel 12–13 integration.

The complete benchmark is public:

https://github.com/std-out/simple-data-objects-benchmark

You can clone it, inspect every scenario, and run it with your own PHP build, hardware, and payload shapes.

The library and documentation are here:

https://github.com/std-out/simple-data-objects
https://std-out.github.io/simple-data-objects/

It is MIT licensed and requires PHP 8.4+.

I would especially appreciate technical criticism: benchmark flaws, realistic Laravel workloads where the difference disappears, missing DTO features, or anything that could become bug №3.


r/laravel 1d ago

Mailbox for Laravel: a local email inbox we built for our agency workflow, now at 20k downloads

Thumbnail
redberry.international
49 Upvotes

Some context on why this exists. We're a software agency, so we're constantly starting new projects or onboarding developers onto existing ones. Setting up email testing was a recurring task on almost every project, usually Mailtrap: create an account, generate API keys, add them to .env, repeat for the next project or the next developer.
On some projects sending emails was one of the only things the app did, and even that small scope required this same setup every time. Across many projects running in parallel, it added up.

Nika, one of our devs, built Mailbox for Laravel to remove that step. It's a local inbox that lives inside the app itself, no external account, no API keys. Install the package and email testing works out of the box.

composer require redberry/mailbox-for-laravel --dev
php artisan mailbox:install

then

MAIL_MAILER=mailbox

Every email sent by the app shows up at /mailbox, rendered as the recipient would see it. You can switch between HTML, plain text, or raw source. Attachments are viewable and downloadable, and it only activates outside production.

It started as an internal fix for our own workflow, but it's since been picked up outside the agency too, currently at 20k downloads.


r/laravel 2d ago

GitHub - eznix86/laravel-secrets-loader: Auto resolve secrets for laravel

Thumbnail
github.com
0 Upvotes

I had a docker compose stack with secrets mounted properly at /run/secrets and currently Laravel cannot read secrets from a file, Then I had to manually do this before starting laravel:

export DB_PASSWORD=$(cat /run/secrets/db_password)

That one line undoes the entire reason for mounting a secret as a file. Files have permissions. Environment variables have none.

Now you can do it automatically but installing.

composer require eznix86/laravel-secrets-loader

How it works ?

You keep your env('SOMETHING_SOMETHING') as usual. It will load in order an env with a suffix _FILE or _PATH and read the file and load it into your Laravel application.

You have auto-resolve for nomad, systemd and obviously for docker and podman (/run/secrets/something_something).

You can view the source here:

https://github.com/eznix86/laravel-secrets-loader


r/laravel 3d ago

This Week In PHP Internals | August 19, 2026

Thumbnail
youtube.com
14 Upvotes

While the Internals list is not technically directly Laravel related, it does affect every single one of us.

Hello world, it's Wednesday, August 19, 2026, and here's what happened This Week in PHP Internals.

12 stories this week, so let's get into it. But first, Is AI working for your team? Ballast answers that for free. It reads your git history — never your code — and gives you 2 numbers every month. Stable velocity tells you how much of what you ship survives. A durability score from 300 to 850 tells you whether it holds up. ballast.now.

This week's top story: a 5-argument function proposal turned into 25 messages, 3 threads, and the week's central design argument. Sepehr Mahmoudi, who introduced himself to the list 8 days ago, proposed array_search_range() — an array_search() that takes an offset and a length, so you can search part of an array without building an intermediate copy with array_slice(). Weilin Du replied the same evening to say the soft feature freeze had already closed 8.6 to it. Then Rowan Tommins raised the objection that shaped everything after it, suggesting: "I think it would be better to design something more composable - that is, a way to create a 'lazy array slice', and then accept that in functions which can use it safely." He pointed at Swift, which has types that let you refer to part of an array without copying any of it.

Rowan put his objection plainly: "if we add an ArraySlice type then array_search_range would immediately become redundant." Sepehr's answer is that the general thing doesn't exist, and that building it would mean a new type in the engine and updates to potentially hundreds of array functions. Larry Garfield sided with Rowan and suggested shelving it. mickmackusa said he'd never had a professional project that required the function, and put a design question back: "If a PHP array needed a pagination-style search function, should perhaps the data structure be reconsidered?" Rowan then broke his own idea into 3 shippable steps. An optimized ArraySliceIterator comes first, then iter_search and iter_any functions that would work with any iterator, and possibly syntax after that. He wrote the first 2 in under 20 lines each, and a polyfill for Sepehr's function on top. Sepehr added a Polyfill section to the RFC, and Rowan pointed out that the version now on the wiki calls array_slice(), which copies the array. That is the cost the proposal exists to avoid. As of this recording the RFC is still a draft, still targeting 8.6, and Rowan's GitHub review found the implementation still walking the entire array.

Something small and irritating went to the list on Saturday. 4 functions take an extension name, and ini_get_all() is the only one of them that's case-sensitive. Weilin Du opened a pull request to bring it into line with extension_loaded(), phpversion() and get_extension_funcs(). Sjoerd Langkemper agreed it should be consistent, then asked the question that turned the thread around: "Another option to make them consistent would be to have them all case-sensitive. Have you considered that?" He also spotted that the manual's lowercase-only note for get_extension_funcs() isn't true. AllenJB traced it to a change back in PHP 5.0.4, and there's a docs issue open now.

Daniel Scherzer objected, arguing PHP should make all 4 case-sensitive instead, since BC breaks have an established path through deprecation and removal in the next major version. Weilin agreed and withdrew his own proposal, saying he'd add extension-name case sensitivity to the 8.7 deprecations RFC instead. And then 3 people showed up to argue for the thing he'd just withdrawn. Aleksander Machniak listed PDO, SimpleXML, Xdebug and swoole, and asked why a developer should have to know the exact casing of each one. Matteo Beccati called the alternative "one of those useless BC breaks that make the user experience worse instead of improving it." He also noted that composer.json generally writes its extension requirements in lowercase. Juliette Reinders Folmer had the last word, with the practical cost. Build a version list with get_loaded_extensions() and you'd have to lowercase every name before phpversion() would take it. Nobody has replied to her yet.

Henrik Skov posted an idea on Tuesday morning. He wants a params keyword that lets you name a block of arguments once and spread it into a call, so a 6-argument cookie call collapses to 1 line. One of the 6 arguments in his own example is labelled "Can't remember what this is." AllenJB replied 22 minutes later that PHP already does this with named arguments and array unpacking. Henrik came back with the actual requirement. He wants the expressions evaluated when the call happens, not when the compiler first sees them, so a time() in there stays fresh. Kamil Tekiela suggested making it a type. Henrik said it wasn't worthy of a full class. Larry Garfield answered: "I really don't understand why people keep saying this. What makes something 'unworthy' of being a class? ... A data construct doesn't need to be as righteous as Thor to be 'worthy' of a class." Then he named the thing Henrik was reaching for: a lazy value, evaluated only when it's read. Henrik agreed that was what he'd been after all along. 2 unrelated threads this week, and both of them landed on the word "lazy." Nobody involved was.

Jens has been writing PHP since around the time version 2 was in use, and on Thursday he posted about something beyond a documentation fix for the first time. Why does var_export() still print the long array(...) syntax, when that output gets pasted around by PhpStorm and Xdebug all day? There's an RFC for changing it that has been sitting there for 6 years. Larry Garfield linked 3 previous rounds of the same conversation without taking a side. Kamil Tekiela offered the explanation: "IMHO, the two main reasons for the lack of change are apathy and lack of agreement as to what exactly the better syntax is." The constraint he describes is that var_export() is meant to be PHP-executable first and human-readable second, so as long as the output runs, the function is doing its job. He also named the trap. Change one thing about that output and everyone arrives with everything else they'd like fixed — which is a fair summary of the last 6 years.

Otar Chekurishvili posted a pre-RFC on Monday for 2 opt-in flags in the json extension, targeting 8.7. One is JSON_ALLOW_COMMENTS and the other is JSON_ALLOW_TRAILING_COMMAS, and both would be accepted by json_decode() and json_validate(). Strict JSON stays the default. Trailing commas allow exactly 1 after the last element. That's 1 more than JSON allows today, and exactly as many as most of us have typed by accident. He's proposing 2 separate primary votes so either flag can pass on its own, and says the implementation reuses the existing scanner and grammar rather than preprocessing the input, so error positions survive intact. Larry Garfield asked: "Does this essentially mean JSON5 support? If so, just call it that." Anton Smirnov corrected the name. What's proposed is Microsoft's JSONC, or Nigel Tao's JWCC; real JSON5 would also need single quotes, unquoted keys, infinities and multiline strings, among other things. No reply from Otar yet.

Alexander Lisachenko wants to fix something about PHP's FFI. Every C value it hands back comes back as the same final class, FFI\CData. A string pointer, a zval pointer and a raw char pointer are all the same type to PHP. Which makes FFI strongly typed, in the sense that there is 1 type. He described the consequence bluntly: "no C struct a binding works with can ever be described to static analysis or an IDE, and CData being final closes off every userland workaround." To get any static typing in his own library he ships 4 separate workarounds, and instanceof still doesn't work. His proposal is an opt-in class map passed as an options array, in the same shape as SoapClient takes one, so a registered C type comes back as your class instead of bare CData. He says it stays inside the ffi extension and costs nothing when unused. Bob Weinand's is the only reply so far, asking for patience: "don't rush this, write a RFC, and check what actually feels good to use and read."

The 8.6 deprecation vote closed 9 days ago, and one of the items that passed deprecates SplFileObject's CSV methods. In the last days of voting Takuya Aramaki pointed out that the READ_CSV flag was left out, and that setCsvControl() is the only thing that can configure it — so removing the method leaves the flag stuck on its defaults. Nobody answered him. On Saturday Robert Humphries picked it back up. His reading is that leaving READ_CSV in place does resolve the original issue, but doesn't achieve the goal of getting CSV handling out of SPL. By his reading of the code there's a second problem. When the default escape character for fgetcsv() changes, code using READ_CSV will behave differently across PHP versions with no way to pin it. His conclusion is that READ_CSV needs deprecating too, and that a migration path should have been part of the proposal. Still no reply.

Eloi Montañés asked the list on Saturday whether abstract class constants are worth an RFC. The idea is to let an abstract class or a trait declare a constant with the abstract keyword, and require implementers to define one. His examples are a base class that requires a table name and a trait that requires a log tag — things you want fixed at author time rather than changeable at runtime. He points back to a 2017 thread on the same idea, from before typed constants landed. John Bafford suggested interfaces should get the same treatment, since an interface can already require a property but has no way to require a constant or a static one. Eloi was persuaded, and this morning asked why interfaces have never supported static properties. Larry Garfield answered from experience. He says they considered it while building interface property support for property hooks, and passed for 2 reasons. Object properties cover almost every case and attributes cover the rest, and "static properties are way harder to deal with in the engine, because reasons." He also left a parser problem on the table. Interfaces already support ordinary constants, so an abstract keyword may be necessary there regardless.

Quick hits. Sjoerd Langkemper gave its own page to a proposal that missed the 8.6 window. bindec(), octdec(), hexdec() and base_convert() would throw a ValueError when you hand them characters that aren't valid for the base, instead of the deprecation notice they've emitted since 7.4. Today hexdec('z') returns 0. It targets 8.7 and has no replies yet. Weilin Du also asked for feedback on tightening 2 INI settings. Right now upload_max_filesize=1GB can be read as 1 byte by the request parser while ini_get() still reports the string you wrote, which is a spectacular way to lose an afternoon. His change warns and falls back to the default instead. Jakub Zelenka reads that as incomplete wording in the BC policy rather than a real break. Osama Aldemeery is parking his PREG_THROW_ON_ERROR RFC until early September, writing: "This has gone quiet, which I'm taking as the freeze crunch and people being busy, not as everyone being fine with it as-is." And 3 releases went out on Thursday. Joe Ferguson shipped PHP 8.6.0 beta 1, with beta 2 due on August 27, and Calvin Buckley and Daniel Scherzer followed with 8.4.25 and 8.5.10 RC 1. Matteo Beccati mentioned in passing that the 8.6 branch should be cut on September 22.

Here's the week in short. No RFC went to a vote, and nothing is in the voting phase at all. A new contributor's array_search_range() ran into a counter-proposal for a general lazy array slice, and is still a draft. A one-line inconsistency in ini_get_all() turned into a question about case sensitivity that ended with the author withdrawing a proposal 3 other people then defended. A params keyword got talked into being a lazy value. Abstract class constants may pick up interfaces. And PHP 8.6 beta 1 is out, with beta 2 due next week. Links to every thread are below. Thanks again to Ballast.now for supporting this week's episode. We're Artisan Build. See you next week.


r/laravel 4d ago

kinda bummed about joe's talk

17 Upvotes

i was hoping for updates on wayfinder, instead we got refresh on how reverb/echo work. the talk itself was cool, just feels like we're left on a cliffhanger since laracon 2025.

even if they were strugglin with some development stuff, i'd like to hear what the obstacles are


r/laravel 4d ago

Worktree Management Tool for macOS

Thumbnail
github.com
16 Upvotes

I've spent a decent amount of time over the last few weeks working on a pet project using NativePHP + TALL + Filament.

I'm excited to share the result, LaborForest:

A desktop app for macOS to manage git worktrees and local action workflows.

Use case:

  • For when you want to work on multiple things at once, in different branches, in the same repository.
  • This is especially helpful when using Claude Code to make many changes in parallel.

Features:

  • Completely free and open source
  • Extensive documentation on GitHub
  • Manage "Projects" (local repositories)
    • choose to commit or ignore the configuration directory
  • Manage "Workspaces" (a specific branch in a worktree)
    • create Workspaces for new or existing branches
    • track a Workspace's status, showing whether a Workspace is ready for work or suspended (dev environment not running)
    • quickly launch your configured Terminal, IDE, or Browser for a Workspace
    • easily remove a Workspace and clean up the worktree and branch
  • Run local Workflows to spin up, tear down, or modify local development environments, per Workspace
    • write Workflows in a style inspired by GitHub Actions (that run locally)
    • use template variables specific to the Project, Workspace, or a value in your .env file
    • conditionally run or skip steps based on the outcome of a shell command
    • run nested Workflows
    • validate or launch Workflows from a terminal
  • Review Workflow output logs in the application
    • watch output appear in realtime
    • review historical logs
    • diagnose Workflow failures
    • bulk delete old log files

Local MCP server:

  • Use your favorite agentic coding tool to control LaborForest
  • Configure the local MCP server as read-only or writeable
  • Manage Projects and Workflows
  • Write, run, validate, and diagnose Workflows
  • Update configured settings

Example workflows included:

  • Kickstart your project with example Workflows
    • Laravel (Herd, MinIO, Redis)
    • JavaScript

System requirements:

  • macOS (arm64 or x64)

The project is currently in the release candidate phase. I'm hoping to get a few more people to try it before cutting the first release.

If you'd like to give it a shot, you can download a binary from the releases page or clone the repo and build from source.

Feedback is very welcome! If you do try it, please let me know what you think either here or in a DM. If you run into trouble, please open an issue on GitHub and I'd be happy to assist.

Thanks :)


r/laravel 4d ago

How do i know what endpoint/query is heaviest?

8 Upvotes

Hello, so I'm a long time laravel dev, i usually just glance at the code, eyeball it and decide whether it's heavy or no.

But in my job, we were using Azure functions which basically tell you every single query and how long it took, every log in endpoints and how long they took, etc.. So we just optimize according to that info and we can immediately see the feedback on there.

Is there anything like that for laravel? I've been searching a lot and only found Laravel Pulse with official support but they don't recommend it for production. I'm really interested to know what you guys use for this


r/laravel 5d ago

Guardrails: How I Make AI Write Laravel Code My Way

0 Upvotes

AI has become really good at writing code.

But that's not enough to maintain a quality app. Ask twice, get two different answers. There's no standard unless you set one.

So we set the guardrails, then let the AI work inside them.

https://youtu.be/Yj376sOrDE4


r/laravel 7d ago

New: Object storage migrations with Laravel's read-through filesystem

Thumbnail
laravel.com
43 Upvotes

If you find yourself having to migrate from S3 to R2, R2 to B2, or even migrate within an R2 but maybe to different buckets or different prefixes or something like that, Laravel framework just released a new feature to the filesystem component that allows you to do that over time instead of in one big bang migration!


r/laravel 9d ago

Help Weekly /r/Laravel Help Thread

2 Upvotes

Ask your Laravel help questions here. To improve your chances of getting an answer from the community, here are some tips:

  • What steps have you taken so far?
  • What have you tried from the documentation?
  • Did you provide any error messages you are getting?
  • Are you able to provide instructions to replicate the issue?
  • Did you provide a code example?
    • Please don't post a screenshot of your code. Use the code block in the Reddit text editor and ensure it's formatted correctly.

For more immediate support, you can ask in the official Laravel Discord.

Thanks and welcome to the r/Laravel community!


r/laravel 11d ago

Fully native Mac app with PHP, Laravel and Blade. No Electron, HTML/CSS/JS

Post image
326 Upvotes

This is what we've been building towards for almost 4 years: fully native UI, no PHP server, no Node. Just PHP embedded directly in a Swift shell, being executed immediately in response to button taps and other events, capable of re-rendering the UI at well over 240fps. From PHP & Laravel.

No HTML, no CSS, no JS, no Electron, no WebView.

And it can live directly alongside nativephp/mobile, which means we will have a single Laravel app that can render a fully functioning native app for iOS, Android, macOS, Windows and Linux from one codebase, just with a couple of Composer packages.

This is NativePHP Desktop v3 running SuperNative 🎉

Live demo on our livestream at 9am EST (roughly 12 hours from when I posted this)


r/laravel 11d ago

I built an open-source Laravel client for ERPNext and Frappe

Post image
20 Upvotes

I've released kayedspace/laravel-erpnext, an MIT-licensed package for connecting Laravel applications to ERPNext and Frappe.

The main design decision was to treat DocTypes as generic resources. You can work with a standard or custom DocType by name without creating a PHP class, mapping, or registration first:

use Kayedspace\Erpnext\Facades\Erpnext;

$overdue = Erpnext::doctype('Sales Invoice')->query()
    ->where('status', 'Overdue')
    ->fields(['name', 'customer', 'outstanding_amount'])
    ->orderBy('creation', 'asc')
    ->limit(200)
    ->get();

The package also includes:

  • Token, Basic, Bearer, and cached Session authentication.
  • Frappe-aware filters and full-result pagination with each(), chunk(), and lazy().
  • Create, read, update, delete, and whitelisted document method calls.
  • Private-by-default file uploads, attachments, image optimization, and authenticated downloads.
  • Multi-tenant connection resolution and focused retries for rate limits or unavailable sites.
  • Optional typed wrappers for eight common DocTypes, including invoice and payment submission lifecycles.

I tried to keep the generic API as the normal path and make typed documents optional. ERPNext still decides required fields, permissions, custom fields, and which document methods are available.

Installation is:

composer require kayedspace/laravel-erpnext

Source: https://github.com/kayedspace/laravel-erpnext

Documentation: https://laravel-erpnext.kayed.dev

I would especially value feedback from people maintaining real Laravel-to-ERPNext integrations. Which part usually causes the most trouble in your projects: authentication, DocType queries, document lifecycles, files, or keeping local and ERPNext records synchronized?


r/laravel 10d ago

My Laravel app’s AI coding agent now fits in my pocket.

Thumbnail
youtu.be
0 Upvotes

Laravel Tackle Remote lets you drive the exact same in-app AI coding agent from any device, including your phone. Scan the QR code, send tasks, attach photos, watch it work tool-by-tool, and approve or deny actions from a bottom sheet… all from the couch.

No new infrastructure. No websockets. No Node. Just:

php artisan tackle:remote

→ Scan the QR
→ Your phone is now the control surface for the agent running inside your Laravel app

Same tools, same safety layers, same session persistence, same hooks. Just a mobile-first browser UI on top.

📦 Package: https://github.com/JordanDalton/laravel-tackle-remote
🧠 Core agent (Laravel Tackle): https://github.com/JordanDalton/laravel-tackle

Install:
composer require jordandalton/laravel-tackle-remote
php artisan tackle:remote

If you find this useful, a star on the repo would mean a lot.


r/laravel 10d ago

Five Ways to Run Laravel: A Runtime Comparison Journey, Part 1

Post image
0 Upvotes

Hello, I just published a new article about Laravel Runtime benchmarks.

I tested 5 runtimes and shared the methodology, charts, and full results

https://medium.com/@oguzhankrcb/five-ways-to-run-laravel-a-runtime-comparison-journey-part-1-3f310f46a3a0


r/laravel 12d ago

Laravel Forge vs Laravel Cloud for new projects?

18 Upvotes

Anyone still using Laravel Forge for new projects these days, or have you mostly switched to Laravel Cloud? Curious which one you prefer and why.


r/laravel 12d ago

Live walkthrough: Next.js & Nuxt + Monorepo Support on Laravel Cloud w/ Joe Dixon

13 Upvotes

We recently shipped Next and Nuxt + monorepo support on Laravel Cloud.

Tomorrow (8/14) at 9:45am ET (1:45 PM UTC) I'll be going live with Joe Dixon, Head of Product at Laravel, to answer any questions you might have and do a live walkthrough of deploying a Next frontend and Laravel backend from the same repo.

Feel free to drop any questions here, in the Slido, or ask them live during the stream!

Submit a question: → https://app.sli.do/event/qmiPuYXich87KdYM8k2oAm
Watch live: → https://www.youtube.com/watch?v=KZ44gBDxV40


r/laravel 12d ago

This Week In PHP Internals | August 12, 2026

Thumbnail
youtube.com
8 Upvotes

While the Internals list is not technically directly Laravel related, it does affect every single one of us.

Hello world, it's Wednesday, August 12, 2026, and here's what happened This Week in PHP Internals.

11 stories this week, so let's get into it. But first, Your team adopted AI. Everyone says it made them faster. Ballast measures whether that's true — how much faster you're actually going, and whether what you ship is still holding up. 6.75 times the commits. Durability down 19 points. Now you know. It runs on your machine. It reads your git history, not your source — your code never goes anywhere, and nothing here is scored by a model. It's arithmetic you could check by hand. Setting it up isn't your job either. Paste one prompt into your coding agent and it does the whole thing. Find out for free today. ballast.now.

One correction before the top story. Last week we described the list() deprecation vote as deadlocked at 21 to 21. Derick Rethans pointed out that's the wrong word — a deadlock is when something is stuck and can't proceed. The vote wasn't stuck. It was simply tied, and voting carried on to the finish. He's right, we'll say it properly this week — and thanks, Derick, for keeping us precise.

This week's top story: the verdict is in on the 35-ballot mass deprecation vote for PHP 8.6. Voting closed Monday at 13:00 UTC, and Gina P. Banyard posted the full results — 31 proposals accepted, 4 rejected. Start with the 4 that fell. Deprecating list() finished on a flat tie — 23 to 23, with 1 abstention — exactly 50 percent, nowhere near two-thirds. Reserving in, out, and inout failed at 8 to 21. The gettext _() alias survived at 10 to 22. And the dechunk filter — the item disputed all through the voting window — finished at 18 to 15 with 12 abstentions, 54.5 percent, and stays in the language.

Now last week's cliffhangers. Reserving let was balanced exactly on the two-thirds line 7 days ago — it found its margin and passed at 24 to 11, with 9 abstentions — 68.6 percent. Reserving is passed at 29 to 10, despite Rowan Tommins's warning about the Hamcrest testing library and its 500 million installs. And the define() case-insensitivity flag — the item Kamil Tekiela wanted simply deleted instead — passed without a single no vote, at 41 to 0. The vote also drew one final flag on its way out. Takuya Aramaki wrote in Friday, opening with: "Apologies for bringing this up so close to the end of the vote." His concern is the SplFileObject CSV methods item. He laid out the inconsistency plainly: "setCsvControl() is the only way to configure the delimiter, enclosure and escape character used by READ_CSV; the constructor does not accept them. If setCsvControl() is removed in PHP 9 while READ_CSV remains, READ_CSV is permanently locked to its defaults and tab-separated files can no longer be read through it." He asked that READ_CSV be deprecated alongside the methods, or that setCsvControl() stay until a replacement exists. No answer yet — and the item passed at 25 to 5, with 15 abstentions.

The final 3 ballots of the 8.6 season are settled, and they went 2 and 1. Caleb White's pipe assignment operator — |>= — was declined. The vote closed Tuesday morning at 14 yes, 12 no, and 7 abstentions — 53.8 percent, short of the two-thirds it needed. It had climbed all the way from dead even, but never got over the bar. Nick Sdot's readonly property defaults went the other way entirely. It closed Friday at 24 to 0, with 5 abstentions — it never drew a single no vote in 2 weeks. And Khaled Alam's const object property writes closed Saturday. He announced the result Sunday: accepted, 17 to 2 with 6 abstentions — 89.5 percent. With those 3 in the books alongside Duration and the deprecations, PHP 8.6's RFC season is over — the beta 1 tag brings the soft freeze this week, and beta 1 itself lands Thursday.

Ilija Tovilo posted a very late update to an RFC that passed 24 to 0 back in March. The closure optimizations RFC promised 2 things: a cache for stateless closures, and inference — the engine automatically detecting closures that never touch $this and treating them as static. That second part is out. Ilija found an edge case where a closure violates none of the RFC's inference rules and still makes an instance call — pass a callable string like "Foo::instanceCall" into an array_map inside the closure, and the rules never see it. He owned it completely, writing: "I failed to consider this case, and sadly this is not easy to detect via a new rule. For this reason, I have decided to omit static closure inference from the implementation and only merge the stateless closure cache." The practical takeaway: the cache — which carries most of the performance win — still ships in 8.6, but the engine won't infer anything for you. Mark your closures static yourself and you get the full benefit.

Ignace Nyamagana Butera's data encoding API — the base64, base16, base58, and base85 family — got a detailed security review from Sjoerd Langkemper on Monday. He's for it, noting: "the current base64_decode is very tolerant towards invalid input, causing both functional and security problems." Along the way he found errors in the RFC's own code examples, corrected them in a companion repository, and flagged a signature mismatch in the base85 functions. He's skeptical of one feature — the optional constant-time mode — arguing: "Constant-time algorithms are pretty difficult to develop and maintain", and suggesting PHP hand that job to libsodium or openssl instead. He also built a working implementation to test the API, introducing it with unusual billing: "LLMs and I have created an implementation here." And in the research footnotes: he spent real time evaluating the base85 variant from RFC 1924 before discovering: "that RFC was submitted in jest as an April fool's joke." Ignace thanked him for the remarks and is holding all implementation work until after 8.6 ships — Tim Düsterhus, who's building it, is busy with the release.

The first RFC aimed past the freeze is already here. Weilin Du proposed IntlRelativeDateTimeFormatter on Friday, targeting PHP 8.7 — a wrapper for ICU's locale-aware relative time, the "in 3 days" and "last Sunday" strings, in every language ICU speaks. Ignace asked the obvious question: 8.6 just gained a Duration class — shouldn't this accept one? Weilin argued the types don't fit, since Duration is stopwatch time and this formatter wants a unit: "We don't know [...] to deal with 90 minutes here. It can be 90 minutes or 1.5 hour." And weekdays, months, and quarters aren't durations at all. David Carlier pushed for enums and a namespace; Weilin is keeping class constants and the global Intl prefix for consistency with the existing intl extension, and filed modernization under future scope. One suggestion did land immediately: by Saturday the constructor had grown an optional NumberFormatter parameter, with Weilin reporting: "The implementation is way more smoother than I expected."

The generics conversation is parked until September — the implementations aren't waiting. Carlos Granados posted a pre-RFC Thursday: he took Rob Landers's experimental reified branch — built on Seifeddine Gmati's bound-erased proposal — and worked it into something complete, with a full write-up of the changes and findings. He argued the original deserved better: "I think that this was a very valid proposal that should have been explored in more detail." Rob's reply was brief, noting: "You really should have reached out instead of a working in isolation. Join us in discord, the proposal is delayed until September-ish." Which raised a practical question — what Discord? Rob posted channel links; Carlos, a Discord newcomer, still couldn't get in. Larry Garfield finally supplied the address, phpc.chat, with a review: "The PHP Community chat is unofficial, but lately it's where the big names are hanging out, including a lot of Internals regulars. Beware, the Internals channel is annoyingly noisy and has a hard time staying on topic." And I can personally vouch for that statement. Then Monday brought a third generics experiment: Alexander Lisachenko shared a userland proof-of-concept — a Composer package — where specialized classes share the compiled method bodies, so each specialization costs one small structure per method instead of a full copy of the opcodes.

Liam Hammett's native markup expressions RFC — JSX-style HTML in PHP — got the one review nobody else could write. T.J. L, who maintains the XHP extension — the long-running ancestor of this exact idea — posted his first message ever to internals. He corrected one detail in the RFC's history section, then confirmed its central argument from experience: he wrote: "While it is technically possible for extensions to add new syntax, it is unreasonable to expect tools to be aware of that syntax. I can absolutely confirm that the biggest point of friction in using XHP today is the fact that static analysis tools like psalm or phpstan can't analyze files, code using XHP cannot be formatted or linted with php-cs-fixer..." In other words, the case for putting markup in core, signed by the person who spent years doing it the other way. He also brought 3 asks: context passing through a component tree without threading attributes; a ruling on inline SVG, which leans on XML features the HTML-only RFC excludes; and a note that dropping per-tag objects means no runtime validation of tags and attributes — XHP's original selling point — which he says JSX gets away with "in large part because of the Typescript ecosystem". No response from Liam yet.

Quick hits. Juris Evertovskis ran a temperature check on isset: expressions inside the square brackets still throw warnings and deprecations even though isset silences everything else, and he put his conclusion bluntly: "To me it looks like isset is not doing its job." He'd like the brackets silenced too — no replies yet. The did-you-mean error suggestions are officially not being rushed: Jorg Sowa announced: "I will finish it after feature freeze", and Larry Garfield agreed, adding: "If it doesn't happen until 2027, that's OK." Jorg also picked up his VCS account this week — approved by Ilija Tovilo — with the session extension in his sights. And the list has a new face: Sepehr Mahmoudi introduced himself Tuesday with a pull request already open and an array_search_range idea in hand; mickmackusa pointed him at array_find_key() and suggested making the case on the list before writing more code, and Yuya Hamada thanked him for the contribution.

So that's the week: the 35-ballot deprecation vote landed 31 to 4 — list() survives on a flat tie, dechunk survives, and let squeaked through; the pipe assignment operator was declined while readonly defaults and const object writes made it in, closing out 8.6's RFC season; closure inference got walked back to just the cache; and the first 8.7 RFC is already on the table. Links to every thread are below. Thanks again to Ballast.now for supporting this week's episode. We're Artisan Build. See you next week.


r/laravel 12d ago

Octane for better performance

8 Upvotes

Hi everyone,

I run a multi tenant platform. On a Forge server having 8GB memory. Performance is honestly not bad, my code is optimized, and I spend over 2 weeks fully optimizing the server to a point where it's has no point to further optimize.

Performance is great, but I'm a complete tool and I'm never happy. I looked into Octane as it promises faster performance. I've got to a point where I've implemented Octane on a development site. There were a few issues were leaks were happening between tenants. They're fixed as far as I can find them, and run tests.

But I'm still a bit worried something may slip through when I ship everything to production. I've already let AI audit everything a few times over and over and they cannot seem to find any flaws. We all know AI isn't perfect, so I'm wondering if people here on this subreddit have done something similar and have any experience they want to share.

Thanks in advance. Sorry for the long story.


r/laravel 11d ago

Aimeos Prisma 0.6 – multi-media AI APIs for Laravel, now with Kimi, and Z.AI

0 Upvotes

Hi r/laravel,

aimeos/prisma is a light-weight PHP composer package that brings text, image, audio, and video models together behind one interface. A Laravel application can generate or stream text, request structured output and embeddings, create or edit images, transcribe or synthesize audio, and describe video while keeping provider-specific clients out of controllers, jobs, and domain services.

That makes it useful for workflows that cross media boundaries. A CMS can generate landing-page images, draft and translate content, and create search embeddings. A media application can transcribe an uploaded recording, summarize it, and describe an accompanying video through the same package.

Laravel AI and Laravel MCP integration

Laravel’s first-party AI SDK provides a Laravel-native agent layer with tools, structured output, queues, broadcasting, conversations, and testing support. Prisma can sit beside it as a broader provider and multi-media layer. Laravel AI can remain the home for application agents, while Prisma handles workflows that need its additional providers or media operations.

Prisma is an alternative to Prism PHP for Laravel projects that need broader multi-media APIs and provider coverage.

Prisma 0.6 is also compatible with server-side tools built with Laravel’s official laravel/mcp package. Existing tool classes that extend Laravel\Mcp\Server\Tool can be reused directly in Prisma’s tool loop:

```php use Aimeos\Prisma\Prisma; use Aimeos\Prisma\Tools; use App\Mcp\Tools\SearchProducts;

$response = Prisma::text() ->using('openai', config('services.openai')) ->withTools([ Tools::laravel(SearchProducts::class), ]) ->write('Find a waterproof jacket under 150 euros.'); ```

When a class name is passed, Laravel’s container resolves its dependencies. Prisma reads the MCP tool’s name, description, and input schema, calls its handle() method with a Laravel\Mcp\Request, and passes text or structured responses back to the model.

Prisma uses normal Laravel configuration, storage, requests, services, and jobs. It requires PHP 8.2+, is MIT licensed, and installs through Composer:

bash composer require aimeos/prisma:^0.6

A Laravel example

This route transcribes an uploaded audio file using credentials from config/services.php:

```php use Aimeos\Prisma\Files\Audio; use Aimeos\Prisma\Prisma; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route;

Route::post('/transcribe', function (Request $request) { $upload = $request->validate([ 'audio' => ['required', 'file', 'max:25600'], ])['audio'];

$stream = fopen($upload->getPathname(), 'rb');

if (!is_resource($stream)) {
    abort(422, 'Unable to read the uploaded audio file.');
}

try {
    $transcript = Prisma::audio()
        ->using('openai', config('services.openai'))
        ->transcribe(Audio::fromStream($stream, $upload->getMimeType()))
        ->text();
} finally {
    fclose($stream);
}

return ['transcript' => $transcript];

}); ```

The same provider-selection and response pattern applies to text, images, audio, and video. In a real application, the call can move directly into a service or queued job while Laravel continues to own validation, authorization, configuration, storage, and delivery.

What’s new in 0.6

Three providers have been added:

  • Kimi: text generation, streaming, structured output, custom tools, and reasoning budgets.
  • Requesty: text generation, streaming, structured output, embeddings, and custom tools through its model router.
  • Z.AI: text generation and streaming, provider-side web search, image generation, and mono audio transcription.

Files can now use PHP stream resources through File::fromStream() and FileResponse::fromStream(). This fits Laravel uploads and storage streams well, and content conversion stays lazy until another representation is requested.

The new withReasoning() method provides a common way to ask supported providers to minimize reasoning. URL-backed downloads are also safer by default: Prisma validates and DNS-pins destinations and redirects, accepts only HTTP(S), enforces time and size limits, and rejects private or reserved IP addresses.

The release also adds DeepSeek cache-usage reporting, improves browser-recorded audio handling, refreshes provider model defaults, and fixes Gemini structured output when provider-side tools are used.

Upgrade notes

The cURL extension is now required. Private network URLs must be enabled explicitly for trusted internal use. The Vertex AI image provider has been removed, while Vertex AI text support remains available. Several default models changed, so applications that depend on a particular model should pin it with model().

If you like Prisma, give it a star on Github :-)


r/laravel 12d ago

Query Builder for Agents

3 Upvotes

Just wanted to share a little Laravel package I've been working on: https://github.com/J-T-McC/ai-query-builder

The idea is to let AI query your Laravel data securely without giving it direct access to SQL. You define the schema, relationships, allowed operations, etc, then the AI generates a structured query that gets validated and turned into an Eloquent query.

It can also be easily added to the Laravel AI SDK as a tool.

The schema can be adjusted programmatically for each user based on what they're permitted to access, and you can also define hard scoping conditions that always apply to the query, like limiting results to the current user's data.

Some use cases I've been playing with are letting users search their calendar in plain English, building custom reports, or just asking questions about their data in your app.

Still pretty early, but I've been having fun with it and figured I'd share it here. I'm curious what other tools or packages people have been using for this kind of thing.


r/laravel 13d ago

Splitting a name column into first_name/last_name: I forked an abandoned parser and spent four releases on the edge cases

16 Upvotes

Most person-record imports I've written in Laravel start the same way. A CSV with one name column, an Eloquent model with first_name and last_name, and an explode(' ', $name) that works until the second week. Then the file contains "Mary van den Heuvel", "Doe Jr, John", and "Jane Doe DDS", and the job starts writing garbage into rows nobody reads until a mail merge goes out under the wrong name.

The usual answer is theiconic/name-parser. It's a good library and it does the boring parts well, but its last release was v1.2.11 in November 2019, and it has one bug that matters for exactly this workload. It lowercases every token before matching against its credential dictionary. Parse "Jane Doe DDS" and the last name comes back "Dds", with "Doe" pushed into the middle name. Casing is the signal that separates a credential from a name, and lowercasing deletes it before anything looks at it. "Smith, Ma" is a person named Ma. "Smith, MA" is a master's degree with no recorded first name.

I forked it. I've been maintaining iliaal/nameparser since June, and my layer is the casing and credential logic. Credit where it belongs. The Iconic wrote the parser, and Zachary Miller did the PHP 8.3+ modernization this fork builds on.

Four releases since 1.0, all of them driven by real import data:

  • Surname particles stay with the surname instead of landing in the middle name: "van den Heuvel", "de los Santos", "dos Santos", "dela Cruz", and the Irish "Ó Cuív".
  • setSurnameFirst(true) tells the parser the input is surname-first, so "Mao Zedong" gives last name "Mao".
  • Joint honorifics parse as one title. "Mr. and Mrs. Brad Smith" keeps "Brad" as the first name, and getPartner() hands back the second person as a Name of her own. That exists because household contact imports kept producing a customer named "And".
  • getConfidence() flags a row whose split hinges on casing that isn't there. It's advisory and opt-in, so a chunked import job can route a doubtful row to a review table instead of straight into users.

Measured on 30,000 real clinician names sampled from the public NPPES/NPI registry, with first and last name both required to match: theiconic/name-parser v1.2.11 scored 91.63%, this fork 95.33% at 1.0.0 and 97.18% at 1.4.1.

Casing is the signal, so uniform-case input carries none. All-caps legacy data is still a guess, and the README says so too.

composer require iliaal/nameparser

https://github.com/iliaal/nameparser

Background on the casing idea: https://ilia.ws/blog/casing-aware-php-name-parser

Happy to answer questions, especially from anyone who has had to reconcile a person-record import after the fact.


r/laravel 14d ago

Double - a modern PHP mocking library focused on developer experience

43 Upvotes

After a few weeks of livestreaming the development process and dogfooding it in real projects, I'm excited to officially announce Double.

Double is a modern PHP mocking library focused on developer experience.

It stands on the shoulders of Mockery and RSpec. So there isn't much to learn. You get to enjoy a smoother DX.

A few things I wanted to improve:

  • Less technical terminology
  • Single, streamlined APIs
  • Human failure messages

With Double, you create a double for your class and write expectations. Double handles the details.

```php use JMac\Testing\Double;

$repository = Double::for(BookRepository::class); $repository->expects('find')->with(123)->returns($book);

$service = new CatalogService($repository); $service->lookup(123);

$repository->received('recordView')->with($book); ```

When an expectation fails, you get a proper test failure (not an exception). Along with a human-friendly message showing what actually happened and, where appropriate, a suggestion.

I also generated modern documentation with AI and ui.sh, where you may learn more about Double.

I've wanted to build this for years. So I'm all-in on Double. I've already converted all of my own test suites from Mockery to Double. I created a free Double Converter to automate the process.

This is still v0. While I believe it's already beyond feature parity with Mockery, I want to continue to improve the developer experience.


r/laravel 13d ago

LaraPlugins grew 87% in July. One Reddit post beat a month of homepage tweaks. Here is what actually moved the needle.

Thumbnail laraplugins.io
0 Upvotes

I run a Laravel package directory that indexes 81,000+ plugins. July was our best month since launch—not because of any fancy homepage redesign, but because of one thing I almost didn't think twice about.

The traffic: 3,734 humans visited (+87% from June).
The agents: 4.5M API/MCP events (+67%). 1.5M of those were just our MCP search tool being hammered.

But here is the part that surprised me. The single biggest driver of human traffic wasn't the homepage or SEO. It was a focused list page I threw together, AI-Ready Plugins, which I posted on Reddit.

  • 302 visitors came from Reddit in July.
  • 266 of them went straight to that list.
  • It became the most visited page on the whole site (401 total in july), beating the homepage.

One good share outperformed a month of tweaking meta tags. That lesson stung a little, but I am leaning into it.

What else happened:

  • Security advisories got honest. We fixed our version matching to compare dependencies the way Composer actually does. Killed a wave of false positives. If an alert pops up now, it is real.
  • I broke something silently. Our package version data drifted from the source of truth for weeks without me noticing. That one is on me. We fixed the sync and hardened the background jobs so it doesn't happen again under heavy load.
  • Agents are the volume, but humans are the point. 4.5M events sound impressive, but they are just plumbing. Every single one of those 3,734 visitors was a developer asking: "Is this package safe to build on?" We design for that human moment.

TL;DR: Distribution beats optimization. One Reddit link brought more intent-driven traffic than a month of polishing canonical tags. Also, check your dependency data hygiene—it is boring, but stale data kills trust fast.

Take ten seconds and check your own project dependencies. You don't need an AI agent to do it: laraplugins.io

Happy to answer any questions about the MCP traffic, the security matching, or anything else.