Upload multiple files in Laravel 4

2020-02-23 04:08发布

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

4条回答
兄弟一词,经得起流年.
2楼-- · 2020-02-23 04:14

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.

查看更多
Rolldiameter
3楼-- · 2020-02-23 04:16

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.

查看更多
时光不老,我们不散
4楼-- · 2020-02-23 04:21

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.

查看更多
Juvenile、少年°
5楼-- · 2020-02-23 04:31

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.

查看更多
登录 后发表回答