在 Laravel 4 中上传多个文件

Posted

技术标签:

【中文标题】在 Laravel 4 中上传多个文件【英文标题】:Upload multiple files in Laravel 4 【发布时间】:2013-08-14 19:33:11 【问题描述】:

这是我用于上传多个文件的控制器代码,我正在从 Google Chrome 上的“邮递员”rest API 客户端传递密钥和值。我正在从邮递员添加多个文件,但只有一个文件正在上传。

public function post_files() 
    $allowedExts = array("gif", "jpeg", "jpg", "png","txt","pdf","doc","rtf","docx","xls","xlsx");
    foreach($_FILES['file'] as $key => $abc) 
        $temp = explode(".", $_FILES["file"]["name"]);
        $extension = end($temp);
        $filename= $temp[0];
        $destinationPath = 'upload/'.$filename.'.'.$extension;

        if(in_array($extension, $allowedExts)&&($_FILES["file"]["size"] < 20000000)) 
            if($_FILES["file"]["error"] > 0) 
                echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
            
            if (file_exists($destinationPath)) 
                echo $filename." already exists. ";
             else 
                $uploadSuccess=move_uploaded_file($_FILES["file"]["tmp_name"],$destinationPath);
                if( $uploadSuccess ) 
                    $document_details=Response::json(Author::insert_document_details_Call($filename,$destinationPath));
                    return $document_details; // or do a redirect with some message that file was uploaded
                // return Redirect::to('authors')
                 else 
                    return Response::json('error', 400);
                
            
        
      

我也尝试过这段代码,但它返回了临时文件夹中文件的位置

$file = Input::file('file');
            echo count($file);

echo count($_FILES['file']); 总是返回我 5.谁能告诉我为什么?

以及为什么foreach(Input::file('file') as $key =&gt; $abc) 给出错误无效参数

【问题讨论】:

【参考方案1】:

1.表格:- 表单开始标签必须有'files'=>true,文件字段必须有名称[](带数组)和'multiple'=>true

<?php 
 Form::open(array('url'=>'apply/multiple_upload','method'=>'POST', 'files'=>true)) 
 Form::file('images[]', array('multiple'=>true)) 
?>

2。将以下代码添加到您的控制器功能:-

<?php
// getting all of the post data
$files = Input::file('images');
foreach($files as $file) 
  // validating each file.
  $rules = array('file' => 'required'); //'required|mimes:png,gif,jpeg,txt,pdf,doc'
  $validator = Validator::make(array('file'=> $file), $rules);
  if($validator->passes())
    // path is root/uploads
    $destinationPath = 'uploads';
    $filename = $file->getClientOriginalName();
    $upload_success = $file->move($destinationPath, $filename);
    // flash message to show success.
    Session::flash('success', 'Upload successfully'); 
    return Redirect::to('upload');
   
  else 
    // redirect back with errors.
    return Redirect::to('upload')->withInput()->withErrors($validator);
  

?>

来源:http://tutsnare.com/upload-multiple-files-in-laravel/

编辑:参考源链接无效

【讨论】:

注意:php 代码只是验证第一个文件并立即重定向。如果没有文件,则返回 void 并且不显示任何效果。不过链接似乎不错。 源 URL 现在重定向到某个托管域,仅供参考。 @damd 抱歉,参考 URL 无效。您可以询问代码是否有任何问题。【参考方案2】:

上述解决方案不适用于多个文件,因为一旦第一个项目得到验证,返回就会触发,所以这是经过几个小时的头墙撞击后的解决方案。灵感来自https://www.youtube.com/watch?v=PNtuds0l8bA

// route
Route::get('/', function() 
    return View::make('main');
);
Route::post('up', 'FUplaodController@store');

// controller
class FUplaodController extends \BaseController 
    public function store()
    
        if (Input::hasFile('images'))
        
            $files = Input::file('images');
            $rules = [
                'file' => 'required|image'
            ];
            $destinationPath = public_path().'/uploads';

            foreach ($files as $one)
            
                $v = Validator::make(['file' => $one], $rules);
                if ($v->passes())
                
                    $filename       = $one->getClientOriginalName();
                    $upload_success = $one->move($destinationPath, $filename);
                    if ($upload_success)
                    
                        $done[] = $filename;
                        Session::flash('done', $done);
                    
                
                else
                
                    $filename = $one->getClientOriginalName();
                    $not[] = $filename;
                    Session::flash('not', $not);
                
            
            return Redirect::back()->withErrors($v);
        
        return Redirect::back()->withErrors('choose a file');
    


// view
<!-- uploaded -->
@if (Session::has('done'))
    @foreach (Session::get('done') as $yes)
        <li> $yes </li>
    @endforeach
    <p style="color: #2ecc71">Uploaded</p>
    <br>
@endif

<!-- not uploaded -->
@if (Session::has('not'))
    @foreach (Session::get('not') as $no)
        <li> $no </li>
    @endforeach
    <p style="color: #c0392b">wasnt uploaded</p>
    <br>
@endif

<!-- errors -->
<p style="color: #c0392b"> $errors->first() </p>
<hr>

<!-- form -->
 Form::open(['url' => 'up', 'files'=>true]) 
     Form::file('images[]', ['multiple'=>true]) 
     Form::submit('Upload') 
 Form::close() 

你基本上将文件名保存在一个数组中并将这些数组传递给一个会话,然后只在循环完成时添加return

【讨论】:

太棒了,描述得很好。非常感谢。【参考方案3】:

不使用任何 API,但这可能概述了原理。

我设置了这个 routes.php 文件,它将帮助您进行上传测试。

routes.php

// save files
Route::post('upload', function()
    $files = Input::file('files');

    foreach($files as $file) 
                // public/uploads
        $file->move('uploads/');
    
);

// Show form
Route::get('/', function()

    echo Form::open(array('url' => 'upload', 'files'=>true));
    echo Form::file('files[]', array('multiple'=>true));
    echo Form::submit();
    echo Form::close();
);

注意输入名称,files[]:如果上传多个同名文件,也要加上括号。

【讨论】:

【参考方案4】:

解决方案:

您只需执行以下操作即可获取所有文件:

$allFiles = Input::file();

解释:

Input 类实际上是 Illuminate\Http\Request 类的 Facade(是的,就像 Request 门面一样 - 它们都充当同一个类的“Face”!**)。

这意味着您可以使用 Request 中可用的任何方法。

如果我们搜索函数file(),我们会看到它是这样工作的:

public function file($key = null, $default = null)

    return $this->retrieveItem('files', $key, $default);

现在,retrieveItem() 是一个受保护的方法,所以我们不能直接从控制器中调用它。然而,深入观察,我们看到we can pass the file() method "null" 是关键。如果我们这样做,那么我们将获得所有物品!

protected function retrieveItem($source, $key, $default)

    if (is_null($key))
    
        return $this->$source->all();
    
    else
    
        return $this->$source->get($key, $default, true);
    

所以,如果我们调用Input::file(),Request 类将在内部运行$this-&gt;retrieveItem('files', null, null),而$this-&gt;retrieveItem('files', null, null) 又会运行return $this-&gt;files-&gt;all();,我们将上传所有文件。

** 注意Input Facade 有额外的方法get() 可用。

【讨论】:

以上是关于在 Laravel 4 中上传多个文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中上传多个文件

laraver框架学习------工厂模型填充测试数据

如何使用laravel在数据库中上传多个文件

在 Laravel 5 (Lumen) 中使用基本路径

在 Laravel 5.8.38 中上传多个文件时数组到字符串的转换错误

Laravel 4.2输入文件空