Tôi đang phát triển một tập lệnh tải lên php đơn giản và người dùng chỉ có thể tải lên các tệp ZIP và RAR.
Những loại MIME nào tôi nên sử dụng để kiểm tra $_FILES[x][type]
? (một danh sách đầy đủ xin vui lòng)
Cảm ơn bạn..
Tôi đang phát triển một tập lệnh tải lên php đơn giản và người dùng chỉ có thể tải lên các tệp ZIP và RAR.
Những loại MIME nào tôi nên sử dụng để kiểm tra $_FILES[x][type]
? (một danh sách đầy đủ xin vui lòng)
Cảm ơn bạn..
Câu trả lời:
Câu trả lời từ freedompeace, Kiyarash và Sam Vloeberghs:
.rar application/x-rar-compressed, application/octet-stream
.zip application/zip, application/octet-stream, application/x-zip-compressed, multipart/x-zip
Tôi cũng sẽ kiểm tra tên tập tin. Đây là cách bạn có thể kiểm tra xem tệp là tệp RAR hay ZIP. Tôi đã thử nghiệm nó bằng cách tạo ra một ứng dụng dòng lệnh nhanh.
<?php
if (isRarOrZip($argv[1])) {
echo 'It is probably a RAR or ZIP file.';
} else {
echo 'It is probably not a RAR or ZIP file.';
}
function isRarOrZip($file) {
// get the first 7 bytes
$bytes = file_get_contents($file, FALSE, NULL, 0, 7);
$ext = strtolower(substr($file, - 4));
// RAR magic number: Rar!\x1A\x07\x00
// http://en.wikipedia.org/wiki/RAR
if ($ext == '.rar' and bin2hex($bytes) == '526172211a0700') {
return TRUE;
}
// ZIP magic number: none, though PK\003\004, PK\005\006 (empty archive),
// or PK\007\008 (spanned archive) are common.
// http://en.wikipedia.org/wiki/ZIP_(file_format)
if ($ext == '.zip' and substr($bytes, 0, 2) == 'PK') {
return TRUE;
}
return FALSE;
}
Lưu ý rằng nó vẫn không chắc chắn 100%, nhưng có lẽ nó đủ tốt.
$ rar.exe l somefile.zip
somefile.zip is not RAR archive
Nhưng ngay cả WinRAR cũng phát hiện các tệp không phải RAR dưới dạng lưu trữ SFX:
$ rar.exe l somefile.srr
SFX Volume somefile.srr
application/x-zip-compressed
zip
hoặc rar
tập tin nào cả. Theo thông số kỹ thuật của WC3, điều này sẽ được thể hiện dưới dạng: "Tôi thích loại application/zip
| application/x-rar-compressed
nội dung, nhưng nếu bạn không thể cung cấp thì application/octet-stream
(luồng tệp) cũng ổn".
multipart/x-zip
thể có giá trị? Nó không phải là đa phần. Danh sách SitePoint chứa nhiều loại MIME không chính xác và chưa hoàn thành. Sổ đăng ký loại IANA Media chính thức không (cũng có thể sẽ không hoàn thành) 100%.
Một danh sách chính thức của các loại mime có thể được tìm thấy tại Cơ quan cấp số được gán Internet (IANA) . Theo Content-Type
tiêu đề danh sách của họ zip
là application/zip
.
Loại phương tiện cho rar
các tệp không được đăng ký chính thức tại IANA nhưng giá trị loại mime không chính thức thường được sử dụng là application/x-rar-compressed
.
application/octet-stream
có nghĩa là nhiều như: "Tôi gửi cho bạn một luồng tệp và nội dung của luồng này không được chỉ định" (vì vậy đúng là nó cũng có thể là một tệp zip
hoặc rar
tệp). Máy chủ có nhiệm vụ phát hiện nội dung thực sự của luồng là gì.
Lưu ý: Để tải lên, không an toàn khi dựa vào loại mime được đặt trong Content-Type
tiêu đề. Tiêu đề được đặt trên máy khách và có thể được đặt thành bất kỳ giá trị ngẫu nhiên nào. Thay vào đó, bạn có thể sử dụng các hàm thông tin tệp php để phát hiện loại mime loại tệp trên máy chủ.
Nếu bạn muốn tải xuống một zip
tệp và không có gì khác, bạn chỉ nên đặt một Accept
giá trị tiêu đề duy nhất . Bất kỳ giá trị bổ sung nào sẽ được sử dụng làm dự phòng trong trường hợp máy chủ không thể đáp ứng Accept
tiêu đề của bạn trong loại mime được yêu cầu.
Theo thông số kỹ thuật WC3 này:
application/zip, application/octet-stream
sẽ được mô tả như sau: "Tôi thích loại application/zip
mime, nhưng nếu bạn không thể cung cấp cái này thì application/octet-stream
(một luồng tệp) cũng ổn".
Vì vậy, chỉ có một duy nhất:
application/zip
Sẽ đảm bảo cho bạn một zip
tệp (hoặc 406 - Not Acceptable
phản hồi trong trường hợp máy chủ không thể đáp ứng yêu cầu của bạn).
Bạn không nên tin tưởng $_FILES['upfile']['mime']
, hãy tự kiểm tra loại MIME. Với mục đích đó, bạn có thể sử dụng fileinfo
tiện ích mở rộng , được bật theo mặc định kể từ phiên bản PHP 5.3.0.
$fileInfo = new finfo(FILEINFO_MIME_TYPE);
$fileMime = $fileInfo->file($_FILES['upfile']['tmp_name']);
$validMimes = array(
'zip' => 'application/zip',
'rar' => 'application/x-rar',
);
$fileExt = array_search($fileMime, $validMimes, true);
if($fileExt != 'zip' && $fileExt != 'rar')
throw new RuntimeException('Invalid file format.');
LƯU Ý: Đừng quên bật tiện ích mở rộng trong php.ini
và khởi động lại máy chủ của bạn:
extension=php_fileinfo.dll
Trong một câu hỏi được liên kết , có một số mã Objective-C để lấy loại mime cho một URL tệp. Tôi đã tạo tiện ích mở rộng Swift dựa trên mã Objective-C đó để lấy loại mime:
import Foundation
import MobileCoreServices
extension URL {
var mimeType: String? {
guard self.pathExtension.count != 0 else {
return nil
}
let pathExtension = self.pathExtension as CFString
if let preferredIdentifier = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil) {
guard let mimeType = UTTypeCopyPreferredTagWithClass(preferredIdentifier.takeRetainedValue(), kUTTagClassMIMEType) else {
return nil
}
return mimeType.takeRetainedValue() as String
}
return nil
}
}
Vì tiện ích mở rộng có thể chứa nhiều hơn hoặc ít hơn ba ký tự sau đây sẽ kiểm tra tiện ích mở rộng bất kể độ dài của nó.
Thử cái này:
$allowedExtensions = array( 'mkv', 'mp3', 'flac' );
$temp = explode(".", $_FILES[$file]["name"]);
$extension = strtolower(end($temp));
if( in_array( $extension, $allowedExtensions ) ) { ///
để kiểm tra tất cả các ký tự sau '.' cuối cùng