PHP Image Uploaded Name won't change - php

I have PHP function to upload file (image).
foreach($_FILES['wallpaperFile']['tmp_name'] as $key => $tmpName)
{
$file_name = $_FILES['wallpaperFile']['name'][$key];
$file_type = $_FILES['wallpaperFile']['type'][$key];
$file_size = $_FILES['wallpaperFile']['size'][$key];
$file_tmp = $_FILES['wallpaperFile']['tmp_name'][$key];
move_uploaded_file($file_tmp,"assets/img/wallpapers/".time().$file_name);
}
It's working and I can see the data image uploaded on my folder.
But now how can I set the image file name only time() without .$file_name
If I remove .$file_name, file uploaded is not correct without extension and only 1 file, even though I uploaded 3 files.
Example:
Image file name: 1510750186shubuh.jpg
What I want only
1510750186.jpg

You can use pathinfo() for this, with PATHINFO_EXTENSION flag, Like:
foreach($_FILES['wallpaperFile']['tmp_name'] as $key => $tmpName)
{
$file_name = $_FILES['wallpaperFile']['name'][$key];
$file_type = $_FILES['wallpaperFile']['type'][$key];
$file_size = $_FILES['wallpaperFile']['size'][$key];
$file_tmp = $_FILES['wallpaperFile']['tmp_name'][$key];
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
move_uploaded_file($file_tmp,"assets/img/wallpapers/".time().'.'.$ext);
}
This will only add the extension and no the full file name.
Edit:
To upload multiple files at the same time try to use 1 of these:
$newFileName = time()."{$key}.{$ext}";
move_uploaded_file($file_tmp,"assets/img/wallpapers/".$newFileName);
Or
$newFileName = str_replace('.','',microtime(true)).".{$ext}";
move_uploaded_file($file_tmp,"assets/img/wallpapers/".$newFileName);

I don't think that the extension of the file is your problem here. It's that time() only has a one-second resolution. It's highly improbable that time() will have a different value in any iteration of that loop. As such all your files have the same name with just time().
It's probably better to use something like microtime(true), which has microsecond fidelity or uniqid() to get a higher resolution in the same request.
foreach($_FILES['wallpaperFile']['tmp_name'] as $key => $tmpName)
{
$file_name = $_FILES['wallpaperFile']['name'][$key];
$file_type = $_FILES['wallpaperFile']['type'][$key];
$file_size = $_FILES['wallpaperFile']['size'][$key];
$file_tmp = $_FILES['wallpaperFile']['tmp_name'][$key];
/* user either this */
move_uploaded_file($file_tmp,"assets/img/wallpapers/" . microtime(true));
/* or this */
move_uploaded_file($file_tmp,"assets/img/wallpapers/" . uniqid());
}
You can see the difference by simply printing the value of both time() and microtime(true) inside that loop to realize the problem that time() would pose on your requirements here.
foreach($_FILES['wallpaperFile']['tmp_name'] as $key => $tmpName)
{
echo "time(): ", time(), "<br>\n";
echo "microtime(true): ", microtime(true), "<br>\n";
echo "uniqid(): ", uniqid(), "<br>\n";
}
Warning
You should never rely on $_FILES['wallpaperFile']['name'] here, because it is user-supplied input, and as such it is vulnerable to manipulation. Avoid allowing the client to possibly exploit/manipulate your filesystem by handing them direct-access to it via this vector. Having a completely random filename on your filesystem, instead, and storing that random name in your database to associate it with some arbitrary user-supplied-input is preferrable, because it allows you to retain full-control over your server's file system while still allowing the user to retain control over their own data.

Related

Create a unique name for the uploaded image

I have a certain code for image upload .I found this on the internet and there was no explanation of the code either.What i can understand from the code is that php upload a certain file makes it a temporary file and then moves the temporary file to the original location
Code Looks something like this
$filename = $_FILES["img"]["tmp_name"];
list($width, $height) = getimagesize( $filename );
move_uploaded_file($filename, $imagePath . $_FILES["img"]["name"]);
What happens now is that when i try to provide an unique name to the image when it is being moved using the move_uploaded_file then a file does come up inside the folder but it says an invalid file and with the extension type of file.
My code for trying to achieve the same but with an unique name/id for the uploaded image.
$uniquesavename=time().uniqid(rand());
$filename = $_FILES["img"]["tmp_name"];
list($width, $height) = getimagesize( $filename );
move_uploaded_file($filename, $imagePath . $uniquesavename);
How to achieve the same as before and could you please explain me the previous code as well?
Sample code:
// Get file path from post data by using $_FILES
$filename = $_FILES["img"]["tmp_name"];
// Make sure that it's a valid image which can get width and height
list($width, $height) = getimagesize( $filename );
// Call php function move_uploaded_file to move uploaded file
move_uploaded_file($filename, $imagePath . $_FILES["img"]["name"]);
Please try this one:
// Make sure this imagePath is end with slash
$imagePath = '/root/path/to/image/folder/';
$uniquesavename=time().uniqid(rand());
$destFile = $imagePath . $uniquesavename . '.jpg';
$filename = $_FILES["img"]["tmp_name"];
list($width, $height) = getimagesize( $filename );
move_uploaded_file($filename, $destFile);
Edit 1:
To get image type in two ways:
Get the file type from upload file name.
Use php function as below
CODE
// Get details of image
list($width, $height, $typeCode) = getimagesize($filename);
$imageType = ($typeCode == 1 ? "gif" : ($typeCode == 2 ? "jpeg" : ($typeCode == 3 ? "png" : FALSE)));
$name = $_FILES['file']['name'];
$tmp_name = $_FILES['file']['tmp_name'];
$location = "uploads/";
$new_name = $location.time()."-".rand(1000, 9999)."-".$name;
if (move_uploaded_file($tmp_name, $new_name)){
echo "uploaded";
}
else{
sleep(rand(1,5));
$new_name = $location.time()."-".rand(1000, 9999)."-".$name;
if (move_uploaded_file($tmp_name, $new_name)){
echo "uploaded";
}
else{
echo"failed, better luck next time";
}
}
here, location is folder inside directory, i mainly create folder "uploads"
time() adds timestamp , which is always unique, until two person upload at same time, which is rare.
moreover, adding 4 digit random number to it , making combination rarest
after that adding actual file name , to making combination unique.
why i use it :
u can extract timestamp later if u need to know when image was uploaded.
u can extract actual filename too.
Lets, say our so unique combination somehow fails,
then, php instance will wait for 1 to 5 second whatever random number is generated. and rename with latest timestamp and regenerated random number.
It's the best u can think of without being resource hog.
you can use
$strtotime = strtotime("now");
$filename = $strtotime.'_'.$_FILES['file']['name'];

php is_file not detecting image with period in name

I have a function which checks if image files exist. It works for all images, except when a period is inside the filename. The filenames are user uploaded, and many already exist that are not sanitized. Here is an example:
$img = 'nice_name.jpg'; // detects
$img = 'bad_name.7.jpg'; // doesn't detect
if (is_file($path . $img)) {
return $path . $prefix . $img;
}
I'm not sure how to escape this or make it work. I have doubled checked and the file does exist at that path. The function works for other image names in the same folder.
edit: This was marked a duplicate and linked to a question about uploading files. I am using is_file() to check if a file already exists. There is no uploading occurring, and the file already has the extra "." in its name on the server, so this is a different issue.
You can use basename() to get the file name, and then do something with it, like rename it if it contains a period.
$testfile = "test.7.img";
$extension = ".img";
$filename = basename($testfile, $extension);
if(strpos($filename,".") > 0) {
$newname = str_replace(".","",$filename) . $extension ;
rename($testfile,$newname);
}
//... then continue on with your code

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.

PHP move_uploaded_file dynamic file name - files have no extension

I want to upload some GPX (XML technically) files to the server and rename them with dynamic file names (such as 0.gpx, 1.gpx ... ). I can not figure out how to do this with the move_uploaded_file function as it only creates the files extensionless. I get a 'name' file instead of a 'name.gpx' file.
Shouldn't it use the PATHINFO_EXTENSION of the uploadef file automatically to create the file with the right extension?
I have tried to call the function like this:
$filename = 0;
move_uploaded_file($_FILES['uploadfiles']['tmp_name'][$f], $filename);
$filename++;
Even if I try to create a string with the extension it does not work:
$tmp = 0;
$ext = pathinfo($name, PATHINFO_EXTENSION);
$filename = $tmp + "." + $ext;
move_uploaded_file($_FILES['uploadfiles']['tmp_name'][$f], $filename);
$tmp++;
Help please?
File name should have the extension. This works fine for me to find the extension:
$temp = explode(".", $_FILES["uploadfiles"]["name"]);
$extension = end($temp);
echo $extension; // Display the extension
$tmp = 0;
$filename = $tmp.".".$extension;
move_uploaded_file($_FILES['uploadfiles']['tmp_name'][$f], $filename);
$tmp++;
Hope this helps.
I don't think temporary files have an extension.
You could manually add "gpx" to the name :
$tmp = 0;
$filename = $tmp . ".gpx";
move_uploaded_file($_FILES['uploadfiles']['tmp_name'][$f], $filename);
$tmp++;
Or maybe check the mimetype and craft the appropriate extension out of it.
Or take the extension in $_FILES['uploadfiled']['name'], match it in a whitelist, and append it to your final filename.

PHP image upload - rename without losing extension?

I currently have:
$file_name = $HTTP_POST_FILES['uid']['name'];
$random_digit=rand(0000,9999);
$new_file_name=$random_digit.$file_name;
$path= "uploads/images/users/".$new_file_name;
if($ufile !=none)
{
if(copy($HTTP_POST_FILES['uid']['tmp_name'], $path))
{
echo "Successful<BR/>";
echo "File Name :".$new_file_name."<BR/>";
echo "File Size :".$HTTP_POST_FILES['uid']['size']."<BR/>";
echo "File Type :".$HTTP_POST_FILES['uid']['type']."<BR/>";
}
else
{
echo "Error";
}
}
this generates a random number before the current file name ie 4593example.jpg
but i would just like it to rewrite the whole filename to 4593.jpg removing the ucrrent name (example). When i have tried doing this i lose the extension (.jpg)
any help is appreciated.
If you're dealing with images only, I would consider detecting the image's type using getimagesize() and giving the new file an extension according to that.
That way, you don't have to rely on what extension you get from the user (which could be wrong).
Like so:
$extensions = array(
IMAGETYPE_JPG => "jpg",
IMAGETYPE_GIF => "gif",
IMAGETYPE_PNG => "png",
IMAGETYPE_JPEG2000 => "jpg",
/* ...... several more at http://php.net/manual/en/image.constants.php
I'm too lazy to type them up */
);
$info = getimagesize($_FILES['uid']['tmp_name']);
$type = $info[2];
$extension = $extensions[$type];
if (!$extension) die ("Unknown file type");
move_uploaded_file($_FILES['uid']['tmp_name'], $path.".".$extension);
`
Also:
As #alex says, your method has a considerable risk of collisions of random names. You should add a file_exists() check to prevent those (e.g. a loop that creates a new random number until one is found that doesn't exist yet)
HTTP_POST_FILES is deprecated, use $_FILES instead
I strongly advise you to use move_uploaded_file() instead of copy() which is vulnerable to attacks.
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$newFilename = $random_digit . '.' . $ext;
BTW, what will happen if the random number clashes (which may happen next or in 10 years)?
There are many better ways to name them - for example, hash of the filename and time() should theoretically never clash (though in practice hash collisions do occur).
You can get the original extension by using the following code:
$extension = strrchr($HTTP_POST_FILES['uid']['tmp_name'], '.');
Then you can add the extension to the variable $new_file_name like this:
$new_file_name = $random_digit . $file_name . '.' . $extension;
You can use this code:
$file_name = $HTTP_POST_FILES['uid']['name']; $random_digit=rand(0000,9999);
$extension= end(explode(".", $HTTP_POST_FILES['uid']['name']));
$new_file_name=$random_digit.'.'.$extension; $path= "uploads/images/users/".$new_file_name; if($ufile !=none) { if(copy($HTTP_POST_FILES['uid']['tmp_name'], $path)) { echo "Successful
"; echo "File Name :".$new_file_name."
"; echo "File Size :".$HTTP_POST_FILES['uid']['size']."
"; echo "File Type :".$HTTP_POST_FILES['uid']['type']."
"; } else { echo "Error"; } }
enjoy!!!!!!!!!

Categories