Warm tip: This article is reproduced from serverfault.com, please click

How to queue upload to s3 using Laravel?

发布于 2020-11-30 15:46:59

I'm dispatching a job to queue my video file, the files are being stored on s3. Everything is working except if I upload a video file for example that's 20mb, when I look in my bucket it says the file is 120b. So this makes me think that I'm uploading the path and filename as a string instead of the file object. And for some reason, when I try getting the file using the Storage::get() or File::get() and dd the result, it shows a bunch or random and crazy characters. It seems like I can only get these weird characters, or a string, I can't get the file object for some reason.

In my controller I'm also storing it in the public disk (I will delete the file later in my Jobs/UploadVideos.php file).

CandidateProfileController.php:

$candidateProfile = new CandidateProfile();
$candidateProfile->disk = config('site.upload_disk');

// Video One
if($file = $request->file('video_one')) {
    $file_path = $file->getPathname();
    $name = time() . $file->getClientOriginalName();
    $name = preg_replace('/\s+/', '-', $name);

    $file->storePubliclyAs('videos', $name, 'public');
    $candidateProfile->video_one = $name;
}

if($candidateProfile->save()) {

    // dispatch a job to handle the image manipulation
    $this->dispatch(new UploadVideos($candidateProfile));

    return response()->json($candidateProfile, 200);

} else {
    return response()->json([
        'message' => 'Some error occurred, please try again.',
        'status' => 500
    ], 500);
}

Jobs/UploadVideos.php:

use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $candidateprofile;
    public $timeout = 120;
    public $tries = 5;

    /**
     * Create a new job instance.
     *
     * @param CandidateProfile $candidateProfile
     */
    public function __construct(CandidateProfile $candidateProfile)
    {
        $this->candidateprofile = $candidateProfile;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $disk = $this->candidateprofile->disk;
        $filename = $this->candidateprofile->video_one;
        $original_file = storage_path() . '/videos/' . $filename;

        try {
            // Video One
            Storage::disk($disk)
                ->put('videos/'.$filename, $original_file, 'public');

            // Update the database record with successful flag
            $this->candidateprofile->update([
                'upload_successful' => true
            ]);

        } catch(\Exception $e){
            Log::error($e->getMessage());
        }
    }
Questioner
Ryan Sacks
Viewed
0
Rwd 2020-12-01 00:20:01

File Storage docs

The 2nd parameter for put() should be the contents of the file not the path to the file. Also, unless you've updated the public disk in your config/filesystem.php, the video isn't going to be stored in storage_path() . '/videos/...'.

To get this to work you should just need to update your Job code:

$filename = 'videos/' . $this->candidateprofile->video_one;

Storage::disk($this->candidateprofile->disk)
    ->put($filename, Storage::disk('public')->get($filename), 'public');

$this->candidateprofile->update([
    'upload_successful' => true,
]);

Also, wrapping your code in a try/catch will mean that the Job won't retry as it will technically never fail.