Cannot upload image via move_uploaded_file - php

I am using code below to upload image via drag an drop system. Everything is ok, JS part is working well. But PHP part of code shows me error:
PHP Warning: move_uploaded_file(assets/img/photos/1657614494809.jpg): failed to open stream: No such file or directory in /www_root/_inc/upload.php on line 29, referer: https://smartobchod.sk/bazar/add.php
[Sat Jul 23 12:56:18 2022] [error] [client 78.99.32.1] PHP Warning: move_uploaded_file(): Unable to move '/home/gm016900/tmp/phpKaBL6m' to 'assets/img/photos/1657614494809.jpg' in /www_root/_inc/upload.php on line 29, referer: https://smartobchod.sk/bazar/add.php
EDITED 25.07.2022 (added some security checks)
My PHP code in upload.php is:
<?php
// Get reference to uploaded image
$image_file = $_FILES["file"];
// Get image name
$image_name = $_FILES["file"]["name"];
// Get file size
$image_size = $_FILES["file"]["size"];
// Exit if no file uploaded or image name contains unvalid characters /, \\
if ( ( !strpos($image_name, '/') || !strpos($image_name, '\\') ) && isset($image_file) ) {
$errors = array();
$maxsize = 10485760;
$acceptable = array(
'image/jpeg',
'image/jpg',
'image/gif',
'image/png'
);
} else {
die('No image uploaded.');
}
// Exit if image file is zero bytes or if image size is more then 10 MB
if (getimagesize($image_file["tmp_name"]) <= 0) {
die('Uploaded file has no contents.');
} elseif ($image_size >= $maxsize) {
die('Image is too large. Image must be less than 10 megabytes.');
}
// Exit if is not a valid image file or image has not supported type
$image_type = exif_imagetype($image_file["tmp_name"]);
if (!$image_type) {
die('Uploaded file is not an image.');
} elseif ( !in_array($image_file["type"], $acceptable) ) {
die('Image has not supported type JPG, PNG, GIF.');
} else {
$src = "default.png";
}
// Get file extension based on file type, to prepend a dot we pass true as the second parameter
$image_extension = image_type_to_extension($image_type, true);
// Create a unique image name
$image_name = bin2hex(random_bytes(16)) . $image_extension;
// Location
$relative_location = "/bazar/assets/img/photos/".$image_name;
$absolute_location = dirname(__DIR__, 2).$relative_location;
$return_arr = array();
// transfer file created in tmp folder to location of pictures with name saved in address of $location
// in $image_file is stored $_FILES["file"]["tmp_name"]
if (move_uploaded_file($image_file["tmp_name"], $absolute_location)) {
$src = $relative_location;
$return_arr = array("name" => $image_name,"size" => $image_size, "src"=> $src);
}
echo json_encode($return_arr);
This is sent in header to upload.php:
Content-Disposition: form-data; name="file"; filename="1657614494809.jpg"
Content-Type: image/jpeg
Can you advice me what can be problem?

Here I think your tmp/ folder permission is not proper so it is not able to read that folder or write just check /home/gm016900/tmp permission is should be gm016900 or it may not be created.

Based on your comments, you just need to keep track of relative vs absolute paths.
I wasn't able to test this code, but hopefully you should get the general gist if it fails. Instead of a single $location variable, I'm using two variables $relativeLocation and $absoluteLocation. The latter isn't actually needed, but it makes debugging much easier.
/* Getting file name */
$filename = $_FILES['file']['name'];
/* Getting File size */
$filesize = $_FILES['file']['size'];
/* Location */
$relativeLocation = "assets/img/photos/".$filename;
$absoluteLocation = __DIR__.'/'.$relativeLocation;
$return_arr = array();
/* Upload file */
if (move_uploaded_file($_FILES['file']['tmp_name'], $absoluteLocation)) {
$src = "default.png";
// checking file is image or not
if (is_array(getimagesize($absoluteLocation))) {
$src = $relativeLocation;
}
$return_arr = array("name" => $filename, "size" => $filesize, "src" => $src);
}
echo json_encode($return_arr);
Depending on where your function lives relative to the storage, you might need to go update a directory or two, or possibly go up and then back down:
// Up one directory
$absoluteLocation = dirname(__DIR__).'/'.$relativeLocation;
// Up two directories
$absoluteLocation = dirname(__DIR__, 2).'/'.$relativeLocation;
// Up one directory then over to a sibling directory
$absoluteLocation = dirname(__DIR__).'/files/'.$relativeLocation;
As a personal preference, I always have a constant (or equivalent) in my projects that represents a known location on disk, and if I'm using a router script I define it there. That way, no matter how deep I get in nesting I can build my paths relative to that constant.
I also go one step further and use this library (merged into Symfony here) to avoid string concatenation, not worry about whether something ends with a slash or not, and to be more cross platform. So my actual code looks like:
$absoluteLocation = Path::join(PROJECT_ROOT, 'files', $relativeLocation);
Some people might think that's overkill, but once again it is just a personal preference.

Related

PHP move_uploaded_file doesn't work occasionally?

I now there are lots of same questions here, but I didn't find my answer.
I want to upload an image using move_uploaded_file() function in PHP. Here is my logic?
//check if file uploaded
if (!isset($_POST) || !isset($_FILES)) {
return back();
}
// allowed extensions
$extensions = ['jpg', 'jpeg', 'gif', 'png'];
$fileName = pathinfo($_FILES['profile-image']['name'], PATHINFO_FILENAME);
// save file extension into a variable for later use
$parts = explode('.',$_FILES['profile-image']['name']);
$extension = strtolower(end($parts));
$fileSize = $_FILES['profile-image']['size'];
// check the extension
if (!in_array($extension, $extensions)) {
return back()->withErrors(['File Extension is not valid']);
}
// check if file size is less than 2MB
if ($fileSize >= 2e+6) {
return back()->withErrors(['File Size is too large.']);
}
//check if there is other errors
if ($_FILES['profile-image']['error']) {
return back()->withErrors(['You have anonymus error']);
}
// generate a unique file name
$profile_image = Hash::make($fileName) . '-' . time() . '.' . $extension;
// make a directory if there isn't one
if (!is_dir('public/img')) {
mkdir('public/img');
}
// if current user has an image then delete it
$user = App::get('database')->find('users', compact('id'));
if ($user->profile_image) {
unlink('public/img/' . $user->profile_image);
}
// move image into directory and final check for errors
if( ! move_uploaded_file($_FILES['profile-image']['tmp_name'], 'public/img/' . $profile_image) ) {
return back()->withErrors(['Your file doesn\'t uploaded']);
}
// Insert Uploaded Image into DB.
App::get('database')->update('users', compact('id'), compact('profile_image'));
return redirect('dashboard')->withMessage('Thank for uploading the file.');
I try this code, everything works properly but just sometimes. I don't know why sometimes my uploaded file doesn't move to the directory and sometimes it does. I tried for the same image, sometimes it uploaded and sometimes it failed. This is interesting, because when I upload an image and it fails, can't catch any errors at all.
Did you check max_file_uploads and post_max_size in your php.ini file ?
Maybe the file is bigger than the maximum size allowed.
Regards.
OK, I find the problem. When I hash the image name and save it to DB, sometimes it includes / inside file name, then when I use the file name in image src attribute, it considers the part before the / as another directory.
It might have trouble with,
Your Destination Directory have some writing permission issue.
Try this for manage file permission,
if (!is_writable($url)) {
try {
chmod($url, 0644);
} catch (Exception $e) {
die($e->getMessage() . ' | File : ' . $url . ' | Needs write permission [0644] to process !');
}
}
All the Best !

How to encode the image file in PHP

i am using one file upload form field,from that field i want to encode the filename,don't to want to move the any temporary folder,directly i want to insert the database,while display the image directly fetch DB and display the website,I want encode like data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA
$path = basename($_FILES['file']['name']);//here i am getting filename
$im = file_get_contents($path);//here i am getting false
$imdata = base64_encode($im); // so can't here encode the filename
$horoscope = array("encode" => $imdata,"path" =>$path,"getcontents" =>$im);
echo json_encode($horoscope);
PHP uploads the file into a temporary file and tells you where that is in the $_FILES['file']['tmp_name'] the $_FILES['file']['name'] holds the file name that the user called the file on their system, the one they select in the browser.
So if you want to grab the file before you have done a move_uploaded_file() on the file use $_FILES['file']['tmp']
$path = $_FILES['file']['tmp_name'];
$im = file_get_contents($path);
$imdata = base64_encode($im);
$horoscope = array("encode" => $imdata,
"path" =>$path,
"getcontents" =>$im
);
echo json_encode($horoscope);
I was not sure what you were passing back the $path for, so that may still need to be $_FILES['file']['name'].
$horoscope = array("encode" => $imdata,
"path" => $_FILES['file']['name'],
"getcontents" => $im
);
RE:Comment 1
I assume you want to store the base64encoded version of the file to the database so that will be $imdata
RE:Comment 2
To get the extension of the incoming file use pathinfo()
$path = $_FILES['file']['tmp_name'];
$file_parts = pathinfo($path);
$extn = $path_parts['extension'];
But beware, just because the extension says .png is not actual guarantee that it is a .png file

Image Upload in CakePHP on localhost

i am getting an error in uploading image into folder. there is an error occured during uploading that image.
my Controller Code is (cakeplus is my root folder ex: htpp://localhost/cakeplus) :
$directory = "http://".$_SERVER['HTTP_HOST'].'/cakeplus/pics';
if(!is_dir($directory)) {
mkdir($directory,0777);
}
$files_array = $this->data['Photo']['path'];
//pr($files_array); die;
if(isset($files_array['name']) && $files_array['name']!='') {
$filetype = $files_array['type'];
$filesize = $files_array['size'];
$filename = $files_array['name'];
$filetmpname = $files_array['tmp_name'];
$file_type = explode('.',$filename);
$ext_name = array_reverse($file_type);
$final_file_title = $ext_name[1];
$file_name = Inflector::slug( str_replace( ".".$ext_name[0], "" , $filename ). '_' .time() ,'-' );
$newFileName = $file_name.'.'.$ext_name[0];
move_uploaded_file($filetmpname, $directory.'/'.$newFileName);
$requirementuploadData['Photo']['path'] = $file_name;
$this->Photo->create();
$this->Photo->save($requirementuploadData,false);
}
Error(s)(Warnings) :
Warning (2): move_uploaded_file(http://localhost/cakeplus/pics/wallpaper-1433586197.png): failed to open stream: HTTP wrapper does not support writeable connections [APP\Controller\PhotosController.php, line 31]
Warning (2): move_uploaded_file() [function.move-uploaded-file]: Unable to move 'C:\xampp\tmp\phpA80D.tmp' to 'http://localhost/cakeplus/pics/wallpaper-1433586197.png' [APP\Controller\Photos
Look into the CakePHP Upload plugin - it will abstract away much of the work that goes into dealing with file and image uploads.
The error you are seeing is because you cannot use move_uploaded_file() to transfer from a file path (C:\xampp\tmp\phpA80D.tmp) to an HTTP URL (http://localhost/cakeplus/pics/wallpaper-1433586197.png).
If you don't want to use the Upload plugin, and would prefer to keep working with what you already have, I would start by changing the $directory path. Something like this might be more appropriate:
$directory = WWW_ROOT . 'pics';
This will contain the path to your ./yourapp/webroot/pics directory, which is also the location of http://yourapp.com/pics.
Check out the documentation for more predefined paths.
may be folder dont have permission to write an image.
you should to use cakephp upload component.
$this->Upload->upload($file,$destination,$name);

Retrieving external image and saving locally results in distorted image

Stuck on this one. I have this function below that simply takes $ImageSrc which is an external image from anywhere, eg imgur, and then saves it locally (this is not a scraper, I'm allowing people to attach images to their profiles)
public function UploadScreenshot($ImageSrc, $Title, $Description = false) {
$RandomName = substr(md5($Title . time()), 0, 20);
$UploadDir = "/home/vanrust/public_html/Screenshots/";
$file = pathinfo($ImageSrc);
$ext = $file["extension"];
if (!in_array($ext, array('jpg','png','bmp','jpeg'))) return array("error" => "Invalid File Type");
$RandomName = "{$RandomName}.{$ext}";
$image = file_get_contents($ImageSrc);
file_put_contents($UploadDir . $RandomName, $image);
}
The result of the file no matter what is unrecognizable.
The image:
After UploadScreenshot() has retrieved it:
Try to use rename() to move the original file to the new location and rename it.
$file = pathinfo($ImageSrc);
$ext = $file["extension"];
if (!in_array($ext, array('jpg','png','bmp','jpeg'))) return array("error" => "Invalid File Type");
$RandomName = "{$RandomName}.{$ext}";
rename($UploadDir . $RandomName, $ImageSrc);
}
Alternatively, you can use move_uploaded_file() if your $ImageSrc does contain a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism).
file_put_contents() needs to be used with caution. A single offset (in binary codes) at the beginning or at the end of the file will significantly alter the picture. It requires a validation at the end to compare both files bytes.

FPDF error: Image file has no extension and no type was specified

I am getting the error as mentioned on the title when I try to run my php code which will generate a PDF file. This is the current code I am using:
$pdf = new PDF();
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetFont('Times','',12);
foreach($inventories as $key => $inventories) :
$image = $inventories['image'];
$resourceID = $inventories['resourceID'];
$learningcentre = $inventories['learningcentre'];
$title = $inventories['title'];
$quantity = $inventories['quantity'];
$description = $inventories['description'];
$html= 'Resource ID: '. $resourceID. '<br>Title: '.$title.'<br>Learning Centre: '.$learningcentre.'<br>Quantity: '.$quantity.'<br>Description: '.$description.'<br><br>';
$pdf->Image('images/'.$image,10,6,30);
$pdf->WriteHTML($html);
endforeach;
$pdf->Output();
My images are currently stored in the images folder and I have converted the images file type to "File" by using these codes:
$fileTypes = array(
'image/pjpeg',
'image/jpeg',
'image/png',
'image/gif'
);
// default value for unsuccessful move file
$successfullyMoveFile = false;
// the name of the input type
$fileInputName = 'file';
// an array to store all the possible errors related to uploading a file
$fileErrorMessages = array();
//if file is not empty
$uploadFile = !empty($_FILES);
if ($uploadFile)
{
$fileUploaded = $_FILES[$fileInputName];
// if we have errors while uploading!!
if ($fileUploaded['error'] != UPLOAD_ERR_OK)
{
$errorCode = $fileUploaded['error']; // this could be 1, 2, 3, 4, 5, 6, or 7.
$fileErrorMessages['file'] = $uploadErrors[$errorCode];
}
// now we check for file type
$fileTypeUploaded = $fileUploaded['type'];
$fileTypeNotAllowed = !in_array($fileTypeUploaded, $fileTypes);
if ($fileTypeNotAllowed)
{
$fileErrorMessages['file'] = 'You should upload a .jpg, .png or .gif file';
}
// if successful, we want to copy the file to our images folder
if ($fileUploaded['error'] == UPLOAD_ERR_OK)
{
$successfullyMoveFile = move_uploaded_file($fileUploaded["tmp_name"], $imagesDirectory . $newFileName);
}
}
I believed the problem lies with the file type. Is there any way allow FPDF to understand the file type?
The instructions in the error message are quite clear but I'll try to explain them with another words since you're finding some difficulties. The Image() function has a type parameter described this way:
Image format. Possible values are (case insensitive): JPG, JPEG, PNG
and GIF. If not specified, the type is inferred from the file
extension.
For instance, if the picture is a GIF you need to type 'GIF' (don't forget the quotes). The following example is provided:
$pdf->Image('http://chart.googleapis.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World',60,30,90,0,'PNG');
But you call the function this way:
$pdf->Image('images/'.$image,10,6,30);
You've left the type empty, so FPDF (as documented) will try to guess the image type from the file extension. The extension is the trailing part of the file name after the dot. For instance, if the file is called kitten.jpg then the extension is jpg and FPDF will assume it's a JPEG picture. The following example is provided:
$pdf->Image('logo.png',10,10,-300);
Back to your code, I have no way to know what $image or $newFileName contain (you've managed to omit all the relevant code) but, given the error message, I'd say it doesn't end with a file extension that FPDF can recognise; it probably doesn't even have an extension at all. So you need to either append the file extension to the file name or store the file type anywhere else (e.g. a database table). You could also use heuristics to find out the image type but I don't think it's worth the effort.

Categories