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

Zend Mvc Plugin Fileprg Laravel Package

zendframework/zend-mvc-plugin-fileprg

A Zend Framework MVC controller plugin that implements the File Post/Redirect/Get pattern, letting you validate uploads before redirecting and preserve file upload state across requests.

View on GitHub
Deep Wiki
Context7

Getting Started

First, a reality check: this is not a Laravel package. zendframework/zend-mvc-plugin-fileprg is a controller plugin for Zend Framework 2/3 (now Laminas) MVC — it gives you a File Post/Redirect/Get workflow so an uploaded file survives a redirect (e.g. when validation fails and you re-render the form). If you're on Laravel, there is nothing to install here; the equivalent is $request->file() + $request->flash() / withInput(), or putting the file reference in the session and re-rendering the Blade form. Use this package only if you maintain ZF/Laminas apps.

composer require zendframework/zend-mvc-plugin-fileprg:^1.1

Release 1.1.0 is purely platform work: PHP 7.1 and 7.2 are now supported, HHVM is dropped. No API changes, so it's a safe composer update — and it's the version to pin if you're still on the Zend namespace but running a modern PHP 7.x runtime.

First use case: a form with a single file input where an invalid submission should not force the user to re-pick the file.

Where to look first:

  1. The package README — the controller example is the whole API in ~15 lines.
  2. Zend\Mvc\Plugin\FilePrg\FilePrg — read __invoke(); it's short and documents the three return states.
  3. The Zend\InputFilter\FileInput and Zend\Filter\File\RenameUpload docs — the plugin only reports what your input filter did.
  4. laminas/laminas-mvc-plugin-fileprg — the maintained successor; the repo you're on is archived.

Implementation Patterns

The canonical controller action. The plugin returns one of three things, and your action branches on all three:

use Zend\InputFilter\FileInput;
use Zend\Filter\File\RenameUpload;

public function uploadAction()
{
    $form = $this->form;               // injected UploadForm
    $prg  = $this->fileprg($form);     // optionally: ('route', ['id' => 42])

    if ($prg instanceof \Zend\Http\PhpEnvironment\Response) {
        return $prg;                   // POST was valid: 302 back to this URL
    }

    if ($prg === false) {
        return ['form' => $form];      // GET with no pending data: blank form
    }

    // GET after the redirect: $prg holds the filtered data
    $form->setData($prg);
    if ($form->isValid()) {
        $this->attachmentService->persist($form->getData());
        return $this->redirect()->toRoute('uploads');
    }

    return ['form' => $form];          // stale data, re-render
}

Make the form's input a FileInput, not the default Input. This is the single most common integration failure. The default input type ignores $_FILES entirely, so isValid() passes and you get an empty value.

$inputFilter->add([
    'name'       => 'attachment',
    'type'       => FileInput::class,
    'required'   => true,
    'filters'    => [[
        'name'    => RenameUpload::class,
        'options' => [
            'target'          => './data/uploads',
            'randomize'       => true,
            'use_upload_name' => true,
            'overwrite'       => false,
        ],
    ]],
    'validators' => [[
        'name'    => \Zend\Validator\File\Size::class,
        'options' => ['max' => '2MB'],
    ]],
]);

Use RenameUpload in the filter chain rather than moving the file in your controller. The plugin stores filtered data in the session, so a renamed/relocated file is what survives the redirect — leaving the move until the final branch means you're relying on a PHP temp path that may already be gone.

Persist in the post-redirect branch, not the POST branch. Treat the POST branch as "validate + redirect" and the second GET as "the user's intent is confirmed". This keeps the write idempotent-ish (a refresh of the final page still has the data) and matches the plugin's contract.

Wrap it behind a service. Controllers using $this->fileprg() directly are hard to unit test; either inject the plugin (it's a normal AbstractPlugin with setSessionManager() / setRedirect()) or move the three-branch logic into a small handler and keep the controller branch-free.

Laravel translation of the same pattern, if you're porting:

$request->validate(['attachment' => 'required|file|max:2048']);

if ($request->hasFile('attachment')) {
    $path = $request->file('attachment')->store('uploads');
    session()->put('pending_attachment', $path);
    return redirect()->route('uploads.confirm');
}

$path = session()->pull('pending_attachment');

Gotchas and Tips

  • enctype="multipart/form-data" on the <form>, or the plugin receives an empty file set and silently validates. Check this before debugging anything else.
  • Session configuration is mandatory. The plugin uses Zend\Session\Container; if Zend\Session isn't wired into your ServiceManager/session_manager config, you get a container instantiation error rather than a helpful message. ZF skeleton apps need Zend\Session enabled explicitly.
  • The data is single-consumption. The session entry is cleared when the plugin returns it on the following GET. Don't cache the returned array expecting it on the next request — copy what you need then.
  • $prg === false vs $prg instanceof Response vs array. Use strict comparisons. A loose if ($prg) on a falsy-but-present array is a classic source of "form renders as if nothing was submitted".
  • The redirect target defaults to the current URL. Pass an explicit route name when the form lives on a page that isn't re-routable (e.g. a POST-only endpoint), otherwise you redirect into a 405.
  • Validation errors are on you. The plugin returns false on an invalid POST; it does not repopulate $form with the submitted values. Call $form->setData($this->getRequest()->getPost()) in that branch or the user loses non-file fields.
  • 1.1.0 / 1.0.x compatibility: 1.1.0 adds PHP 7.1–7.2 support and removes HHVM. There are no deprecations or BC breaks, so ^1.1 is a drop-in for ^1.0. If any of your CI runs on HHVM, that job now fails to install — remove it rather than pinning 1.0.x.
  • This package is end-of-life. Zend Framework is archived; migrate to laminas/laminas-mvc-plugin-fileprg (namespace Laminas\Mvc\Plugin\FilePrg, same API, class-rename via the migration tooling). Budget for the rename rather than planning new features here.
  • Extension point: if you need a different persistence store, subclass FilePrg and override the session-container accessors — the class is small and the container namespace is the natural seam.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin