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

Form Handler Component Laravel Package

hostnet/form-handler-component

Hostnet Form Handler Component offers a reusable way to define, validate, and process forms in PHP applications. It helps organize form logic, handle submissions consistently, and integrate cleanly into existing projects.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a plain Composer library, not a Laravel package — expect no service provider, no facade, and no config file to publish. The repository is unlisted, so treat the installed source as the documentation.

  1. Install and inspect:
    composer require hostnet/form-handler-component
    composer show hostnet/form-handler-component
    ls vendor/hostnet/form-handler-component/src
    
  2. Read composer.json first. It tells you the real integration surface: PHP constraint, whether it pulls in symfony/form, symfony/http-foundation, or PSR-7 messages, and therefore whether you are bridging Symfony's Request or Laravel's Illuminate\Http\Request.
  3. Skim the abstract base classes and interfaces in src/. In a component like this the entry point is almost always an abstract handler plus a result/value object — that pair is what you bind your own logic to.
  4. Pick the smallest endpoint you own — a newsletter signup, a contact form, a profile update — and make it the pilot. The win is a controller that does three lines instead of thirty.

A typical first pass looks like this (names will differ; match what's in src/):

final class UpdateProfileHandler extends AbstractFormHandler
{
    public function __construct(private UserRepository $users) {}

    protected function handle(array $data): FormHandlerResult
    {
        $user = $this->users->update($this->currentUser(), $data);
        return FormHandlerResult::success($user);
    }
}

Then in the controller:

public function update(Request $request, UpdateProfileHandler $handler)
{
    $result = $handler->handle($request->all());

    return $result->isValid()
        ? redirect()->route('profile')->with('status', 'Saved')
        : back()->withErrors($result->getErrors())->withInput();
}

If that compiles and the redirect works, you have understood 80% of the package.

Implementation Patterns

One handler per use case. Resist the urge to build a generic CrudHandler. The value of this pattern comes from each handler owning exactly one form lifecycle: bind → validate → mutate → return a result. It keeps handlers testable in isolation and keeps controllers from becoming orchestrators.

Return a result object, not a boolean. The whole point of a form handler is that the outcome carries both success data and validation errors. Map the result onto Laravel's session flash in one place — a small trait or a base controller method — so every form endpoint responds consistently:

protected function respond(FormHandlerResult $result, string $route)
{
    if ($result->isValid()) {
        return redirect()->route($route)->with('status', 'Saved');
    }
    return back()->withErrors($result->getErrors())->withInput();
}

Use DTOs if the package supports binding. If there is a data-mapping hook, map raw request arrays into a typed DTO before persistence. This gives you a second validation layer (constructor type checks) and makes handlers easy to call from jobs, commands, and tests without an HTTP request.

Integrate with Form Requests rather than replacing them. Laravel's FormRequest already does authorization and validation well. A common pragmatic split: authorize and validate in the FormRequest, then pass $request->validated() into the handler. You get Laravel's error bag and withInput() behavior for free while still keeping the mutation logic out of the controller.

Bind handlers in a service provider. Since there is no auto-discovery, register handlers (or the interfaces they implement) in AppServiceProvider::register(), or rely on Laravel's constructor injection and let the container resolve them. If the package expects a Symfony-style container or event dispatcher, that is where the adapter work lives.

Test at the handler level. Instantiate the handler directly, feed it an array, assert on the result. No HTTP kernel, no session, no middleware — this is the main reason to adopt the pattern.

Gotchas and Tips

  • Symfony heritage. Hostnet components are written for the Symfony ecosystem. Watch for Symfony\Component\HttpFoundation\Request, symfony/form, or a EventDispatcherInterface dependency in composer.json. If present, you need an adapter layer: convert Illuminate\Http\Request into the expected type at the controller boundary. Do not leak Symfony request objects into the rest of your Laravel app.
  • Validation semantics differ. Symfony's validator and Laravel's validator produce different error shapes. Check what the result object's getErrors() actually returns — an array keyed by field, a ConstraintViolationList, or a message bag — before wiring it into withErrors(). Convert explicitly.
  • No config means no escape hatch. If the package has hardcoded assumptions (a specific exception type, a logger interface), a thin wrapper class of your own is the extension point. Wrap the library rather than forking it.
  • Low adoption signal. Twelve stars and a single maintainer component means issues may go unanswered. Pin the version in composer.json, read the changelog between upgrades, and keep a thin abstraction so you can swap it out in an afternoon if it stalls.
  • Check the release date against your PHP version. The February 2025 release is recent, but confirm the PHP constraint matches what you run — components often drop older PHP versions in minor releases.
  • Debugging tip: if a handler silently no-ops, log the bound data immediately after binding, before validation. Most failures in this kind of component are binding failures (field name mismatch, missing CSRF token, empty payload) rather than logic errors.
  • Do not use it for JSON APIs. If your endpoint returns JSON, Laravel's validation exceptions and FormRequest already give you a clean 422 response. This package earns its keep on HTML form workflows where you need the success/error bifurcation in one place.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core