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.
Related
The file name is known but the file extension is unknown. The images in thier folders do have an extension but in the database their names do not.
Example:
$ImagePath = "../images/2015/03/06/"; (Folders are based on date)
$ImageName = "lake-sunset_3";
Does not work - $Ext is empty:
$Ext = (new SplFileInfo($ImagePath))->getExtension();
echo $Ext;
Does not work either - $Ext is empty:
$Ext = (new SplFileInfo($ImagePath.$ImageName))->getExtension();
echo $Ext;
Does not work either - $Ext is still empty:
$Ext = (new SplFileInfo($ImagePath,$ImageName))->getExtension();
echo $Ext;
$Ext should produce ".jpg" or ".jpeg" or ".png" etc.
So my question is simple: What am I doing wrong?
Now, this is a bit of an ugly solution but it should work. Make sure that all your files have unique names else you'll have several of the same file, which could lead to your program obtaining the wrong one.
<?php
$dir = scandir($imagePath);
$length = strlen($ImageName);
$true_filename = '';
foreach ($dir as $k => $filename) {
$path = pathinfo($filename);
if ($ImageName === $path['filename']) {
break;
}
}
$Ext = $path['extension'];
?>
Maybe this might help you (another brute and ugly solution)-
$dir = '/path/to/your/dir';
$found = array();
$filename = 'your_desired_file';
$files = scandir($dir);
if( !empty( $files ) ){
foreach( $files as $file ){
if( $file == '.' || $file == '..' || $file == '' ){
continue;
}
$info = pathinfo( $file );
if( $info['filename'] == $filename ){
$found = $info;
break;
}
}
}
// if file name is matched, $found variable will contain the path, basename, filename and the extension of the file you are looking for
EDIT
If you just want the uri of your image then you need to take care of 2 things. First directory path and directory uri are not the same thing. If you need to work with file then you must use directory path. And to serve static files such as images then you must use directory uri. That means if you need to check files exists or what then you must use /absolute/path/to/your/image and in case of image [site_uri]/path/to/your/image/filename. See the differences? The $found variable form the example above is an array-
$found = array(
'dirname' => 'path/to/your/file',
'basename' => 'yourfilename.extension',
'filename' => 'yourfilename',
'extension' => 'fileextension'
);
// to retrieve the uri from the path.. if you use a CMS then you don't need to worry about that, just get the uri of that directory.
function path2url( $file, $Protocol='http://' ) {
return $Protocol.$_SERVER['HTTP_HOST'].str_replace($_SERVER['DOCUMENT_ROOT'], '', $file);
}
$image_url = path2url( $found['dirname'] . $found['basename'] ); // you should get the correct image url at this moment.
You are calling a file named lake-sunset_3. It has no extension.
SplFileInfo::getExtension() is not designed to do what you are requesting it to do.
From the php site:
Returns a string containing the file extension, or an empty string if the file has no extension.
http://php.net/manual/en/splfileinfo.getextension.php
Instead you can do something like this:
$path = $_FILES['image']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
getExtension() only returns the extension from the given path, which in your case of course doesn't have one.
In general, this is not possible. What if there is a file lake-sunset_3.jpg and a file lake-sunset_3.png?
The only thing you can do is scan the directory and look for a file with that name but any extension.
You're trying to call an incomplete path. You could try Digit's hack of looking through the directory for for a file that matches the name, or you could try looking for the file by adding the extensions to it, ie:
$basePath = $ImagePath . $ImageName;
if(file_exists($basePath . '.jpg'))
$Ext = '.jpg';
else if(file_exists($basePath . '.gif'))
$Ext = '.gif';
else if(file_exists($basePath . 'png'))
$Ext = '.png';
else
$Ext = false;
Ugly hacks aside, the question begging to be asked is why are you storing them without the extensions? It would be easier to strip off the extension if you need to than it is try and find the file without the extension
I want get uploaded image extension.
As I know, best way is getimagesize() function.
but this function's mime, returns image/jpeg when image has .jpg or also .JPEG extension.
How can get exactly extension?
$ext = pathinfo($filename, PATHINFO_EXTENSION);
you can use image_type_to_extension function with image type returned by getimagesize:
$info = getimagesize($path);
$extension = image_type_to_extension($info[2]);
You can also use strrpos and substr functions to get extension of any file
$filePath="images/ajax-loader.gif";
$type=substr($filePath,strrpos($filePath,'.')+1);
echo "file type=".$type;
output: gif
if you want extension like .gif
$type=substr($filePath,strrpos($filePath,'.')+0);
output: .gif
$image = explode(".","test.file.hhh.kkk.jpg");
echo end($image);
One more way to do it:
$ext = strrchr($filename, "."); // .jpg
$file_ext = pathinfo($_FILES["file"]["name"], PATHINFO_EXTENSION);
or to make it clean
$filename= $_FILES["file"]["name"];
$file_ext = pathinfo($filename,PATHINFO_EXTENSION);
You can also explode the file name with dots and take the end of the array as follows:
$ext = end(explode('.', 'image.name.gif'));
According to: Two different ways to find file extension in PHP
And a new way for you lol:
$ext = explode('.', 'file.name.lol.lolz.jpg');
echo $ext[count($ext) - 1];
For those who want to check if image type is JPEG, PNG or etc. You can use exif_imagetype function. This function reads the first bytes of an image and checks its signature. Here is a simple example from php.net:
<?php
if (exif_imagetype('image.gif') != IMAGETYPE_GIF) {
echo 'The picture is not a gif';
}
?>
$size = getimagesize($filename);
$ext = explode('/', $size['mime'])[1];
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.
I have an image file name without extension (lets assume it is image_file_name - NOTE IT IS MISSING THE EXTENSION) and I also know the file type (lets assume the file type is image/jpeg). Now is there a php function that returns the file extension given its type? As explained in the following pseudo code:
$extension = get_extension('image/jpeg'); // Will return 'jpg'
$file_name = 'image_file_name' . '.' . $extension; // Will result in $file_name = image_file_name.jpg
Please note that the image above was only an example, the file name could be of any file type, such as a web page file name or anything else. and the extension could be anything as well, it could be html, css ...etc.
Is it possible to do the above? And how?
$ext = substr(image_type_to_extension(exif_imagetype('dev.png')), 1); //example png
This will give you the extension correctly and is more reliable than $_FILE['image']['type'].
You can use finfo to perform mime-magic to determine the file type.
$finfo = finfo_open(FILEINFO_MIME, "/path/to/mimiemagic.file");
$res = $finfo->file($filename);
list($type, $encoding) = explode(";", $res);
$typeToExt = array(
"image/jpeg"=>"jpg",
"image/png"=>"png",
"text/html"=>"html",
"text/plain"=>"txt",
"audio/mpeg"=>"mp3",
"video/mpeg"=>"mpg"
);
$ext = $typeToExt[$type];
You can use FILEINFO_MIME directly to determine MIME type and then use a switch case to add extension. There is this mime_content_type(), but it seems deprecated.
$finfo = new FileInfo(null, 'image_file_name');
// Determine the MIME type of the uploaded file
switch ($finfo->file($_FILES['image']['tmp_name'], FILEINFO_MIME) {
case 'image/jpg':
$extension = 'jpg'
$file_name = 'image_file_name' . '.' . $extension;
break;
case 'image/png':
$extension = 'png'
$file_name = 'image_file_name' . '.' . $extension;
break;
case 'image/gif':
$extension = 'gif'
$file_name = 'image_file_name' . '.' . $extension;
break;
}
For more extensions, keep adding cases to switch.
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!!!!!!!!!