Laravel 5问题上传/保存pdf

时间:2018-07-15 05:51:54

标签: pdf laravel-5.6

我正在使用Laravel 5.6,jQuery 3.3.1,bootstrap 3.3.7和PHP 7.1.4

我需要允许用户上传文件和图片,基本上是jpg,gif,png和pdf。我正在使用公用磁盘并将文件存储在storage / app / public / folder_name中,其中folder_name在环境文件中定义

FILESYSTEM_DRIVER=public
PO_FILE_FOLDER=purchase_orders
INSURANCE_FILE_FOLDER=insurance
NOTE_FILE_FOLDER=notes
RENTAL_AGREEMENT_FILE_FOLDER=rental_agreements
SIGNATURES=signatures

然后在config / app中定义它们

'insurance_file_folder' => env('INSURANCE_FILE_FOLDER', ''),
'po_file_folder' => env('PO_FILE_FOLDER', ''),
'note_file_folder' => env('NOTE_FILE_FOLDER', ''),
'rental_agreement_file_folder' => env('RENTAL_AGREEMENT_FILE_FOLDER', ''),

'max_image_width' => env('MAX_IMAGE_WIDTH', 500),
'filesystem_driver' => env('FILESYSTEM_DRIVER', 'local'),

当我上载图像文件时,它们会上载到适当的文件夹,但是当我尝试上载pdf文件时,系统会创建一个新文件夹,命名为我正在命名的文件,而pdf则位于具有随机名称的新文件夹中。我正在使用完全相同的代码来上传图像和pdf文件,所以我不知道为什么它适用于一种而不适用于另一种。

这是我的控制器代码

public function store(PurchaseOrderRequest $poRequest, Customer $customer)
{
    $purchaseOrder = $customer->purchaseOrders()->create($poRequest->except('attachment'));

    if ($poRequest->hasFile('attachment')) {
        $purchaseOrder->saveFile(config('app.po_file_folder', ''), $poRequest->file('attachment'));
    }

    return redirect()->action('CustomerController@edit', $customer)->with('alert', 'Purchase Order created.');
}

我的模型PurchaseOrder saveFile代码

public function saveFile($folder_name, $file)
{
    // if file submited then check if file already exists, if so delete file and create new file
    $file_name = $this->createFileName();
    File::removeFiles($folder_name.'/'.$file_name, FALSE);
    $file_name = $file_name.'.'.$file->getClientOriginalExtension();
    $file = File::resize($file);
    $this->attachment_path = $folder_name.'/'.$file_name;
    Storage::disk(config('app.filesystem_driver', ''))->put($this->attachment_path, $file);

    $this->save();
}

public function createFileName()
{
    $file_name = 'po_'.$this->customer->code.'-'.$this->customer->id.'_'.$this->po_number.'-'.$this->id;
    return $file_name;
}

我的文件帮助程序代码

public static function resize($file)
{
   $resized_file = $file;

   if (strtolower($resized_file->getClientOriginalExtension()) != 'pdf') {
     // resize file if it is not pdf (file is photo)
     // get image size then resize largest size to size limit - dont upsize if image is smaller than max size
     list($width, $height) = getimagesize($resized_file);

     if ($width > $height) {
        $resized_file = Image::make($resized_file)->resize(config('app.max_image_width', ''), null, function ($constraint) {
             $constraint->aspectRatio();
             $constraint->upsize();
        })->encode($resized_file->getClientOriginalExtension(), 60);
     } else {
        $resized_file = Image::make($resized_file)->resize(null, config('app.max_image_width', ''),function ($constraint) {
             $constraint->aspectRatio();
             $constraint->upsize();
        })->encode($resized_file->getClientOriginalExtension(), 60);
     }
   }

   return $resized_file;
}

public static function removeFiles($file_name, $ext_included = FALSE)
{
   if ($ext_included == TRUE) {
     // remove specific file
     if (Storage::disk(config('app.filesystem_driver', ''))->exists($file_name)) {
         Storage::delete($file_name);
     }
   } else {
      // remove file with any extension
      $ext = array('.pdf', '.jpg', '.jpeg', '.gif', '.png');

      for ($cnt = 0; $cnt <= 4; ++$cnt) {
         if (Storage::disk(config('app.filesystem_driver', ''))->exists($file_name.$ext[$cnt])) {
            Storage::delete($file_name.$ext[$cnt]);
         }
      }
   }
}

我意识到使用env变量可能会使代码有些混乱,但是在我需要更改文件夹名称或将文件移至应用程序外部的情况下,我试图减轻这种麻烦。该应用程序将只有很少的用户(3或4),并且我预计不会上传太多文件,这就是为什么我将文件存储在应用程序结构中的原因。

这是我的第一个Laravel应用,我使用文档和许多其他教程将这段代码放在一起。花费了一段时间,但最终我将它用于图像。因此,如果您发现不符合标准或良好做法的内容,欢迎您提出任何建议。

感谢您抽出宝贵的时间阅读本文,感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

根据文件是图像还是pdf,我不得不使用两种不同的方法将文件保存在系统中。我先对图像进行一些处理(调整大小),然后再将它们放入Intervention Image的存储文件夹中。反过来,这会返回与原始上载文件不同的对象类型,因为某些添加文件(处理后)的命令将不起作用。

因此,如果我要存储pdf文件,我会使用:

$file->storeAs($folder_name, $file_name, config('app.filesystem_driver', ''));

如果我存储使用干预图像的图像,则使用:

Storage::disk(config('app.filesystem_driver', ''))->put($this->attachment_path, $file);

我找不到对两者都起作用的命令,因此我只在存储前检查扩展名。不知道这是否是“正确的方法”,但是它完成了工作。