读取文件头

PHP 读取文件头

在上传文件中时需要判断文件类型,严谨的一种做法就是通过读取文件头来确定文件类型。下面就是读取几种常用文件的头信息.

读取JPEG文件

$file = 'example.jpg';
$fp = fopen($file, 'rb');
$header = fread($fp, 2); // 读取前2字节
fclose($fp);
if (bin2hex($header) == "ffd8")  {
    // 是JPEG文件
}

也可以通过getimagesize来确定是不是图片.

读取ZIP文件

<?php
$file = 'example.zip';
$fp = fopen($file, 'rb');
$header = fread($fp, 4); // 读取前4字节
fclose($fp);
if (bin2hex($header) === '504b0304') {
    // 是ZIP文件
}

读取Word文件

<?php
$file = 'example.docx';
$fp = fopen($file, 'rb');
$header = fread($fp, 4);
fclose($fp);
$hex = bin2hex($header);
if ($hex === 'd0cf11e0') {
    // 是老版 Word (doc) 文件
} elseif ($hex === '504b0304') {
    // 是新版 Word (docx) 文件
}

读取Excel文件

<?php
$file = 'example.xlsx';
$fp = fopen($file, 'rb');
$header = fread($fp, 4);
fclose($fp);
$hex = bin2hex($header);
if ($hex === 'd0cf11e0') {
    // 是老版 Excel (xls) 文件
} elseif ($hex === '504b0304') {
    // 是新版 Excel (xlsx) 文件
}

读取RAR文件

<?php
$file = 'example.rar';
$fp = fopen($file, 'rb');
$header = fread($fp, 8); // 读取前8字节
fclose($fp);
$hex = bin2hex($header);
if (strpos($hex, '526172211a07') === 0) {
    // 是RAR文件(可进一步判断07 00是RAR4,07 01 00是RAR5)
}

读取PNG文件

<?php
$file = 'example.png';
$fp = fopen($file, 'rb');
$header = fread($fp, 8); // 读取前8字节
fclose($fp);
if (bin2hex($header) === '89504e470d0a1a0a') {
    // 是PNG文件
}

读取GIF文件

<?php
$file = 'example.gif';
$fp = fopen($file, 'rb');
$header = fread($fp, 6); // 读取前6字节
fclose($fp);
if ($header === "GIF87a" || $header === "GIF89a") {
    // 是GIF文件
}

读取MP3文件

<?php
$file = 'example.mp3';
$fp = fopen($file, 'rb');
$header = fread($fp, 3); // 读取前3字节
fclose($fp);
if ($header === "ID3") {
    // 有ID3标签的MP3文件
} else {
    // 可能是无标签的MP3,需进一步判断帧头
    $fp = fopen($file, 'rb');
    $header2 = fread($fp, 2);
    fclose($fp);
    if (bin2hex($header2) === 'fffb' || bin2hex($header2) === 'fff3' || bin2hex($header2) === 'fff2') {
        // 可能是MP3文件
    }
}

读取MP4文件

<?php
$file = 'example.mp4';
$fp = fopen($file, 'rb');
fseek($fp, 4); // 跳过前4字节长度
$ftyp = fread($fp, 4);
fclose($fp);
if ($ftyp === 'ftyp') {
    // 是MP4文件
}

读取FLV文件

<?php
$file = 'example.flv';
$fp = fopen($file, 'rb');
$header = fread($fp, 3); // 读取前3字节
fclose($fp);
if ($header === "FLV") {
    // 是FLV文件
}

读取PDF文件

$file = 'example.pdf';
$fp = fopen($file, 'rb');
$header = fread($fp, 4); // 读取前4字节
fclose($fp);
if ($header === "%PDF") {
    // 是PDF文件
}

读取PPT文件

$file = 'example.pptx';
$fp = fopen($file, 'rb');
$header = fread($fp, 4);
fclose($fp);
$hex = bin2hex($header);
if ($hex === 'd0cf11e0') {
    // 是老版 PPT (ppt) 文件
} elseif ($hex === '504b0304') {
    // 是新版 PPT (pptx) 文件
}

读取BMP文件

$file = 'example.bmp';
$fp = fopen($file, 'rb');
$header = fread($fp, 2); // 读取前2字节
fclose($fp);
if ($header === "BM") {
    // 是BMP文件
}

读取TIFF文件

$file = 'example.tiff';
$fp = fopen($file, 'rb');
$header = fread($fp, 4); // 读取前4字节
fclose($fp);
$hex = bin2hex($header);
if ($hex === '49492a00' || $hex === '4d4d002a') {
    // 是TIFF文件
}

读取7z文件

$file = 'example.7z';
$fp = fopen($file, 'rb');
$header = fread($fp, 6); // 读取前6字节
fclose($fp);
if (bin2hex($header) === '377abcaf271c') {
    // 是7z文件
}

读取ELF文件

$file = 'example.elf';
$fp = fopen($file, 'rb');
$header = fread($fp, 4); // 读取前4字节
fclose($fp);
if (bin2hex($header) === '7f454c46') {
    // 是ELF可执行文件
}

读取PE文件(Windows EXE/DLL)

$file = 'example.exe';
$fp = fopen($file, 'rb');
$header = fread($fp, 2); // 读取前2字节
fclose($fp);
if ($header === "MZ") {
    // 是Windows可执行文件(EXE/DLL)
}

读取PDF/HTML/XML文件(文本类)

$file = 'example.html';
$fp = fopen($file, 'rb');
$header = fread($fp, 15); // 读取前15字节
fclose($fp);
if (stripos($header, '<!DOCTYPE') === 0 || stripos($header, '<html') === 0) {
    // 是HTML文件
}

$file = 'example.xml';
$fp = fopen($file, 'rb');
$header = fread($fp, 5); // 读取前5字节
fclose($fp);
if (stripos($header, '<?xml') === 0) {
    // 是XML文件
}