PHP Reddit – Telegram
PHP Reddit
34 subscribers
289 photos
37 videos
24.8K links
Channel to sync with /r/PHP /r/Laravel /r/Symfony. Powered by awesome @r_channels and @reddit2telegram
Download Telegram
Tech stack advice needed

Hi there,
I've been working with Drupal for most of my dev career so I know a thing or 2 about Symfony. I have no problems understanding Symfony's backed concepts but I'm a bit puzzled of what's a proper way to build the Front-End part.

My goal is to rebuild a personal Drupal based SaaS using Symfony.
Not because Drupal is not good but because I want to expand my tech knowledge and hopefully in the future land a job around Symfony ecosystem.

I'm basically trying to pick tech stack in between what's used in enterprise(job offers) and my own needs.

The thing is that when I started my SaaS, to satisfy my needs for refresh-less pages, I ported Livewire (Laravel) to Drupal known as "Wire Drupal". In Symfony word this would be "symfony/ux-live-component". I gave it a try, it's usable but I want to go a different route because I would like to build API for my app. Eventually I want to move some API to be served from a Go instance.

Based on my research, looks like this is what I need:
\- Symfony to build backend, API
\- Login, register, homepage, ... served with twig
\- Tailwindcss
\- Interactivity: use a FE framework like Vue or React (can't decide yet - I don't really like React but looks like everyone around using it) as components within templates which would make calls to API.

Now the biggest uncertainty I have is what's a proper way to get Vue/React to work as components?

I'm aware of "symfony/ux-vue" but I'm getting so confused of everything around it, specifically why so many dependencies around like stimulus, turbo; also the choice between Encore, AssetMapper.
It feel like too many dependencies around with unknown feature.

My goal is to have minimum maintenance(especially to the FE part) once built.

Should I just follow everything advised around "symfony/ux-vue" docs or try a different approach?

Thank you.



https://redd.it/1n3xdue
@r_php
Building a Robust Field Type System for Custom Fields v2

**TL;DR**: Rebuilt the field type architecture from scratch to eliminate boilerplate, add intelligent automation, and provide graceful error handling. Went from 10+ required methods to a fluent configurator API that generates working code in 30 seconds.

# The Problem That Started It All

After maintaining 30+ field types for [Custom Fields](https://custom-fields.relaticle.com/v2/introduction) V1, I kept running into the same issues:

* **Massive boilerplate**: Every field type required implementing 10+ interface methods
* **Manual option handling**: Choice fields needed custom logic for user-defined vs built-in options
* **Fragile system**: Deleting a field type class would crash any page displaying those fields
* **Poor DX**: Creating new field types took hours of copy-paste-modify cycles

The breaking point came when I realized I was spending more time maintaining the field type system than building actual features.

# Design Principles

I established four core principles for the v2 rewrite:

# 1. Convention over Configuration

Smart defaults with clear escape hatches. The system should work perfectly out-of-the-box but allow customization when needed.

# 2. Composition over Inheritance

Instead of rigid abstract classes, use fluent configurators that compose behaviors. This prevents the "deep inheritance hell" problem.

# 3. Fail Gracefully

Production systems can't crash because a developer deleted a field type class. The system must degrade gracefully and continue functioning.

# 4. Generate Working Code, Not TODOs

Commands should create immediately functional code, not skeleton files full of placeholder comments.

# The Architecture

# Configurator Pattern

The biggest change was moving from interface-based to configurator-based field types:

https://preview.redd.it/plv16lxa25mf1.png?width=3680&format=png&auto=webp&s=d3511a3ee6c0b807ecf411f7a429ecb2e55d0f6e

The configurator approach:

* **Encodes best practices**: You can't accidentally create invalid configurations
* **Reduces cognitive load**: Method chaining makes relationships clear
* **Prevents mistakes**: Type-safe configuration with IDE support
* **Enables intelligent defaults**: Each configurator knows what makes sense for its data type

# Intelligent Feature Application

The real breakthrough was solving the closure component problem.

In v1, closure-based components were "dumb" - they only did what you explicitly coded. Class-based components got automatic option handling, validation, etc., but closures missed out.

V2's `ClosureFormAdapter` changed this

https://preview.redd.it/tozdx0r935mf1.png?width=3680&format=png&auto=webp&s=29f92867c1b360d9ec10a37a28909609f81a3e3f

Now developers can write simple closures and get all the advanced features automatically applied.

# Graceful Degradation

One of the biggest production issues was fields becoming "orphaned" when their field type classes were deleted or moved. The entire admin panel would crash with "Class not found" errors.

The solution was defensive filtering at the BaseBuilder level

https://preview.redd.it/jr5h0lp235mf1.png?width=3680&format=png&auto=webp&s=dab99889d373e70c906e806b4f568e9a9f218adb

This single change made the entire system bulletproof against field type deletion.

# The withoutUserOptions() Design

This was the trickiest design decision. Initially, I thought:

* Single choice = built-in options
* Multi choice = user-defined options

But real-world usage broke this assumption. Users needed:

* Single choice with user-defined options (custom status fields)
* Multi choice with built-in options (skill level checkboxes)
* Both types with database-driven options (country selectors, tag systems)

The solution was making `withoutUserOptions()` orthogonal to choice type. It controls **WHO** manages the options, not **HOW MANY** can be selected:

https://preview.redd.it/wix7obsl25mf1.png?width=3680&format=png&auto=webp&s=837733e2b43b175abe0a028e901e5d8ebe1dbb92

This single flag unlocked infinite flexibility while keeping the API
simple.

# Interactive Generation

The generation command showcases the philosophy:

https://preview.redd.it/nxlq3r2o25mf1.png?width=3680&format=png&auto=webp&s=1273d65cc368e40c8712c396f9ca92ab6934dbcd

The interactive prompt shows data type denoscriptions:

* **String** \- Short text, identifiers, URLs (max 255 chars)
* **Single Choice** \- Select dropdown, radio buttons
* **Multi Choice** \- Multiple selections, checkboxes, tags
* etc.

Each selection generates the appropriate:

* Configurator method (`text()`, `singleChoice()`, `numeric()`)
* Form component (`TextInput`, `Select`, `CheckboxList`)
* Smart defaults (validation rules, capabilities)

# Real-World Impact

# For Package Maintainers

* **90% less boilerplate**: field types went from \~200 lines each to \~50 lines
* **Consistent behavior**: Shared configurators eliminated behavioral drift between field types
* **Bulletproof error handling**: No more production crashes from missing field types

# For Package Users

* **30-second field type creation**: Generate → customize → register → done
* **Automatic feature application**: Write simple closures, get advanced features
* **Clear extension patterns**: The configurator API guides you toward best practices

# The Philosophy

The best APIs are the ones that get out of your way. They should:

* **Make easy things trivial** (basic field types)
* **Make complex things possible** (dynamic database options)
* **Make wrong things difficult** (invalid configurations)
* **Make debugging obvious** (clear error messages and graceful degradation)

This field type system achieves all four by being opinionated about structure while flexible about implementation.

# Key Takeaways

1. **Fluent APIs reduce cognitive load** \- Method chaining makes relationships obvious
2. **Automatic feature application** \- Systems should be smart enough to apply features without explicit configuration
3. **Defensive programming pays off** \- Always assume things will be deleted, moved, or broken
4. **Generation > Templates** \- Create working code, not skeletons
5. **Orthogonal design decisions** \- `withoutUserOptions()` works with any choice type because it solves a different problem

Building developer tools is about eliminating friction while maintaining power. This field type system does both.

*Built with Laravel, Filament PHP, and way too much coffee *

https://redd.it/1n3ywjf
@r_php
Anyone tried Vizra?

I am looking to build AI agents on a Laravel app and I’m looking for the most efficient way to do so using a package. So far I’ve seen LarAgents mentioned a few times, but Vizra (https://github.com/vizra-ai/vizra-adk) seems a bit more polished?

Has anyone tried those?

https://redd.it/1n421oe
@r_php
I am working on an API for time conversion.

https://preview.redd.it/56dphgktqamf1.png?width=3092&format=png&auto=webp&s=5257182d2c42180ac9d52ebec3ae4904f2349fe2

Hello, there are surely already 200 that do the same; the intention is for it to be low-cost and that as it becomes profitable, more things can be integrated, such as countries, regionalization, and others. I come to share the idea here since the base is made in Laravel. The intention is for it to be accessible and solve the eternal problem of conversions easily and elegantly. I estimate launching the free version at the end of September to see how it works. Thanks you for your feedback

https://redd.it/1n4nbgw
@r_php
Built a free invoice generator with TALL stack

Hey folks 👋

I put together a simple invoice generator using the TALL stack + Laravel. No signup, no ads—just create and download invoices quickly.

👉 https://getfreecrm.com/tools/invoice-generator

Would love to hear what you think or how I can make it better!

https://redd.it/1n4stc3
@r_php
Uptime monitoring Forge

Hi, what do you guys use to get notified if the web app goes down and can't be accessed? Does Forge have this built in? Or do you use something else? Thanks

https://redd.it/1n4x53l
@r_php
Weekly /r/Laravel Help Thread

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!

https://redd.it/1n4zy53
@r_php
Weekly Ask Anything Thread

Feel free to ask any questions you think may not warrant a post. Asking for help here is also fine.

https://redd.it/1n5dv9t
@r_php
PHP 8.5 introduces a new flag called FILTER_THROW_ON_FAILURE, which, when used, causes the filter function to automatically throw an exception if validation fails, instead of returning false or null.

So, here’s how you would typically validate an email address without the new flag:

    if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
return false;
}



As you can see, you have to manually check the return value and handle the failure.

With the new FILTER_THROW_ON_FAILURE flag, you can simplify this:

    try {
filter_var($email, FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE);
return true;
} catch (\Filter\FilterFailedException $e) {
return false;
}


Read more


https://redd.it/1n5gfms
@r_php
Weekly help thread

Hey there!

This subreddit isn't meant for help threads, though there's one exception to the rule: in this thread you can ask anything you want PHP related, someone will probably be able to help you out!

https://redd.it/1n5gukf
@r_php
Symfony Rate Limiter Issue (Maybe?)

I've used this limiter in a few projects and it works as expected by autowiring it in the controller, no problems there.

I wanted to use it as a standalone component within a custom validator. That aside for now, to replicate the issue i am having, if you add this to a controller:

use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
use Symfony\Component\RateLimiter\RateLimiterFactory;
^^^ Remember to add these.

$factory = new RateLimiterFactory(
'id' => 'login',
'policy' => 'token_bucket',
'limit' => 3,
'rate' => ['interval' => '15 minutes',
], new InMemoryStorage());

$limiter = $factory->create();
$limit = $limiter->consume(1);

if (!$limit->isAccepted()) {
dd('limit hit');
}

dd($limit->getRemainingTokens());

Github Repo: https://github.com/symfony/rate-limiter

The above code is in the README of the repo. What i would expect on every refresh is the remaining tokens to count down then hit the limit but this will always show 2 remaining.

From looking at it, the storage is getting renewed every time and not persistent, but this is the "Getting started" code...

What am i doing wrong?

https://redd.it/1n5lw6k
@r_php
An alternative approach to Laravel route localization

Hey r/laravel, 👋

I'd like to share the package I've been working on. https://github.com/goodcat-dev/laravel-l10n

The core idea is to define localized routes and route translations directly in your routes/web.php file using the Route::lang() method. Here's an example:

Route::get('{lang}/example', Controller::class)
->lang(
'fr', 'de',
'it' => 'it/esempio',
'es' => 'es/ejemplo'
);

This single route definition handles:

`/{lang}/example` for French `fr/example` and German `de/example`.
Translated routes it/esempio, es/ejemplo.
`/example` for English, the default locale.

The main features I focused on were:

All route definitions in one place, with no need for separate translation files.
Automatically generates the correct URL for the active locale with the standard `route()` helper.
Automatically looks for locale-specific view files (e.g. views/es/example.blade.php) and falls back to the generic view if no localized version is found.
A mechanism to detect a user's preferred language based on the `Accept-Language` header and model that implements the `HasLocalePreference` interface.
No custom route:cache command required.

This package is still experimental, so there may be some bugs. I'd like to hear your thoughts on this approach to localization. What do you think?

You can check it out here: https://github.com/goodcat-dev/laravel-l10n

https://redd.it/1n5rhrf
@r_php
SheafUI: A 100% free Laravel Blade UI platform with CLI install, 33+ components, and full code ownership

We just released **SheafUI**, an open-source UI platform for Laravel developers.

The philosophy is simple:

* **Your code should be yours** : every component you install is native Blade + Alpine, copied into your project (no vendor lock) and supportable both alpine and livewire.
* **No copy-paste:** install with one command using the SheafUI CLI.
* **All free:** 33+ components today, with more coming soon.

Example:

php artisan sheaf:init
php artisan sheaf:install button

After that, the component lives in resources/views/components/ui/, fully editable and owned by you.

Website: [sheafui.dev](http://sheafui.dev)
CLI repository: [https://github.com/sheafui/cli](https://github.com/sheafui/cli)
Components repository: [https://github.com/sheafui/components](https://github.com/sheafui/components)

We’d love feedback from the Laravel community, which components would you like to see added next?

https://redd.it/1n5uax5
@r_php
Laravel Deployment on multi-project server

I manage a Hetzner server running three Laravel projects under HestiaCP and Debian.
Right now deployments run from a GitHub Actions workflow that uses SSH into the server and runs a remote deploy noscript whenever a PR is merged.

This works but doesn’t scale.
What deployment strategy would you recommend for a multi-project server like this?

https://redd.it/1n5xhst
@r_php
Config mixture: the Laravel way

I’m trying to add an external config source to my project. This config source I can access over HTTP. However, I would like to keep using config() to access configuration values.

On top of that, the values that I receive from the external source might be a reference to some env() value or another key in that external source.

Env values I have are coming either from .env file or OS.

So, I have a mixture of everything here.

What is THE Laravel way to configure such configuration sources?

https://redd.it/1n629rt
@r_php