问题
I am trying to implement a image upload with other form elements with dropzone.js in laravel. So far I've managed to display the drag and drop image upload view with other form elements. And also get POST details from the submitted form. But when dropzone is passing the uploaded image to the database data save function it encode image with base64. I think I've managed to get the file extension also. And when I submit the button it gives me this error "Call to a member function move() on string" . Please put me in the right direction.
Here is the Form
<form class="form-horizontal" action="{{ route('save-slider-content') }}" method="POST" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="box-body">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="sliderTitle" id="sliderTitle" placeholder="Title of the post goes here">
</div>
</div>
<input type="hidden" name="date" id="date" value="<?php echo date("d-m-Y"); ?>">
<div class="form-group">
<label for="image" class="col-sm-2 control-label">Image</label>
<input hidden id="file" name="file"/>
<div class="col-sm-10">
<div class="dropzone needsclick dz-clickable" id="fileUpload">
<div class="dz-default dz-message">
<i class="fa fa-image fa-5x"></i>
<h3 class="sbold">Drop an image here to upload</h3>
<span>You can also click to open file browser</span>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Link</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="sliderLink" id="sliderLink" placeholder="Provide a link">
</div>
</div>
</div><br>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-info pull-right">Post</button>
</div>
<!-- /.box-footer -->
</form>
Here is the dropzone configuration
<script type="text/javascript">
Dropzone.options.fileUpload = {
url: "save-slider-content",
addRemoveLinks: true,
accept: function(file) {
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = function() {
let content = fileReader.result;
$('#file').val(content);
file.previewElement.classList.add("dz-success");
}
file.previewElement.classList.add("dz-complete");
}
}
</script>
Route
Route::post('store-slider-content', [ 'as' => 'save-slider-content', 'uses' => 'SliderContent@save_slider_data']);
save_slider_data function in Controller
public function save_slider_data(Request $request)
{
$slider = new Slider;
$slider->title = $request->sliderTitle;
$slider->title_sin = $request->sliderTitleSin;
$slider->date = $request->date;
$slider->link = $request->sliderLink;
$file = $request->file;;
$image_data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $file));
$f = finfo_open();
$mime_type = finfo_buffer($f, $image_data, FILEINFO_MIME_TYPE);
$imageName = time().'.'.$mime_type;
$image_data->move(public_path('slider_uploads'), $imageName);
return response()->json(['success'=>$imageName]);
$slider->img_url = $imageName;
$slider->save();
}
回答1:
Edited to include the logic for either Symfony\Component\HttpFoundation\File\File or Illuminate\Support\Facades\File (Illuminate\Filesystem\Filesystem)
move
is a method of a File
object, but $image_data
is just a string. So one thing you could do is write the decoded image to a temp file, instantiate a File
of it, and move it, like
//... your code ...
$image_data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $file));
// ... and then:
//grab a new tmp file
$tmpFilePath=sys_get_temp_dir().'/'.uniqid();
//write the image to it
file_put_contents($tmpFilePath, $image_data);
//move it.
//give it a name
$imageName = time().'.'.str_replace("image/","",$mime_type);
//if using Symfony\Component\HttpFoundation\File\File;
//get an instance of File from the temp file and call ->move on it
$tmpFile=new File($tmpFilePath);
$tmpFile->move(public_path('slider_uploads'), $imageName);
//or if using File facade
File::move($tmpFilePath, public_path("slider_uploads/$imageName"));
//...and then, back to your code...
$slider->img_url = $imageName;
$slider->save();
return response()->json(['success'=>$imageName]);
}
回答2:
You can do this:
In config/filesystems.php
, register a new disk slider_uploads
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'slider_uploads' => [
'driver' => 'local',
'root' => public_path('slider_uploads')
]
]
And then use your new disk in storing your image
$image_data = $request->file;
@list($type, $image_data ) = explode(';', $image_data );
@list(, $image_data ) = explode(',', $image_data );
if($image_data !=""){ // storing image in public/slider_uploads/ Folder
\Storage::disk('slider_uploads')->put($imageName, base64_decode($image_data ));
}
来源:https://stackoverflow.com/questions/48792585/decode-and-move-base64-encoded-image-in-laravel