I have an image in my database saved as a large BLOB. and now I want to retrieve it and save it to my file system.
for this purpose I have done the following, but the images that were saved to my file system were corrupted ones.
Approach1:
$basedir = 'images/';
$imagename = strtolower(preg_replace('/([^\w\d\-_]+)/', '-', $row->name));
$filename = $basedir . $imagename . '_' . $row->id. '.jpg';
$file_content = base64_decode($row->image_data);
return file_put_contents($filename, $file_content);
Approach2:
$basedir = 'images/';
$imagename = strtolower(preg_replace('/([^\w\d\-_]+)/', '-', $row->name));
$filename = $basedir . $imagename . '_' . $row->id . '.jpg';
fopen($filename,'w');
if($fh = fopen("{$filename}", "wb")) {
fwrite($fh, base64_decode($row->image_data));
fclose($fh) ;
}
Please help!!!
This should do the trick if the BLOB isn't encoded:
file_put_contents('filename.jpg', $row->image_data);
Related
I used to store my upload files (images) in my public folder but this time I want to store them in my storage folder and I get this error
Can't write image data to path (C:\laragon\www\mynewsite\storage\images/aboutimage-1522481830.png)
Error comes from this line (where I use intervention/image package)
Image::make($image)->resize(1200, 600)->save($location);
My function:
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = 'aboutimage' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = storage_path('images/' . $filename);
Image::make($image)->resize(1200, 600)->save($location);
$oldFilename = $indexabout->image;
$indexabout->image = $filename;
Storage::delete($oldFilename);
}
any idea?
UPDATE
My files will upload in root/storage folder instead of root/storage/app/public/images
why is that?
Update 2
I changed my function to code below and it's uploading where it suppose to upload but it does not delete the old image
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = '/aboutimage' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = storage_path('app/public/images' . $filename);
Image::make($image)->resize(1200, 600)->save($location);
$oldFilename = $indexabout->image;
$indexabout->image = $filename;
Storage::delete($oldFilename);
}
SOLVED
here is final code:
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = 'aboutimage' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = storage_path('app/public/images/' . $filename); // root storage path
Image::make($image)->resize(1200, 600)->save($location);
Storage::delete('images/' . $indexabout->image); //public storage path
$indexabout->image = $filename;
}
Basically I gave Root/Storage path to store data and Public/Storage path for deleting them in update method.
I'm working with laravel 5.4 I have a form which I can upload my logoimage and in update function I have this code:
//Save logo
if ($request->hasFile('logo')) {
$avatar = $request->file('logo');
$filename = time() . '.' . $avatar->getClientOriginalExtension();
$location = public_path('avatars/logos/');
$request->file('logo')->move($location, $filename);
$oldFilename = $general_Settings->logo;
$general_Settings->logo = $filename;
Storage::delete($oldFilename);
}
$general_Settings->save();
for updating my image which is work but as you see I have Storage::delete($oldFilename); this part doesn't work and just keep the old image.
what do you think is issue of that?
Solved:
The issue was Filesystem.php I made my local root set to 'root' => public_path('avatars/'), and changed all my functions in my app because no way to save images in sub-folders and delete them just can save in sub-folders.
then my update function become like this:
if ($request->hasFile('logo')) {
$avatar = $request->file('logo');
$filename = 'sitelogo' . '-' . time() . '.' . $avatar->getClientOriginalExtension();
$location = public_path('avatars/');
$request->file('logo')->move($location, $filename);
$general_Settings->logo = $filename;
}
$general_Settings->save();
I hope this help someone.
Since, You have stored logo file name only not full path of file,
You need to give full path from public folder to delete image. Change delete line as:
if ($request->hasFile('logo')) {
$avatar = $request->file('logo');
$filename = time() . '.' . $avatar->getClientOriginalExtension();
$location = public_path('avatars/logos/');
$request->file('logo')->move($location, $filename);
$oldFilename = $general_Settings->logo;
$file_path = "avatars/logos/".$oldFilename;
$general_Settings->logo = $filename;
Storage::delete($file_path);
}
$general_Settings->save();
This might work.
I have my upload php code where my intent is , obtained file from $_files,
add a random number between 0 and 9999 to the name of image like this:
image sent : image.jpg
before saving : image321.jpg
the image is saved in my upload folder but the filename are like
"php2983204tmp"
if ($file !== null) {
$rand = rand(0000,9999);
$path = "some_path";
$file_name = $file->getClientOriginalName(); // file
$extension = $file->getClientOriginalExtension(); // jpg
$file->move($path, $file_name.$rand.$extension);
$response = "File loaded successfully: " . $file_name.$extension;
$response .= '<br>size: ' . filesize($path . '/' . $file->getClientOriginalName()) / 1024 . ' kb';
return new Response($response);
any ideas to fix?
The filename in your example is php and your extension is tmp. None of them have the . that you are missing.
You need to add the dot . as a string after the $file_name and $rand, before the $extension like this:
$file->move($path, $file_name.$rand. "." .$extension);
TIME is always unique identity, use it as below (maybe helpful):
if ($file !== null) {
$rand = rand(0000,9999).time();
$path = "some_path";
$file_name = $file->getClientOriginalName(); // file
$extension = $file->getClientOriginalExtension(); // jpg
$file->move($path, $file_name.$rand.$extension);
$response = "File loaded successfully: " . $file_name.$extension;
$response .= '<br>size: ' . filesize($path . '/' . $file->getClientOriginalName()) / 1024 . ' kb';
return new Response($response);
You need add in the desired chars to the actual string.
$file->move($path, $file_name.$rand.".".$extension);
But I have to say, I am against how you've done this, you don't even check if the "newly" created string already exists in the directory. Its better to hash the time of upload with the original filename, rename the file to the new hash and use a database to point to the file as this way the filename collisions don't occur.
$fn = md5(microtime(true) . $extension . $file_name);
$file->move($path, $fn);
Any idea what's wrong?
I end up with 1bytes files and they are wrong. Using Intervention Image & PHP. Tried many ways to get it but nothing... If I just want to display it works but I can't save the picture...
$avatar_url = 'http://graph.facebook.com/' . $id . '/picture?type=square&width=140&height=140&redirect=false';
$avatar_pic_url = json_decode(file_get_contents($avatar_url), true)['data']['url'];
dd($avatar_pic_url);
$avatar = Image::make($avatar_pic_url);
$extension = 'jpg';
// save it
$destinationPath = 'uploads/avatars/';
$filename = uniqid(). '.' . $extension;
$path_to_temp_image = $avatar->dirname . '/' . $avatar->filename;
$key = $destinationPath . $filename;
// Upload avatar to remote storage
$uploadSuccess = Storage::put($key, $path_to_temp_image);
How do I check if file name exists, rename the file?
for example, I upload a image 1086_002.jpg if the file exists, rename the file as 1086_0021.jpg and save, if 1086_0021.jpg is exist, rename 1086_00211.jpg and save , if 1086_00211.jpg is exist, rename 1086_002111.jpg and save...
Here is my code, it only can do if 1086_002.jpg exist, rename the file as 1086_0021.jpg, maybe should do a foreach, but how?
//$fullpath = 'images/1086_002.jpg';
if(file_exists($fullpath)) {
$newpieces = explode(".", $fullpath);
$frontpath = str_replace('.'.end($newpieces),'',$fullpath);
$newpath = $frontpath.'1.'.end($newpieces);
}
file_put_contents($newpath, file_get_contents($_POST['upload']));
Try something like:
$fullpath = 'images/1086_002.jpg';
$additional = '1';
while (file_exists($fullpath)) {
$info = pathinfo($fullpath);
$fullpath = $info['dirname'] . '/'
. $info['filename'] . $additional
. '.' . $info['extension'];
}
Why not just append a timestamp onto the filename? Then you won't have to worry about arbitrarily long filenames for files which have been uploaded many times.
I hope this helps
$fullPath = "images/1086_002.jpg" ;
$fileInfo = pathinfo($fullPath);
list($prifix, $surfix) = explode("_",$fileInfo['filename']);
$x = intval($surfix);
$newFile = $fileInfo['dirname'] . DIRECTORY_SEPARATOR . $prifix. "_" . str_pad($x, 2,"0",STR_PAD_LEFT) . $fileInfo['extension'];
while(file_exists($newFile)) {
$x++;
$newFile = $fileInfo['dirname'] . DIRECTORY_SEPARATOR . $prifix. "_" . str_pad($x, 2,"0",STR_PAD_LEFT) . $fileInfo['extension'];
}
file_put_contents($newFile, file_get_contents($_POST['upload']));
I hope this Helps
Thanks
:)
I feel this would be better. It will help keep track of how many times a file with the same name was uploaded. It works in the same way like Windows OS renames files if it finds one with the same name.
How it works: If the media directory has a file named 002.jpg and you try to upload a file with the same name, it will be saved as 002(1).jpg Another attempt to upload the same file will save the new file as 002(2).jpg
Hope it helps.
$uploaded_filename_with_ext = $_FILES['uploaded_image']['name'];
$fullpath = 'media/' . $uploaded_filename_with_ext;
$file_info = pathinfo($fullpath);
$uploaded_filename = $file_info['filename'];
$count = 1;
while (file_exists($fullpath)) {
$info = pathinfo($fullpath);
$fullpath = $info['dirname'] . '/' . $uploaded_filename
. '(' . $count++ . ')'
. '.' . $info['extension'];
}
$image->save($fullpath);
You can change your if statement to a while loop:
$newpath = $fullpath;
while(file_exists($newpath)) {
$newpieces = explode(".", $fullpath);
$frontpath = str_replace('.'.end($newpieces),'',$fullpath);
$newpath = $frontpath.'1.'.end($newpieces);
}
file_put_contents($newpath, file_get_contents($_POST['upload']));