使用laravel作业处理图像上载时无法解决的依赖性

问题描述 投票:0回答:1

每个上传的图像为不同的屏幕创建另外四个图像,然后传输到Digital Ocean上的空间。所以这非常耗时。因此,我想使用Laravels Job功能。这就是它现在的样子:

ImageController:

public function uploadMultiple($vehicle_id, Request $request)
{
    $this->setVehicle($vehicle_id);
    $this->validate($request, [
        'images'    => 'required',
        'images.*'  => 'image'
    ]);
    foreach ($request->images as $image){
        $this->uploadSingleImage($image);
    }
    \Alert::success('Bilder wurden hochgeladen')->flash();

    return redirect()->back();
}

protected function uploadSingleImage(UploadedFile $image)
{
    VehicleImageUploaderJob::dispatch($this->getVehicle());
}

车辆图像上传工作:

public function handle(UploadedFile $image)
{
    $disk = FilesystemHelper::getDisk('producerData');
    $originalName = basename($image->getClientOriginalName(), '.'.$image->getClientOriginalExtension());
    $extension = $image->getClientOriginalExtension();

    $dbImage = new Image();

    // Store image in original size
    $path = $image->storeAs(
        'producers/' . $this->getVehicle()->producer->id . '/vehicles/' . $this->getVehicle()->id, // Folder or Directory
        $image->getClientOriginalName(), // File Name
        $disk // Disk
    );
    Storage::disk($disk)->setVisibility($path, 'public');

    $dbImage->original = $path;
    $dbImage->disk = $disk;

    $file = ImageManipulator::make($image);

    foreach(config('images.vehicles.formats') as $format => $values){
        $file->backup();
        $fileName = $originalName . '-' . str_random(6) . '-' . $values['width'] . 'x' . $values['height'] . '.' . $extension;
        if($format === 'thumbnail'){
            $file->fit($values['width'],$values['height'])
                ->save();
        } else {
            $file->fit($values['width'], $values['height'], function ($constraint) {
                $constraint->aspectRatio();
                $constraint->upsize();
            })->save();
        }
        $path = $image->storeAs(
            'producers/' . $this->getVehicle()->producer->id . '/vehicles/' . $this->getVehicle()->id, // Folder or Directory
            $fileName, // File Name
            $disk // Disk
        );

        Storage::disk($disk)->setVisibility($path, 'public');
        $dbImage->{$format} = $path;
        $file->reset();
    }

    $dbImage->save();
    $this->getVehicle()->images()->attach($dbImage->id);
    $this->getVehicle()->save();
}

不幸的是,每次我想上传图像时都会出错(目前队列驱动程序是“同步”):Symfony \ Component \ HttpFoundation \ File \ UploadedFile类中无法解析的依赖项解析[参数#0 [string $ path]]

也许是因为我应该传递图像而不是车辆。车辆在构造函数中是预期的,而处理方法中的图像是预期的。但是当我传入图像时,它会抛出一个错误,说它需要一个Vehicle实例。

laravel laravel-5 queue jobs
1个回答
1
投票

问题是UploadedFile(你从upload-request获得的)是不可序列化的,因此不能由作业处理。所以我不得不创建一个新的模型+表来临时存储图像。

图像的方式如下:

  • 作为文件存储在本地
  • 创建临时模型的新实例
  • 将这个模型传递给工作
  • 重新创建UploadedFile类型的图像并处理图像(创建四个分辨率并将其加载到数字海洋上)
  • 删除本地文件
  • 删除临时模型

新模式:

use App\DBEntities\MasterEntity;

class VehicleImageForJob extends MasterEntity
{
    protected $guarded = ['id'];
}

新表:

class CreateVehicleImageForJobsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('vehicle_image_for_jobs', function (Blueprint $table) {
            $table->increments('id');
            $table->string('file');
            $table->string('mime_type');
            $table->string('original_name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('vehicle_image_for_jobs');
    }
}

filesystem.php中的新磁盘:

'vehicle_image_temp' => [
    'driver' => 'local',
    'root' => storage_path('app/vehicle_images/temp')
]

改装控制器:

protected function uploadSingleImage(UploadedFile $image)
{
    $disk = 'vehicle_image_temp';

    $path = $image->store("/", [
        'disk' => $disk
    ]);

    $vehicleImageForJob = VehicleImageForJob::create([
        'file' => $path,
        'mime_type' => $image->getMimeType(),
        'original_name' => $image->getClientOriginalName()
    ]);

    VehicleImageUploaderJob::dispatch($vehicleImageForJob, $this->getVehicle());
}

修改工作:

class VehicleImageUploaderJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $vehicle;
    protected $image;

    protected $disk = 'vehicle_image_temp';

    /**
     * VehicleImageUploaderJob constructor.
     * @param VehicleImageForJob $image
     * @param Vehicle $vehicle
     */
    public function __construct(VehicleImageForJob $image, Vehicle $vehicle)
    {
        $this->vehicle = $vehicle;
        $this->image = $image;
    }

    /**
     * @param UploadedFile $image
     * @throws \Exception
     */
    public function handle()
    {
        $image = new UploadedFile(storage_path("app/vehicle_images/temp/{$this->image->file}"),
            $this->image->original_name,
            $this->image->mime_type,
            null,
            null,
            true
        );

        $disk = FilesystemHelper::getDisk('producerData');
        $originalName = basename($image->getClientOriginalName(), '.'.$image->getClientOriginalExtension());
        $extension = $image->getClientOriginalExtension();

        $dbImage = new Image();

        // Store image in original size
        $path = $image->storeAs(
            'producers/' . $this->getVehicle()->producer->id . '/vehicles/' . $this->getVehicle()->id, // Folder or Directory
            $image->getClientOriginalName(), // File Name
            $disk // Disk
        );
        Storage::disk($disk)->setVisibility($path, 'public');

        $dbImage->original = $path;
        $dbImage->disk = $disk;

        $file = ImageManipulator::make($image);

        foreach(config('images.vehicles.formats') as $format => $values){
            $file->backup();
            $fileName = $originalName . '-' . str_random(6) . '-' . $values['width'] . 'x' . $values['height'] . '.' . $extension;
            if($format === 'thumbnail'){
                $file->fit($values['width'],$values['height'])
                    ->save();
            } else {
                $file->fit($values['width'], $values['height'], function ($constraint) {
                    $constraint->aspectRatio();
                    $constraint->upsize();
                })->save();
            }
            $path = $image->storeAs(
                'producers/' . $this->getVehicle()->producer->id . '/vehicles/' . $this->getVehicle()->id, // Folder or Directory
                $fileName, // File Name
                $disk // Disk
            );

            Storage::disk($disk)->setVisibility($path, 'public');
            $dbImage->{$format} = $path;
            $file->reset();
        }

        $dbImage->save();
        $this->getVehicle()->images()->attach($dbImage->id);
        $this->getVehicle()->save();

        Storage::disk($this->disk)->delete($this->image->file);
        $this->image->delete();
    }

    protected function getVehicle(): Vehicle
    {
        if($this->vehicle instanceof Vehicle){
            return $this->vehicle;
        } else {
            throw new \Exception("Vehicle not set on ImageUploaderJob");
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.