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 Laminas Form Laravel Package

revolution/laravel-laminas-form

Bridges Laravel with Laminas Form, letting you build, render, and validate forms using Laminas components inside Laravel applications. Integrates form elements, validation, and view helpers while following Laravel conventions.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require revolution/laravel-laminas-form

The package is a thin bridge between Laravel's container/Blade and the Laminas Form component. It is not a form builder of its own — it wires Laminas\Form\Form instances into Laravel so you can keep using Laminas' element/filter/validator model inside a Laravel app.

Where to look first:

  1. The package's src/ directory — the service provider and the form-factory/resolver are the whole surface area. At 1 star and 0 dependents, the source is the documentation.
  2. The Laminas Form docs for Form, Element, InputFilter, and FormElementManager — most of your day-to-day API comes from Laminas, not this package.
  3. composer.json — confirm which Laminas Form major version is pinned; that dictates which APIs you can use.

First use case — a contact form:

// app/Forms/ContactForm.php
namespace App\Forms;

use Laminas\Form\Form;
use Laminas\Form\Element;

class ContactForm extends Form
{
    public function __construct()
    {
        parent::__construct('contact');

        $this->add(['name' => 'email', 'type' => Element\Email::class]);
        $this->add(['name' => 'message', 'type' => Element\Textarea::class]);

        $this->get('email')->setLabel('Email');
        $this->get('message')->setLabel('Message');
    }
}

Make it resolvable (either via the package's auto-wiring in the service provider or by explicitly binding it in a FormServiceProvider — check the source for which). Then in a controller:

public function create(ContactForm $form)
{
    return view('contact', ['form' => $form]);
}

At minimum you get object construction plus Laravel's container lifecycle. Everything past that (rendering, validation, hydration) is Laminas behaviour you drive yourself.

Implementation Patterns

Form objects, not form arrays. The core pattern is moving form definition out of Blade and controllers into dedicated Form subclasses in app/Forms. Each form owns its elements, labels, attributes, and an InputFilter for validation/filtering. Inject these into controllers — Laravel's container handles construction if the package registers a form factory or you bind them yourself.

Populate from the request. Laminas forms expect setData() or bind():

$form->setData($request->all());

if ($form->isValid()) {
    $data = $form->getData(); // already filtered
}

getData() returns filtered values, so Trim/StringToLower/ToInt filters do the sanitising for you — useful when you want transformation separate from Laravel's FormRequest validation.

Render elements in Blade manually. There is no Blade directive set here. Loop over elements and emit HTML yourself, or install laminas/laminas-view and call $this->formRow($form->get('email')) inside a view. A pragmatic middle ground:

@foreach ($form as $element)
    <label>{{ $element->getLabel() }}</label>
    {!! $element->getAttribute('type') === 'textarea'
        ? '<textarea name="'.$element->getName().'"></textarea>'
        : '<input name="'.$element->getName().'" type="'.$element->getAttribute('type').'" />' !!}
    @error($element->getName()) <span>{{ $message }}</span> @enderror
@endforeach

Two validation strategies — pick one. Either:

  • Laminas validation: build an InputFilter, call $form->isValid(), and pull messages via $form->getMessages(). Good when the form is self-contained and you want filters in one place.
  • Laravel validation: keep a FormRequest for HTTP validation and use the Laminas form purely as a rendering/HTML abstraction. This is the lower-friction choice in a Laravel codebase and avoids duplicating error-message plumbing.

Mixing both usually means two sources of errors in the same view — avoid.

Populate from a model. For edit screens, map Eloquent attributes into the form rather than binding the model directly:

$form->setData($post->only(['title', 'body']));

Reusable field factory. Since the package gives you Laminas elements, define small helper methods (e.g. a BaseForm with addText($name, $label)) to keep form classes short and consistent.

Testing. Forms are plain objects — unit test the InputFilter in isolation ($form->setData([...]); $this->assertFalse($form->isValid());) without touching HTTP. Feature tests still go through Laravel routes as normal.

Gotchas and Tips

  • The package is a thin shell — expect to read source. At 1 star and 0 dependents there is effectively no community, no Stack Overflow history, and no ecosystem of examples. Budget time to read the provider and the resolver to understand exactly what gets auto-registered.
  • Version pinning is the main integration risk. Check composer.json for the laminas/laminas-form constraint. Laminas Form has had breaking changes across majors (Form::add() signatures, element class names). If your app also pulls Laminas packages transitively (e.g. via an old Zend-bridge dependency), watch for conflicts.
  • Container wiring. If a form is auto-resolved by the package, constructor injection of services works; if you new it yourself, it does not. Be consistent — either always resolve through the container or always instantiate plainly.
  • CSRF is not free. Laminas forms don't hook into Laravel's CSRF middleware. If you're rendering forms by hand, include @csrf in your Blade template; don't assume a Csrf element in the Laminas form will validate against Laravel's session token.
  • Error messages live in two places. Laminas stores them in getMessages() keyed by element name, Laravel in $errors. If you mix strategies, normalise in the controller before passing to the view.
  • isValid() mutates the form. It sets data and runs filters in place. Don't reuse the same form instance across two requests in a single test without resetting data.
  • Attribute escaping. getAttribute() output is not escaped for you — escape manually if you're echoing element attributes into HTML.
  • Config caching. If you register forms or bindings in a config file, remember php artisan config:cache will freeze them; use a service provider for anything that resolves services at runtime.
  • Debugging. dd($form->getMessages(), $form->getData()) right after setData()/isValid() is the fastest way to see whether the problem is input, filter, or validator. Dump getInputFilter()->getInvalidInput() to find which element failed.
  • Extension points are in the provider. If you need custom elements or view helpers, extend/replace the package's factory rather than editing vendor code — check whether the provider publishes a config for a custom FormElementManager; if it doesn't, fork.
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