php better way to handle file extension [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to extract a file extension in PHP?
Get the file extension (basename?)
trying tot learn from other people´s code , I see a lot of methods to strip a filename from it´s extension, but most of the methods seems too localized as they assume a certain condition. for example :
This will assume only 3-character extension (like .txt, .jpg, .pdf)
substr($fileName, 0, -4);
or
substr($fileName, 0, strrpos($fileName, '.'));
But this can cause problems on file names like .jpeg, .tiff .html . or only 2 like .jsOr .pl
(browsing this list shows some file names can have only 1 character, and some as many as 10 (!) )
some other methods i have seen rely on the point (.)
for example :
return key(explode(“.”, $filename));
Can cause problems with filenames like 20121029.my.file.name.txt.jpg
same here :
return preg_replace('/\.[^.]*$/', '', $filename);
some people use the pathinfo($file) and / or basename() (is it ALWAYS safe ?? )
basename($filename);
and many many other methods ..
so my question has several parts :
what is the best way to "strip" a file extension ? (with the point)
what is the best way to "get" the file extension (without the point) and / or check it
will php own functions (basename) will recognize ALL extensions regardless of how exotic they might be or how the filename is constructed ?
what if any influence does the OS has on the matter ? (win, linux, unix...)
all those small sub-questions , which i would like to have an answer to can be summed-up in an overall single question :
Is there a bullet-proof , overall, always-work, fail-proof , best-practice , über_function that will work under all and any condition ??
EDIT I - another file extension list

Quoting from the duplicate question's top answer:
$ext = pathinfo($filename, PATHINFO_EXTENSION);
this is the best available way to go. It's provided by the operating system, and the best you can do. I know of no cases where it doesn't work.
One exception would be a file extension that contains a .. But no sane person would introduce a file extension like that, because it would break everywhere plus it would break the implicit convention.
for example in a file 20121021.my.file.name.txt.tar.gz - tar.gz would be the extention..
Nope, it's much simpler - and maybe that is the root of your worries. The extension of 20121021.my.file.name.txt.tar.gz is .gz. It is a gzipped .gz file for all intents and purposes. Only when you unzip it, it becomes a .tar file. Until then, the .tar in the file name is meaningless and serves only as information for the gunzip tool. There is no file extension named .tar.gz.
That said, detecting the file extension will not help you determine whether a file is actually of the type it claims. But I'm sure you know that, just putting this here for future readers.

Related

PHP PHAR having problems with filenames with multiple dots

I'm trying to extract some files out of a tar.gz file.
But the filename seems to cause problems:
xxx.some-random-number.tar.gz
When I use \PharData::isValidPharFilename('xxx.some-random-number.tar.gz', false) the function returns false. When I omit the first part (i.e. \PharData::isValidPharFilename('some-random-number.tar.gz', false) it returns true.
I can't use different filenames as they are provided from a third-party service (and I don't wanna rename them on the fly, either (tedious).
Any ideas how to solve this?
I believe the extension needs to be phar, tar or zip. I just answered a similar question here where I provided a bit more detail.

Use PHP to write a file to Windows that contains Japanese characters in the filename

I want to save a file to Windows using Japanese characters in the filename.
The PHP file is saved with UTF-8 encoding
<?php
$oldfile = "test.txt";
$newfile = "日本語.txt";
copy($oldfile,$newfile);
?>
The file copies, but appears in Windows as
日本語.txt
How do I make it save as
日本語.txt
?
I have ended up using the php-wfio extension from https://github.com/kenjiuno/php-wfio
After putting php_wfio.dll into php\ext folder and enabling the extension, I prefixed the filenames with wfio:// (both need to be prefixed or you get a Cannot rename a file across wrapper types error)
My test code ends up looking like
<?php
$oldfile = "wfio://test.txt";
$newfile = "wfio://日本語.txt";
copy($oldfile,$newfile);
?>
and the file gets saved in Windows as 日本語.txt which is what I was looking for
Starting with PHP 7.1, i would link you to this answer https://stackoverflow.com/a/38466772/3358424 . Unfortunately, the most of the recommendations are not valid, that are listed in the answer that strives to be the only correct one. Like "just urlencode the filename" or "FS expects iso-8859-1", etc. are terribly wrong assumptions that misinform people. That can work by luck but are only valid for US or almost western codepages, but are otherwise just wrong. PHP 7.1 + default_charset=UTF-8 is what you want. With earlier PHP versions, wfio or wrappers to ext/com_dotnet might be indeed helpful.
Thanks.

REAL basename vs PHP basename (pathinfo)

I've got for example a watermark file: ROOT.'/media/watermarks/1.jpg'.
In the future user can use (in some custom php template system) for example: 'watermark-filename', 'watermark-basename', , 'watermark-directory', etc to get needed data.
I'm trying to create some reasonable global variables names.
The question is, what does really 'basename' mean?
Terminal:
basename /path/to/source/file.ext -> "file"
PHP:
<?php
echo basename('/path/to/source/file.ext'); // file.ext
$path_parts = pathinfo('/path/to/source/file.ext');
echo $path_parts['basename']; // file.ext
?>
Wikipedia:
Many file systems, including FAT, NTFS, and VMS systems, allow a filename extension that consists of one or more characters following the last period in the filename, dividing the filename into two parts: a basename or stem and an extension or suffix used by some applications to indicate the file type.
I know Wikipedia is not a source, but according to my best knowledge, in operating systems
filename = file.ext
basename = file
extension = ext
While in php:
filename = file
basename = file.ext
extension = ext
Why?

Finding file without knowing the extension in PHP

I have a bunch of uniquely named images with different extensions, if I have one of the unique names, but I don't know the extension (it's an image extension), how can I find the image extension as fast as possible? I've seen other people doing this by searching all possible file extensions on that file name, but it seems too slow to try and load 6 different possible combinations before bringing up the original image.
Does anyone know an easier way?
You could use glob for this. Might not be the best solution but it is simple;
The glob() function searches for all the pathnames matching pattern
according to the rules used by the libc glob() function, which is
similar to the rules used by common shells.
$files = glob('filenamewithoutextension.*');
if (sizeof($files) > 0) {
$file = $files[0]; // Might be more than one hit however we are only interested in the first one?
}
After getting the filename you can use pathinfo to get the specific extension.
$extension = pathinfo($file, PATHINFO_EXTENSION);

Find files with certain name but variable file extension

I'd like to be able to select a file by just giving it's name (without extension). For example, I might have a variable $id holding 12. I want to be able to select a file called the-id-in-the-variable, say, 12.png from a directory, but it may have any one of a number of file extensions, listed below:
.swf
.png
.gif
.jpg
There is only one occurrence of each ID. I could use a loop and file_exists(), but is there a better way?
Thanks,
James
$matches = glob("12.*");
would return an array with all the matching filenames in the current directory. glob() works much the same as wildcard matching at the shell prompt.
Take a look at glob. Unfortunately, the exact semantics of the $pattern parameter is not described in the manual. But it seems your problem can be solved using this function.
Quick question to OP here:
What is the file extension of this file: somefile.tar.gz? Is it .gz or .tar.gz? :) I ask because most would answer this question as .tar.gz...

Categories