Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Helpful Traits Laravel Package

michael-rubel/laravel-helpful-traits

A collection of reusable traits for Laravel that cuts boilerplate across models, controllers, form requests, and more. Drop-in traits add common behaviors like UUIDs, slugs, query scopes, caching, and response helpers, keeping your code concise, consistent, and aligned with Laravel conventions.

View on GitHub
Deep Wiki
Context7

Getting Started

michael-rubel/laravel-safe-request is a small trait package (the GitHub repo name is the authoritative one — don't go looking for a helpful-traits package). The capability it provides changes a FormRequest so that property and array access ($request->key, $request['key']) resolve from $request->safe() instead of $request->all(). The practical effect: the magic accessor becomes a "validated-only" accessor, so unvalidated input cannot be read by accident through the most common syntax.

Minimal setup:

composer require michael-rubel/laravel-safe-request

There is no service provider or config file to expect from a trait package. Read the README first for the exact trait FQCN, then read src/ (small) and tests/ (small) to see the precise accessor overrides. Confirm the package's composer.json constraint against your Laravel version — 2.0.1 explicitly adds Laravel 10 support, and the constraint should now permit illuminate/* ^10.

Apply it to a form request:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use MichaelRubel\SafeRequest\...; // confirm exact name in README

class StorePostRequest extends FormRequest
{
    use SafeRequest; // package trait

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'body'  => ['required', 'string'],
        ];
    }
}

Then in the controller:

public function store(StorePostRequest $request)
{
    $title = $request->title;                 // backed by safe()
    $post  = Post::create($request->safe()->all());
}

First use case: a controller that currently does Post::create($request->all()) or scatters $request->foo lookups everywhere. Swap in the trait, then grep for property reads whose keys have no rule — those are exactly the places you were consuming unvalidated input.

Implementation Patterns

Apply once via a base request. The highest-leverage pattern is a single abstract base class that every request extends, so the trait is inherited everywhere and cannot be forgotten:

abstract class BaseFormRequest extends FormRequest
{
    use SafeRequest; // package trait
}

Bulk extraction through safe(). Prefer the ValidatedInput helpers over constructing arrays by hand:

Post::create($request->safe()->all());
Post::create($request->safe()->only(['title', 'body'])->all());
Post::create($request->safe()->except(['_token'])->all());

Keep an explicit escape hatch for raw input. The trait only changes magic access; input(), query(), all(), and has() still hit the raw request. Use them deliberately, not by accident:

$utm = $request->input('utm_source');   // raw, unvalidated

Nested data. Magic property access does not do dot notation. Use $request->safe()->all() plus data_get():

$city = data_get($request->safe()->all(), 'address.city');

Service/action handoff. Pass $request->safe()->all() or a DTO built from it into your domain layer. This keeps the "unvalidated input never leaves the HTTP layer" boundary intact.

Testing. Nothing changes from a test perspective — $this->post('/posts', $payload)->assertRedirect() still works, because the request is validated before the controller runs.

Compare, don't guess. During a migration, log both sides to build an inventory:

logger()->debug('safe', $request->safe()->all());
logger()->debug('validated', $request->validated());

Gotchas and Tips

  • 2.0.1 is a non-breaking patch. The only change is Laravel 10 support (laravel/framework ^10 / illuminate/* ^10 in the constraint). No API, trait-name, or behaviour changes, so bumping from 2.0.0 requires no code edits — just confirm your composer.json allows the new constraint and run composer update michael-rubel/laravel-safe-request.
  • Maintenance status, not abandonment. Earlier this package looked dormant; 2.0.1 signals it is still being updated for current Laravel majors. That lowers the risk of depending on it, but it remains a very small, low-star package with a single maintainer. The implementation is almost certainly a few lines overriding __get() and offsetGet(). If you want zero supply-chain surface, vendor that logic into your own BaseFormRequest — you get the same benefit with full control.
  • Only magic access is protected. $request->input('x'), $request->all(), $request->query(), $request->only(), and $request->has() still return raw input. The trait is a nudge, not a security boundary. Enforce it with code review or a static-analysis rule that bans $request->all() in controllers.
  • Lifecycle ordering. authorize() and prepareForValidation() run before the validator is populated, so safe() is not usable there. Use $this->input() and $this->route() inside those hooks.
  • Route parameters and other magic fallbacks. Laravel's Request::__get falls back to $this->route($key), which is how $request->post returns a route-model binding. If the trait replaces __get wholesale without that fallback, route-parameter property access can silently return null. Verify with a quick test, or override __get yourself as safe() → parent::__get().
  • Silent nulls instead of loud errors. Reading a key with no validation rule now yields null rather than the raw value. That is the point, but it can mask bugs during the transition. Audit controller reads against your rules() arrays.
  • merge() does not update safe(). The validator snapshots input at validation time; values merged afterwards are not reflected in safe() (or validated()).
  • safe() is Laravel 9+. It returns a ValidatedInput object, not an array — call ->all() before passing it to Model::create() or an action. validated() remains the plain-array alternative, and for most teams $request->validated() without this package is the lower-friction default.
  • JSON and file requests behave normally: validated JSON body keys appear in safe(), and UploadedFile instances come through when the key has rules. $request->file('x') is still raw and unaffected.
  • IDE/static analysis. Property access stays magic, so Larastan/Psalm and autocompletion won't understand $request->title. If type safety matters more than brevity, prefer a DTO built from $request->validated().
  • Check the repo once, not just the README. The repo has a changelog and PR history; skimming it tells you which Laravel majors are actually covered before you commit to the dependency.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager