在Laravel中上传某些文件类型时出现问题

时间:2018-06-29 07:22:32

标签: php laravel file file-upload

在我的应用程序中,我有一个TemplateController,其中包含批量上传方法。它运作良好,但是只要我尝试上传.eps文件,Laravel就会返回验证错误。

  

files.0必须是以下类型的文件:jpg,jpeg,png,gif,ai,eps,mp3,   ogg,mpga,mp4,mpeg,doc,docx,dotx,pdf,odt,xls,xlsm,xlsx,ppt,   pptx,vsd。

我的问题是,我可以在验证程序期望的文件扩展名列表中看到eps

这里是TemplateController

<?php

namespace App\Http\Controllers\Editable;

use App\FileMetaData;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\Controller;

class TemplateController extends Controller
{
    /**
    * Instantiate a new controller instance.
    *
    * @return void
    */
    public function __construct()
    {
        $this->middleware(['role:Template Manager']);
    }

    /**
     * Set allowed extensions for each file category
     * This can be appended to as necessary as it's somewhat restrictive
     */
    private $image_ext = [
        'jpg', 'jpeg', 'png', 'gif', 
        'ai', 'eps'
    ];
    private $audio_ext = [
        'mp3', 'ogg', 'mpga'
    ];
    private $video_ext = [
        'mp4', 'mpeg'
    ];
    private $document_ext = [
        'doc', 'docx', 'dotx', 'pdf', 'odt',
        'xls', 'xlsm', 'xlsx',
        'ppt', 'pptx',
        'vsd'
    ];

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $files = FileMetaData::orderBy('category', 'DESC')->get();

        return view('editable.templates-and-tools.index', compact('files'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('editable.templates-and-tools.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // Get every extension that we allowed
        $all_ext = implode(',', $this->allExtensions());

        $this->validate($request, [
            'name'=>'required|unique:file_meta_data|min:3|max:40',
            'file' => 'required|file|mimes:' . $all_ext . '|max:50000'
        ]);

        // Grab data from the request to fill the necessary fields
        $name = $request->get('name');
        $department = $request->get('department');
        $category = $request->get('category');
        $uploadedFile = $request->file('file');

        // Get the extension and then use this to work out the file type
        $size = $uploadedFile->getSize();
        $extension = strtolower($file->getClientOriginalExtension());
        $type = $this->getType($extension);

        // Create a new instancce of this model
        $file = new FileMetaData();

        $file->name = $name;
        $file->department = $department;
        $file->category = $category;
        $file->size = $size;
        $file->type = $type;
        $file->extension = $extension;

        // Upload all the given files to Storage, within a specific directory
        if ($department != '') {
            $path = $uploadedFile->storeAs('library/' . $department, $name.'.'.$extension);
            $category = null;
        } elseif ($category != '') {
            $path = $uploadedFile->storeAs('library/' . $category, $name.'.'.$extension);
            $department = null;
        }

        // Grab the filepath so we can store it in the database
        $file->filepath = $path;

        // Finally, check that the file exists and save the model
        if (Storage::exists($path)) {
            $file->save();

            return redirect('editable/templates-and-tools')->with('success', $file->name . 'has been added');
        }
    }

    /**
     * Show the form to edit this resource
     */
    public function edit($id)
    {
        $file = FileMetaData::find($id);

        return view('editable.templates-and-tools.edit', compact('file'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        // Get every extension that we allowed
        $all_ext = implode(',', $this->allExtensions());

        $this->validate($request, [
            'name'=>'required|unique:file_meta_data|min:3|max:40',
        ]);

        $file = FileMetaData::find($id);

        // Get the current path to this file
        $currentPath = Storage::url($file->name . '.' . $file->extension);

        $extension = pathinfo($currentPath, PATHINFO_EXTENSION);

        // Grab data from the request to fill the necessary fields
        $name = $request->get('name');
        $department = $request->get('department');
        $category = $request->get('category');

        // Upload all the given files to Storage, within a specific directory
        if ($department != '') {
            $newPath = 'library/' . $department . '/' . $name.'.'.$extension;
            Storage::move($file->filepath, $newPath);
            $category = null;
        } elseif ($category != '') {
            $newPath = 'library/' . $category . '/' . $name.'.'.$extension;
            Storage::move($file->filepath, $newPath);
            $department = null;
        }

        // Grab the filepath so we can store it in the database
        $file->filepath = $newPath;

        $file->name = $name.'.'.$extension;
        $file->department = $department;
        $file->category = $category;

        $file->save();

        return redirect('editable/templates-and-tools')->with('success', $file->name . 'has been edited successfully');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $file = FileMetaData::find($id);

        if (Storage::delete($file->filepath)) {
            $file->delete();
        }

        return redirect('editable/templates-and-tools')->with('success', $file->name . ' has been deleted');
    }

    /**
     * Show page containing bulk upload form
     *
     * @return void
     */
    public function addBulk()
    {
        return view('editable.templates-and-tools.bulk');
    }

    /**
     * Process uploading of multiple files
     *
     * @param Request $request
     * @return void
     */
    public function bulkUpload(Request $request)
    {
        // Get every extension that we allowed
        $all_ext = implode(',', $this->allExtensions());

        $this->validate($request, [
            'files.*' => 'required|file|mimes:' . $all_ext . '|max:50000'
        ]);

        // Initialize a file upload counter
        $fileCount = 0;

        // Get the category and department from the form
        $department = $request->get('department');
        $category = $request->get('category');

        // Ensure that the request contains files
        if ($request->hasfile('files')) {
            // Loop through each file and add it to storage
            foreach ($request->file('files') as $file) {
                // Get the meta data for each file
                $name = $file->getClientOriginalName();
                $extension = strtolower($file->getClientOriginalExtension());
                $type = $this->getType($extension);
                $size = $file->getSize();

                // Upload all the given files to Storage, within a specific directory
                if ($department != '') {
                    $path = $file->storeAs('library/' . $department, $name);
                    $category = null;
                } elseif ($category != '') {
                    $path = $file->storeAs('library/' . $category, $name);
                    $department = null;
                }

                // Grab the filepath so we can store it in the database
                $file->filepath = $path;

                // Create the database entries for the newly uploaded files
                FileMetaData::firstOrCreate([
                    'name' => $name,
                    'department' => $department,
                    'category' => $category,
                    'type' => $type,
                    'extension' => $extension,
                    'size' => $size,
                    'filepath' => $path
                ]);

                $fileCount++;
            }

            return redirect('editable/templates-and-tools')->with('success', $fileCount . ' files have been added');
        }
    }

    /**
     * Get the file type based on the given extension
     * This could be used to categorise files by more generic types
     *
     * @param  string $ext Specific extension
     * @return string      Type
     */
    private function getType($ext)
    {
        if (in_array($ext, $this->image_ext)) {
            return 'image';
        }

        if (in_array($ext, $this->audio_ext)) {
            return 'audio';
        }

        if (in_array($ext, $this->video_ext)) {
            return 'video';
        }

        if (in_array($ext, $this->document_ext)) {
            return 'document';
        }
    }

    /**
     * Get all extensions by merging the individual arrays together
     * If any are added above remember to add them here
     *
     * @return array Extensions of all file types
     */
    private function allExtensions()
    {
        return array_merge($this->image_ext, $this->audio_ext, $this->video_ext, $this->document_ext);
    }
}

我还对单个eps文件执行了$extension变量的转储和处理,并且确实返回了eps。

为了进入此示例,我必须删除验证:

$this->validate($request, [
    'files.*' => 'required|file|mimes:' . $all_ext . '|max:50000'
]);

精简代码段

foreach ($request->file('files') as $file) {
    // Get the meta data for each file
    $name = $file->getClientOriginalName();
    $extension = strtolower($file->getClientOriginalExtension());
    $type = $this->getType($extension);
    $size = $file->getSize();

    dd($extension);
}

当我尝试上传相同的文件时,浏览器输出如下:

  

“ eps”

无论如何,脚本在获取扩展名时就死了,这显然是eps

eps文件有什么不同吗?还是我很密集?

在允许的扩展名列表中,我确实测试了所有其他扩展名,这些扩展名如下:

/**
 * Set allowed extensions for each file category
 * This can be appended to as necessary as it's somewhat restrictive
 */
private $image_ext = [
    'jpg', 'jpeg', 'png', 'gif', 
    'ai', 'eps'
];
private $audio_ext = [
    'mp3', 'ogg', 'mpga'
];
private $video_ext = [
    'mp4', 'mpeg'
];
private $document_ext = [
    'doc', 'docx', 'dotx', 'pdf', 'odt',
    'xls', 'xlsm', 'xlsx',
    'ppt', 'pptx',
    'vsd'
];

请澄清一下,files是一个已上传文件的数组,其HTML是:

<input type='file' name='files[]' multiple required />

有问题的文件

enter image description here

0 个答案:

没有答案