1

It should be be a common use-case, but I can't find whether it's achievable at all.

I want to validate a multipart/form-data uploaded file extension on server-side - must I wait for the file to fully upload? I might be missing something, but it doesn't make sense, especially when handling large files.

Can't I execute PHP before file is uploaded, get metadata and maybe cancel the request altogether? I know I can split to two separate requests, I'm looking for a single-request solution, if applicable

user1768741
  • 155
  • 1
  • 6
  • Generally speaking, no. Your PHP script in most (actually all AFAIK) implementations gets invoked _after_ the server and/or PHP process has handled the data. Instead, if you really want to validate the extension you'll need to use [JS](https://stackoverflow.com/a/4237161/231316). However, the file input type also supports the [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-accept) so I'd encourage you to enforce it there if possibly – Chris Haas May 20 '21 at 18:41

3 Answers3

2

You should wait until the file is fully uploaded so you can then validate. There is no one single-request solution.

1

If you use an Apache/Nginx HTTP server, it executes PHP scripts only after it finished loading the whole request from the client - which is too late for your use case, as Sergio in the other answer correctly points out.


There is a single-request solution in PHP, but you need to have control over the HTTP requests in your PHP script.

You can chose to not use Apache, but instead start a HTTP server from your php-cli (either by using the native socket functions or some HTTP server package such as react/socket that uses them in the background).

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server('127.0.0.1:8080', $loop);
$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
    // here you can have $connection->on(...) event handlers
});
$loop->run();

Then you can have handlers that handle each chunk of the incoming request (example from the react/socket package, specifically ReadableResourceStream):

$connection->on('data', function ($chunk) {
    echo $chunk;
});

And instead of echoing the chunk, you can validate its contents and call $connection->close() if you need, which effectively terminates the unfinished upload.

But this whole thing is a complex solution, and I'd recommend to use it only for a upload service that is completely separated from the application that generates the form page (which can still run under a regular Apache HTTP server because it's just much easier).

Petr Hejda
  • 7,357
  • 6
  • 27
  • 43
0

You can validate it before interact with the server in the frontend, in PHP the script executes when request is finished

kirst
  • 1
  • 2