Upload multiple files in Laravel 4

萝らか妹 提交于 2019-12-18 11:44:06

问题


Here is my controller code for uploading multiple files and I am passing key and value from 'postman' rest API client on Google Chrome. I am adding multiple files from postman but only 1 file is getting upload.

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);
                }
            }
        }
    }  
}

I have tried this code also but it returns me location of a file in temporary folder

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

and echo count($_FILES['file']); returns me always 5.Can anyone tell me why?

and why foreach(Input::file('file') as $key => $abc) gives the error invalid arguments


回答1:


Not using any API, but this might outline the principle.

I set up this routes.php file, whick will help you with upload test.

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();
});

Notice the input name, files[]: If uploading multiple files under the same name, include brackets as well.




回答2:


Solution:

You can get all files by simply doing:

$allFiles = Input::file();

Explanation:

The class Input is actually a Facade for the Illuminate\Http\Request class (Yes, just like the Request facade - they both serve as the "Face" for the same class!**).

That means you can use any methods available in Request .

If we search for the function file(), we see it works like this:

public function file($key = null, $default = null)
{
    return $this->retrieveItem('files', $key, $default);
}

Now, retrieveItem() is a protected method, so we can't just call it from our Controller directly. Looking deeper, however, we see that we can pass the file() method "null" for the key. If we do so, then we'll get all the items!

protected function retrieveItem($source, $key, $default)
{
    if (is_null($key))
    {
        return $this->$source->all();
    }
    else
    {
        return $this->$source->get($key, $default, true);
    }
}

So, if we call Input::file(), the Request class will internally run $this->retrieveItem('files', null, null) which will in turn run return $this->files->all(); and we will get all the files uploaded.

** Note that Input Facade has the extra method get() available in it.




回答3:


the above solutions wont work with multiple files as the return will fire as soon the first item gets validated ,so here is a solution after several hours of head-wall banging. inspired by 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() }}

u basicly save the filenames in an array and pass those arrays to a session then only add return when the loop has finished.




回答4:


1. Form :- Form opening tag must have ‘files’=>true and file field must have name [](with array) and ‘multiple’=>true

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

2. Add below code to your controller function :-

<?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);
  }
}
?>

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

EDIT: Reference source link is not working.



来源:https://stackoverflow.com/questions/18204781/upload-multiple-files-in-laravel-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!