Check if a file is archive (zip or rar) using php

2020-08-11 13:43发布

How can i check if a file is archived (zip or rar) without knowing the extension. I need to find it using php.

I cannot use Fileinfo because its not installed and installation of any other packages on the server its out of the question.

UPDATE:

Zip module its not installed and i cannot install extra packages. I don't want to use mime_content_type because its deprecated

Thank you

标签: php
6条回答
混吃等死
2楼-- · 2020-08-11 13:49
<?php

function isZipFile($filepath){
    $fh = fopen($filepath,'r');
    $bytes = fread($fh,4);
    fclose($fh);
    return ('504b0304' === bin2hex($bytes));
}

Thanks to flu for the helpful link to the zip file specification.

查看更多
【Aperson】
3楼-- · 2020-08-11 13:50

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
}
else(($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.

查看更多
三岁会撩人
4楼-- · 2020-08-11 13:55

Read first 10 bytes of the file. If they are (80, 75, 3, 4, 20, 0, 0, 0, 8, 0) it is a ZIP file. RAR files have the following 7 first bytes: (82, 97, 114, 33, 26, 7, 0) If you open a ZIP file in a text editor (for instance, Notepad++) you will see: PK[ETX][EOT][DC4][NUL][NUL][NUL][BS][NUL]....-> the Ascii codes for the characters are listed above. For the RAR files the picture is: Rar![SUB][BEL][NUL].... So, just read the 10 first bytes of a file and you can tell if it is ZIP or RAR archive. Cheers

查看更多
forever°为你锁心
5楼-- · 2020-08-11 14:01

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);
查看更多
6楼-- · 2020-08-11 14:04

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$ 
查看更多
Summer. ? 凉城
7楼-- · 2020-08-11 14:12

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

查看更多
登录 后发表回答