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!!!!!!!!!
Related
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.
I want to check if an extension is part of an array:
So: if an extension is not part of a forbidden array; do something is allowed
$ext = $path_info['extension'];
$ForbiddenExts = array("php", "html", "htm");
if( $ext != in_array($ForbiddenExts)){
// do something allowed
Change your code to:
$ext = $path_info['extension'];
$ForbiddenExts = array("php", "html", "htm");
if(!in_array($ext, $ForbiddenExts))
{
// do something
}
Check this link for more explanation.
Other than using
if( $ext != in_array($ForbiddenExts)){
You can use
if(!in_array($ext, $ForbiddenExts)){
//your code
}
You have to practice checking the mime type too. Otherwise it may cause errors.
for eg: if someone edit the extension of a ".txt" file to ".pdf"
(assuning pdf is allowed type). Then if you don't check mime type, the
code will accept the file as pdf
Change your code to:
$fileName = 'banner.jpg';
$fileNameParts = explode('.', $fileName);
echo $ext = end($fileNameParts);
$allowed_extensions = array("jpg", "jpeg", "png");
if(in_array($ext, $allowed_extensions))
{
echo 'Allowed Extension';
// do something
}else{
echo 'Not Allowed Extension';
// do something
}
Check this link for more explanation.
I am studying PHP but I don't get the right way by myself. I'd like having Img always required (and I check this in the form input required attribute) but I can decide if upload PDF or not. The script doesn't continue if I don't select both.
I have this:
// image select from form
$img = basename($_FILES['img']['name']);
$allow_img = array('jpg', 'png', 'jpeg');
$ext_img = explode('.', strtolower($_FILES['img']['name']));
$type_img= end($ext_img);
//pdf select from form
$pdf = basename($_FILES['pdf']['name']);
$allow_pdf = array('pdf');
$ext_pdf = explode('.', strtolower($_FILES['pdf']['name']));
$type_pdf= end($ext_pdf);
if ($img || $pdf) {
if(!in_array($type_img, $allow_img) || !in_array($type_pdf, $allow_pdf) ) {
echo "<p><a href='../admin.php'><img style='border:none;' src='../../img/arrow-left.png' /></a>Only jpg, png, jpeg and PDF.</p>";
}
}
Here you go a super fast way to accomplish this:
$filename = $_FILES['img']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
// allowed extensions
$allowed = array('jpeg', 'png', 'jpeg', 'gif');
if (in_array($ext, $allowed)) {
echo "<p><a href='../admin.php'><img style='border:none;' src='../../img/arrow-left.png' /></a>Only jpg, png, jpeg and PDF.</p>";
}
That's it :)
You need javascript for this.
Before you send return, you have check type of file.
Most likely the second basename() call crashes, since no $_FILES['pdf'] is present when no pdf file is uploaded. But you don't even check for an error here... Take a look into the http servers error log file, most likely you will see the error there.
That said: always look into the log files if something unexpected happens. And always test for a variables existance before you use it. And always do error checking when calling some function which might not return what you expect.
You can use pathinfo() inbuilt php function,
$File = $_FILES['image']['name'];
$Infos = pathinfo($File);
echo $extension = $info[extension];
echo "<pre>"; print_r($Infos); echo "</pre>";
$extension = strtolower( $extension);
if( $extension=='pdf'){
// do your stuff
}
So basically, I am simply just trying to check for the correct file extension on a file that is being uploaded.
I know, this question has been answered on here a few times before, although I keep getting the same error and there is no solution or suggestions out there to why this is happening.
Here is my code:
$file = fopen($_FILES['upload_csv']['tmp_name'], 'r');
$ext = pathinfo($file, PATHINFO_EXTENSION);
if($ext != "csv")
{
$errors[] = "Sorry, but only CSV files are supported";
}
Here is my error:
Warning: pathinfo() expects parameter 1 to be string
I have tried around 3 other alternatives now, all using pathinfo(). Although, the exact same error is still shown.
Does anyone have any suggestions to why this is happening?
Your problem is here:
$file = fopen($_FILES['upload_csv']['tmp_name'], 'r');
$ext = pathinfo($file, PATHINFO_EXTENSION);
fopen returns a file handle for use reading and writing a file, but pathinfo is expecting a string containing a filename (optionally, with a path), but you're giving it a file handle.
You should, in any case, be looking at $_FILES['upload_csv']['name'], which is the original name of the file, and extracting the file extension from that.
$path_info = pathinfo('/foo/bar/baz.bill');
echo $path_info['extension']; // "bill"
You can simply read the extension from the name of the file. There is no need to fopen the file.
$allowedTypes = 'csv, xls, xlsx';
function getExtension($str) {
$i = strrpos($str,".");
if (!$i) { return ""; }
$l = strlen($str) - $i;
$ext = substr($str,$i+1,$l);
return $ext;
}
$filename = stripslashes($_FILES[$fileElementName]['name']);
$extension = getExtension($filename);
$extension = strtolower($extension);
$allowedTypes = explode(',',ltrim(rtrim($allowedTypes,','),','));
array_walk($allowedTypes, create_function('&$val', '$val = ltrim(trim($val),".");'));
if (!in_array($extension, $allowedTypes))
{
$errors[] = "Sorry, but only CSV files are supported";
}
$extension=strtolower(pathinfo($_FILES['upload_csv']['tmp_name'], PATHINFO_EXTENSION));
if($ext != "csv")
{
$errors[] = "Sorry, but only CSV files are supported";
}
I want to grab the file name from a known base name in PHP.
I've searched and found pathinfo(), but then you already give the file name with base name and extension in the argument.
Also in the pathinfo() docs:
$path_parts = pathinfo('/path/basename');
var_dump($path_parts['extension']);
That's more or less what I need, but the result is :
string '' (length=0)
I want the extension, not an empty string. I know the base name, but I don't know the extension, how do I grab that?
To list file names, knowing only the base, you can use glob. It returns an array because there may be several files with the same base but different extensions, or none at all:
$files = glob($base.'.*');
if (!empty($files))
echo $files[0];
If file has an extension you can get it like this
$file_name = 'test.jpg';
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
echo $ext; // output:jpg
Example: To scan all files in images directory and show if ext is allowed or not
$image_path = __DIR__ . '/images/';
$files = scandir($image_path);
$allowed_images = array('jpg', 'jpeg', 'gif', 'png');
foreach ($files as $file_name) {
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
if (in_array($ext, $allowed_images)) {
echo $ext . ' allowed<br>';
} else {
echo $ext . ' not allowed<br>';
}
}
You could use:
$ext = end(explode('.',$filename));
Note: it's not secure to rely on this extension to determine the file type.