I'm trying upload image:
View (part):
<input type="file" name="image" />
Countoller:
public function store(Request $request){
dump($request->all());
$this->validate($request,[
'title'=>'required|max:255',
// 'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'text'=>'required',
]);
$imageName = time().'.'.$request->image->getClientOriginalExtension();
$request->image->move(public_path('images'), $imageName);
dump($request);
$data=$request->all();
dump($data);
$aticle=new Article;
$aticle->fill($data);
}
Dump request:
"title" => "fgdfd"
"alias" => "dg"
"desc" => "fdgfgd"
"text" => "gd"
"image" => "IMG_0002.JPG"
"tag" => "hg"
How do I put an image in MySql database?
As the docs describe, you should be using the file() method on the $request to access the uploaded file, not the name of your file field.
In your case, that means:
// Use the file() method to access the uploaded file
$imageName = time() . '.' . $request->file('image')->getClientOriginalExtension();
// storeAs() allows you to move a file while specifying a new filename.
// $path will be the fully qualified path to the file, including filename.
$path = $request->file('image')->storeAs(public_path('images'), $imageName);
It isn't clear from your question whether you want to save the file path in the database, or the actual binary file contents, as a BLOB. Here's how to do both:
// Create new article
$aticle=new Article;
$aticle->fill($data);
// Either save the path to the uploaded image in the DB
$aticle->featured_image = $path;
$aticle->save();
// OR
// Save the file binary contents in the DB
$aticle->featured_image = file_get_contents($path);
$aticle->save();
Ideally, you'll save the file to a location and then store the path to that file in the database.
What version of Laravel are you on ? If you're on 5.3 or higher you can:
$path = $request->image->store('path/to/save/the/file');
this will save the file with a random name, then just store that path to the database.
or you can:
$path = $request->image->storeAs('path/to/save/the/file', 'filename.jpg');
if you want to specify the saved file name.
This work's for me:
Step 1
Use Intervention Image package for manipulating images. You'll install it via composer. Run the command:
composer require intervention/image
Step 2
After installing Intervention Image, you need to add service providers and facade. Open our config/app.php file and add following lines. In the $providers array add the service providers for this package.
Intervention\Image\ImageServiceProvider::class
Step 3
Add the facade of this package to the $aliases array.
'Image' => Intervention\Image\Facades\Image::class
Step 4
And finally publish the configuration using following command:
$ php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5"
Step 5 Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\yourmodel;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Input;
use Response;
use Image;
class YourController extends Controller
{
public function create()
{
return view('yourview.create');
}
public function store(Request $request)
{
$file = Input::file('pic');
$img = Image::make($file);
Response::make($img->encode('jpeg'));
$var = new YourModel;
$var->pic = $img;
$var->save();
return redirect()->route('yourview.index')
->with('success','Success.');
}
Step 6 View
<form action="{{ route('yourview.store') }}" method="POST" enctype="multipart/form-data">
#csrf
<div class="row">
<div class="col-xs-4 col-sm-4 col-md-4">
<div class="form-group">
<strong>Image:</strong>
<input type="file" id="pic" name="pic" class="form-control"></input>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary">Send</button>
</div>
</div>
</form>
Related
I am creating a controller that saves photos to the /storage/ folder. To protect myself from submitting a bunch of large photos and not to style their CSS, I wanted to resize them using the Intervention / image library. Unfortunately, despite following the installation instructions directly from the documentation, several uninstallations and reinstallations of the library do not work. When I use this code snippet:
Use Image;
I get an error saying:
Undefined type 'Image'
Following the instructions, I added the following to /config/app.php:
'providers' => [
...
Intervention\Image\ImageServiceProvider::class,
],
'aliases' => [
...
'Image' => Intervention\Image\Facades\Image::class,
...
],
Besides, I cleaned and reconfigured the cache and config, restarted the server, tried to use:
use Intervention\Image\ImageManagerStatic as Image;
But unfortunately that didn't help either.
What am I doing wrong?
You have to use the namespace below
use Intervention\Image\Facades\Image;
Then you can use like-
$image = $request->file('image');
$ext = $image->getClientOriginalExtension();
$img = Image::make($image)->resize(300, 200)->save('storage/folder/filename'.'.'.$ext);
Use Image facade directly
\Intervention\Image\Facades\Image::make(\File::get($file_address))
->fit($width, $height)
->save($path_for_saving);
You can fit or crop the image based on your needs.
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
public function imageUploadPost(Request $request)
{
$photo = $request->file('image');
$imagename = time() . '.' . $photo->getClientOriginalExtension();
// Upload Crop Image...
$destinationPath = public_path('uploads/thumbnail_images');
if (!File::isDirectory($destinationPath)) {
File::makeDirectory($destinationPath, 0777, true, true);
}
$thumb_img = \Intervention\Image\Facades\Image::make($photo->getRealPath())->resize(100, 100);
$thumb_img->save($destinationPath . '/' . $imagename, 100); // Define Quality 100 (Optional)
echo '<pre>';
print_r("Upload Successfully. Store File : laravel_project/public/uploads & laravel_project/public/uploads/thumbnail_images");
}
I am processing files by extension and storing images, files, and pdf's inside of respective folders located in the public storage.
Php artisan link:storage has already been run. Files are being properly sorted and stored in the correct locations.
The portion of documentation that says to create the URL link using "echo asset()" is a bit unclear to me and I believe that's where the issue lies. Where am I supposed to echo the asset? I was unable to do so in the vue component.
However, on the front end (Vue Component using Axios to pass data) it seems that the :src is only getting the file path stored in the Database and not grabbing the actual file from the storage location.
Here is the portion of the component where the image should display:
<div v-for="image in post.images" :key="image.id">
<img width="220" height="250" :src=" './storage' + image.post_image_path " />
</div>
Here is my Controller function that stores the images:
public function store(Request $request)
{
// get the data from vue component
$title = $request->title;
$description = $request->description;
$author_id = Auth::user()->id;
$images = $request->images;
// creating the new post with the data above
$post = Post::create( [
'title' => $title,
'description' => $description,
'author_id' => $author_id
]);
// we are receiving an array in the image, we need to do a foreach to grab the files that the image has
foreach($images as $image) {
$name = $image->getClientOriginalName();
$ext = $image->getclientoriginalextension();
// creating the extension so we can filter the query above
$ext_images = array('jpg', 'png');
$ext_files = array('pdf', 'doc', 'docx','txt');
$ext_videos = array('mp4', 'mov', 'avi');
// we are proccesing the images files
if (in_array($ext, $ext_images)) {
$imagePath = Storage::disk('local')->put('/post_images' , $image);
Image::create( [
'post_id' => $post->id,
'post_image_path' => '/local/' . $imagePath,
]);
}
// we are proccessing standard files and saving if
elseif (in_array($ext, $ext_files)) {
$imagePath = Storage::disk('local')->put( '/post_files' , $image);
Image::create( [
'post_id' => $post->id,
'post_image_path' => '/local/' . $imagePath,
]);
}
// we are processing the media files (video) and saving if
elseif (in_array($ext, $ext_videos)) {
$imagePath = Storage::disk('local')->put('/post_videos' , $image);
Image::create( [
'post_id' => $post->id,
'post_image_path' => '/local/' . $imagePath,
]);
};
}
return $post;
With the current controller set up files are organized into their respective folders and storing in the "storage/app/specified folder name". This is working correctly, the only issue retrieving the records after they have been created.
PARTIALLY RESOLVED:
By changing the storage location to:
$image->move(public_path('post_images'), $name);
instead of
$imagePath = Storage::disk('local')->put('/post_images' , $image);
While I have a viable work around, understanding why the storage wasn't working would be greatly appreciated.
The asset helper method is going to return to full proper path of the image folder.
Since you are not calling the method (Or you can't since you are working in a vue component), you have to set the base of your path yourself and concat the image name.
By default Laravel's public directory is the entry point, so this should work, if the image is placed properly:
<img width="220" height="250" :src=" '/storage' + image.post_image_path" />
Saving the image like:
$image->move(public_path('post_images'), $name);
resolved the issue.
I'm using The Public Disk which is local driver. I create a symbolic link from public/storage to storage/app/public using this given command php artisan storage:link. I didn't change anything as mentioned in laravel filesystem documentation. But i'm not able to view the image with asset helper. File_path is storing in database but still images are broken.
Controller:
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$slide = new Slider();
$slide->title = $request->title;
$slide->description = $request->description;
//uploading image
if ($request->hasFile('file')) {
$file = $request->file('file');
$slide->file_name = str_random(40) . $file->getClientOriginalName();
$slide->file_size = $file->getClientSize();
$slide->file_mime = $file->getClientMimeType();
$slide->file_path = $file->storeAs('public', $slide->file_name);
}
$slide->status = $request->status;
$slide->save();
return redirect()->route('slider.index')->with('success', 'Done');
}
I'm using storeAs method, which receives the path, the file name.
Database:
View:
<td><img src="{{ asset($slide->file_path) }}" class="content" width="25"></td>
StoreAs method returns the path which is public/filename.jpg and images store into public/storage folder. How do i view the images?
The public and S3 storages support the url method that you can use to get the correct URL for the image
<td><img src="{{ Storage::url($slide->file_path) }}" class="content" width="25"></td>
You should add storage prefix to your asset:
<td><img src="{{ asset('storage/' . $slide->file_path) }}" class="content" width="25"></td>
I have a route in my API right in Laravel for an iOS app that lets you upload images that I got form this tutorial https://www.codetutorial.io/laravel-5-file-upload-storage-download/
and when I tried to upload the file it turns null.
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Fileentry;
use Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use Illuminate\Http\Response;
class FileEntryController extends Controller
{
public function add() {
$file = Request::file('filefield');
$extension = $file->getClientOriginalExtension();
Storage::disk('local')->put($file->getFilename().'.'.$extension, File::get($file));
$entry = new Fileentry();
$entry->mime = $file->getClientMimeType();
$entry->original_filename = $file->getClientOriginalName();
$entry->filename = $file->getFilename().'.'.$extension;
$entry->save();
return redirect('fileentry');
}
}
Route:
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
$api->post('fileentry/add',array(
'as' => 'addentry',
'uses' => 'App\Http\Controllers\FileEntryController#add'
));
}
the user doesn't interact with the web page is all through the app
Other information that maybe the cause of the problem is that i'm using Postman to upload the image to the laravel app (Method: POST, through the binary section).
Try using form-data method from postman and add a parameter as file type.
Keep in mind that the key of the parameter must be equal to the key you're trying to get in backend. In your case it is filefield
$file = Request::file('filefield');
In your html form add this attribute
enctype="multipart/form-data"
I have a Laravel 5.5 app where users with administrator privileges can upload files. After they upload the files I'd like them to be able to view the file in the administrator dashboard.
I have a DocumentController.php that handles the file upload to the local disk:
public function store(Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
// validate that the document is a pdf and
// that required fields are filled out
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'user_id' => 'required|exists:users,id',
'document_path' => 'required|mimes:pdf'
]);
$file = $request->file('document_path');
$path = $file->store('documents/' . $request->user_id);
$document = Document::create([
'user_id' => $request->user_id,
'title' => $request->title,
'description' => $request->description,
'file_path' => $path
]);
return redirect($document->path());
}
This method takes the file from the form, makes sure it is a pdf and then saves the file to storage/app/documents/{user_id}. It then creates a Document record in the database and forwards to the URL based on the document id: /admin/document/{ $document->id }
That route is defined as Route::get('/admin/document/{document}', 'DocumentController#show');
Where in the controller I pass the document to the view:
public function show(Document $document, Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
$storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
return view('admin.document', compact('document', 'storagePath'));
}
On that page I would like to display the pdf document.
resources/views/admin/document.blade.php
#extends('layouts.app')
#section('content')
<div class='container'>
<div class='row'>
<div class='col-sm-2'>
<a href='/admin'>< Back to admin</a>
</div>
<div class='col-sm-8'>
{{ $document }}
<embed src="{{ Storage::url($document->file_path) }}" style="width:600px; height:800px;" frameborder="0">
</div>
</div>
</div>
#endsection
I have tried using the $storagePath variable and Storage methods but cannot get the pdf file to display within the iframe.
Using local file storage how would I display the file in the browser? Also, I've protected the route so that only admins can view the document's page but what is the best way to secure the path to the document itself?
If you want your files to be protected (only admin can access them), then you need to create a new route and new DocumentController method getDocument
Add new route
Route::get('documents/pdf-document/{id}', 'DocumentController#getDocument');
In DocumentController, add
use Storage;
use Response;
Add new method that will read your pdf file from the storage and return it back
public function getDocument($id)
{
$document = Document::findOrFail($id);
$filePath = $document->file_path;
// file not found
if( ! Storage::exists($filePath) ) {
abort(404);
}
$pdfContent = Storage::get($filePath);
// for pdf, it will be 'application/pdf'
$type = Storage::mimeType($filePath);
$fileName = Storage::name($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$fileName.'"'
]);
}
In your view you can show the document like this
<embed
src="{{ action('DocumentController#getDocument', ['id'=> $document->id]) }}"
style="width:600px; height:800px;"
frameborder="0"
>
Shorter version of that Response::make() from #ljubadr answer:
return Storage::response($document->file_path)
<embed
src="{{ url('/filepath') }}"
style="width:600px; height:800px;"
frameborder="0">