Я розробляю простий скрипт завантаження php, і користувачі можуть завантажувати лише ZIP-файли та файли RAR.
Які типи MIME я повинен використовувати для перевірки $_FILES[x][type]
? (повний список, будь ласка)
Дякую..
Я розробляю простий скрипт завантаження php, і користувачі можуть завантажувати лише ZIP-файли та файли RAR.
Які типи MIME я повинен використовувати для перевірки $_FILES[x][type]
? (повний список, будь ласка)
Дякую..
Відповіді:
Відповіді Freedompeace, Кіяраш та Сем Влобергс:
.rar application/x-rar-compressed, application/octet-stream
.zip application/zip, application/octet-stream, application/x-zip-compressed, multipart/x-zip
Я б також перевірив ім'я файлу. Ось як ви могли перевірити, чи файл є файлом RAR або ZIP. Я перевірив це, створивши швидкий додаток командного рядка.
<?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;
}
Зауважте, що це все одно не буде на 100% впевненим, але це, мабуть, досить добре.
$ rar.exe l somefile.zip
somefile.zip is not RAR archive
Але навіть WinRAR виявляє не RAR-файли як архіви SFX:
$ rar.exe l somefile.srr
SFX Volume somefile.srr
application/x-zip-compressed
zip
або rar
файл. Згідно специфікації WC3 це буде intrepreted як: «Я вважаю за краще application/zip
| application/x-rar-compressed
тип контенту, але якщо ви не можете поставити чи це application/octet-stream
(файловий потік) також добре».
multipart/x-zip
б бути дійсним? Це не багатоскладова. Список SitePoint містить безліч неточних типів MIME і далеко не повний. Офіційний реєстр медіа-типів IANA не є (і це, швидше за все, не буде) на 100% заповнений.
Офіційний перелік типів мімів можна знайти в Інтернеті, призначеному для числення (IANA) . Відповідно до їх списку Content-Type
заголовок для zip
є application/zip
.
Тип носія для rar
файлів офіційно не зареєстрований в IANA, але неофіційне загальновживане значення mime application/x-rar-compressed
.
application/octet-stream
означає стільки ж, скільки: "Я надсилаю вам файловий потік, а вміст цього потоку не вказаний" (так це правда, що він може бути zip
або rar
файлом). Сервер повинен виявити, який фактичний вміст потоку.
Примітка. Для завантаження не безпечно покладатися на тип mime, встановлений у Content-Type
заголовку. Заголовок встановлюється на клієнті і може бути встановлений на будь-яке випадкове значення. Натомість ви можете використовувати інформаційні функції файлу php для виявлення файлу mime-типу на сервері.
Якщо ви хочете завантажити zip
файл і нічого іншого, вам слід встановити лише одне Accept
значення заголовка. Будь-які додаткові встановлені значення будуть використані як резервний випадок, якщо сервер не зможе задовольнити ваш Accept
запит mime-типу в заголовку.
Відповідно до специфікацій WC3 це:
application/zip, application/octet-stream
буде інтерпретовано як: "Я віддаю перевагу типу application/zip
mime, але якщо ви не можете доставити це application/octet-stream
(файловий потік), також добре".
Отже, лише один:
application/zip
Гарантує вам zip
файл (або 406 - Not Acceptable
відповідь у випадку, якщо сервер не зможе задовольнити ваш запит).
Ви не повинні довіряти $_FILES['upfile']['mime']
, перевірте тип MIME самостійно. З цією метою ви можете використовувати fileinfo
розширення , включене за замовчуванням з 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.');
ПРИМІТКА. Не забудьте ввімкнути розширення у php.ini
своєму сервері та перезапустити сервер:
extension=php_fileinfo.dll
У пов'язаному запитанні є код Objective-C для отримання типу mime для URL-адреси файлу. Я створив розширення Swift на основі коду Objective-C, щоб отримати тип 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
}
}
Оскільки розширення може містити більше або менше трьох символів, наступне перевірятиме розширення незалежно від його довжини.
Спробуйте це:
$allowedExtensions = array( 'mkv', 'mp3', 'flac' );
$temp = explode(".", $_FILES[$file]["name"]);
$extension = strtolower(end($temp));
if( in_array( $extension, $allowedExtensions ) ) { ///
щоб перевірити наявність усіх символів після останнього '.'