Check if a file is archive (zip or rar) using php
The fileinfo functions should help you with this, by checking the file's mime type:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, $filename); // This will return the mime-type
finfo_close($finfo);
You could output the info from unix file command and parse it(assuming you can execute system commands, which is bad practice).
This is example of centos "file filename" output.
[rr@localhost images] (master)# file ui-anim_basic_16x16.gif ui-anim_basic_16x16.gif: GIF image data, version 89a, 16 x 16
[rr@localhost images] (master)# file ui-icons_454545_256x240.png ui-icons_454545_256x240.png: PNG image data, 256 x 240, 8-bit colormap, non-interlaced
[rr@localhost vendors] (master)# file jquery-validation-1.9.0.zip jquery-validation-1.9.0.zip: Zip archive data, at least v1.0 to extract
also like other people suggested, you could read few bytes and check if they match signature.
for rar
Identifying characters Hex: 52 61 72 21 1A 07 00 , ASCII: Rar!
for zip
Identifying characters Hex: 50 4B 03 04 , ASCII: PK
Output from od -c
:
0000000 R a r ! 032 \a \0 317 220 s \0 \0 \r \0 \0 \0
0000000 P K 003 004 \n \0 \0 \0 \0 \0 \0 \0 ! \0 \0 \0
You could use something like this:
<?php
$fh = @fopen($argv[1], "r");
if (!$fh) {
print "ERROR: couldn't open file.\n";
exit(126);
}
$blob = fgets($fh, 5);
fclose($fh);
if (strpos($blob, 'Rar') !== false) {
print "Looks like a Rar.\n";
} else
if (strpos($blob, 'PK') !== false) {
print "Looks like a ZIP.\n";
} else {
print "I dunno.\n";
exit(1);
}
?>
And my output:
ghoti@baz:~ 423$ ./filephp.php A2.rar
Looks like a Rar.
ghoti@baz:~ 424$ ./filephp.php OLDIE.zip
Looks like a ZIP.
ghoti@baz:~ 425$ ./filephp.php 1-11-1.PDF
I dunno.
ghoti@baz:~ 426$
To test whether a file is a zip archive, you can attempt to open it as a zip using open_zip
function. For rar, you need to have PECL rar (preferably version at least 2.0.0) installed - see http://php.net/manual/en/book.rar.php for more details. The code could look like this:
if(is_resource($zip = zip_open($filename)))
{
zip_close($zip);
//this is a zip archive
}
elseif(($rar = RarArchive::open($filename)) !== FALSE)
{
$rar->close();
//this is a rar archive
}
else
{
//this is not a zip or rar archive
}
You may need to do a bit extra work if the archives are password-protected. Read the corresponding php manual pages for more details.