Skip to main content

Laravel S3 uploads failing when uploading large files in Laravel 5.8

Working on a project for a customer using Laravel 5.8, I found that when uploading files to S3 using Laravel’s Fly System, that the uploads were failing after a certain size.
The error back was a validation error mentioning the file was unable to be uploaded.

To troubleshoot this, there were a few things I did:

  1. Ensured my PHP.INI settings were allowing uploads high enough. I found that PHP.INI only allows 2M by default, so I increased this limit to 20M. I also increased the max post time to 300.
  2. I found out that Amazon S3 doesn’t like files over 5 MB uploading in one go, instead you need to stream it through

Streaming the files

My solution was to have the file upload to the server first, and once it is uploaded, it is streamed from the server to S3.



// Add namespaces
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File;


// Function to receive uploaded file
public function uploadAttachment(Request $request)
{
                        // Grab the file uploaded
			$file = $request->file('file');


                        // Get the mime type if you want to save it to databse
			$extension = $file->getClientMimeType();
			
                        // Validate the request to ensure it meets your restrictions
			$request->validate([
				'file' => 'required|mimes:pdf,jpeg,jpg,png,gif',
			]);

		
			// Save locally first to folder called 'uploads', in app/storage/uploads
			$save_local = Storage::put('file-uploads', $file);

			
			// Get base location of stored file
			$storage_path  = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
			$local_url = $storage_path . $save_local;


			// Save to S3 (Grab the file object and stream it to S3 to a folder called 'file-uploads'. File is set to a public file that can be accessed by URL.
			$savetoS3 = Storage::disk('s3')->putFile('file-uploads', new File($local_url), 'public');


			// Delete local copy so it does not take space on your server
			Storage::delete($save_local);
	

			// Return file path if using javscript for the file upload. This will return an array with the extension as well as the link to the PUBLIC s3 file url.
			return response()->json([

					'file_type' => $extension,
					'link' => Storage::disk('s3')->url($savetoS3)
			]);

	
}

Leave a Reply