前不久在逛论坛时看到一些朋友询问在写文件上传服务时如何判断用户上传的文件是不是自己不允许的文件类型,有很多热心的网友给出了解决方法,但其中9成以上的人都是说通过读取文件的后缀名来确定,这中方法也可以实现,但很拙劣,因为任何一个服务的使用者都可以通过修改后缀名的方法成功的把文件上传到服务器上。
在回答者里只有极小部分的人说可以通过读取头文件来判断,我个人认为这是最好的方法,但没有人给出程序的实现。下面我(z.En:http://blog.youkuaiyun.com/zenwong)就给出使用PHP进行头文件判断文件类型的实现方法。
首先描述一下原理:
想判断一个文件是不是服务允许的文件类型就要先去研究一下他们的头文件,下面用图片文件做例子进行描述。
如果一个服务只允许用户上传JPG,GIF或BMP的图片,那么你可以使用UltraEdit打开他,并采用16进制查看。
现在查看头几行右边的16个字符,也就是“;”右边的那些字符,其中有一些是无法显示的,不要去管他。在其中寻找每个同类型的文件在其中的共同点。
如果是JPG图片的话,他的第一行的第6位到第9位(坐标从0开始)的字符一定是“JFIF”,无论你如何该文件的后缀名,这个“JFIF”都是不会变的。
如果是GIF图片的话,他的第一行的第0位到第2位(坐标从0开始)的字符一定是“GIF”。
如果是BMP图片的话,他的第一行的第0位到第1位(坐标从0开始)的字符一定是“BM”。
如果你的服务允许上传的是别的一些类型的文件的话,可以准备两个这种文件,但不要是用同一个文件复制粘贴的,而是两个完全不同只有类型(不是后缀名)相同的文件,然后打开UltraEdit使用其中的“比较文件”功能把这两个文件进行比较,就可以找到他们的头文件的相同之处,注意:一定要找头文件的相同之处,最好是第一行,别的地方都不可以。
这样就实现了通过头文件来判断文件类型的方法。
下面是用PHP进行的实现代码,其实用任何一种语言都可以实现:
- <?php
- // 要读取的文件的路径
- $file_name = "1.jpg";
- // 打开文件
- $file_pointer = fopen($file_name, "r");
- // 通过文件指针读取指定字节的文件内容
- $file_read = fread($file_pointer, 10);
- // 关闭文件
- fclose($file_pointer);
- // 显示内容
- print "读取到的文件头的前10个字节的内容是: $file_read <BR/>";
- //判断文件类型
- if (strtoupper(substr($file_read,6,4))=='JFIF') {
- print 'JPG图片';
- }elseif (strtoupper(substr($file_read,0,3))=='GIF'){
- print 'GIF图片';
- }elseif (strtoupper(substr($file_read,0,2))=='BM'){
- print 'BMP图片';
- }else {
- print '不是JPG,GIF或BMP图片';
- }
- ?>
(z.En原创文章,转载请注明作者及源地址)
END