I have a php server with Symfony (and API Platform) and I've just created a file upload system with Vich Uploader bundle. I have an Assert attribute on my File property that restricts its maximum size to 5MB.
The problem is that if I enter a file larger than 5MB but also larger than the post_max_size value in php.ini, the server can't process the request and returns a 500 error.
[Web Server ] PHP Warning: POST Content-Length of 27052288 bytes exceeds the limit of 8388608 bytes in Unknown on line 0 [Web Server ] :00","message":"/api/documents"} [Web Server ] Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 81153520 bytes) in C:[...]vendor\symfony\http-kernel\Profiler\FileProfilerStorage.php on line 150 [Web Server ] PHP Stack trace: [many lines of the stack trace]
I looked for a solution but the only one I found was to increase the value of post_max_size. But I think it's a workaround to do that, since all you have to do is enter a file heavier than this limit to bug the server.
So does anyone have a real solution (that doesn't involve increasing values in php.ini) that return a php error (422?) without having memory problems and so on?
For now, I've created an EventListener to return an 422 error :
namespace App\EventListener;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
class MaxPostSizeListener
{
public function onKernelRequest(RequestEvent $event): void
{
if (!isset($_SERVER['CONTENT_LENGTH'])) {
return;
}
$contentLength = (int) $_SERVER['CONTENT_LENGTH'];
if ($contentLength > $this->getPostMaxSize()) {
$errorMessage = 'La taille du fichier est trop grande.';
$response = new Response(json_encode(['message' => $errorMessage]), Response::HTTP_UNPROCESSABLE_ENTITY);
$response->headers->set('Content-Type', 'application/json');
$event->setResponse($response);
}
}
private function getPostMaxSize(): int
{
$maxSize = ini_get('post_max_size');
if (!preg_match('/^(\d+)(.)$/', $maxSize, $matches)) {
return 0;
}
$value = (int) $matches[1];
switch (strtoupper($matches[2])) {
case 'G':
$value *= 1024;
// no break
case 'M':
$value *= 1024;
// no break
case 'K':
$value *= 1024;
}
return $value;
}
}
But I still have the memory problem and the multiple lines in the terminal.