Tworzę prosty skrypt do wysyłania php, a użytkownicy mogą przesyłać tylko pliki ZIP i RAR.
Jakich typów MIME należy używać do sprawdzania $_FILES[x][type]
? (proszę o pełną listę)
Dziękuję Ci..
Tworzę prosty skrypt do wysyłania php, a użytkownicy mogą przesyłać tylko pliki ZIP i RAR.
Jakich typów MIME należy używać do sprawdzania $_FILES[x][type]
? (proszę o pełną listę)
Dziękuję Ci..
Odpowiedzi:
Odpowiedzi udzielone przez freedompeace, Kiyarash i Sam Vloeberghs:
.rar application/x-rar-compressed, application/octet-stream
.zip application/zip, application/octet-stream, application/x-zip-compressed, multipart/x-zip
Sprawdziłbym też nazwę pliku. Oto, jak możesz sprawdzić, czy plik jest plikiem RAR lub ZIP. Przetestowałem to, tworząc szybką aplikację wiersza poleceń.
<?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;
}
Zauważ, że nadal nie będzie to w 100% pewne, ale prawdopodobnie jest wystarczająco dobre.
$ rar.exe l somefile.zip
somefile.zip is not RAR archive
Ale nawet WinRAR wykrywa pliki inne niż RAR jako archiwa SFX:
$ rar.exe l somefile.srr
SFX Volume somefile.srr
application/x-zip-compressed
zip
ani rar
pliku. Według specyfikacji WC3 to będzie intrepreted jak: „Wolę application/zip
| application/x-rar-compressed
typ zawartości, ale jeśli nie można dostarczyć to jako application/octet-stream
(strumień pliku) też jest w porządku”.
multipart/x-zip
być ważny? To nie jest wieloczęściowe. Lista SitePoint zawiera wiele niedokładnych typów MIME i jest daleka od ukończenia. Oficjalny rejestr IANA Media Types nie jest (i prawdopodobnie nigdy nie będzie) kompletny w 100%.
Oficjalną listę typów mime można znaleźć na stronie The Internet Assigned Numbers Authority (IANA) . Zgodnie z ich Content-Type
nagłówkiem listy dla zip
is application/zip
.
Typ mediów dla rar
plików nie jest oficjalnie zarejestrowany w IANA, ale nieoficjalna powszechnie używana wartość typu MIME to application/x-rar-compressed
.
application/octet-stream
znaczy tyle co: „Wysyłam Ci strumień plików, a zawartość tego strumienia nie jest określona” (więc prawdą jest, że może to być również plik zip
lub rar
). Serwer ma wykryć, jaka jest rzeczywista zawartość strumienia.
Uwaga: przy przesyłaniu nie można polegać na typie MIME ustawionym w Content-Type
nagłówku. Nagłówek jest ustawiany na kliencie i może mieć dowolną losową wartość. Zamiast tego możesz użyć funkcji informacji o pliku php, aby wykryć typ MIME pliku na serwerze.
Jeśli chcesz pobrać zip
plik i nic więcej, ustaw tylko jedną Accept
wartość nagłówka. Wszelkie dodatkowe ustawione wartości będą używane jako rezerwowe na wypadek, gdyby serwer nie mógł spełnić Accept
żądanego typu MIME w nagłówku.
Zgodnie ze specyfikacją WC3 :
application/zip, application/octet-stream
zostanie zinterpretowane jako: "Wolę application/zip
typ MIME, ale jeśli nie możesz tego dostarczyć, application/octet-stream
(strumień plików) też jest w porządku".
Więc tylko jeden:
application/zip
Zagwarantuje Ci zip
plik (lub 406 - Not Acceptable
odpowiedź na wypadek, gdyby serwer nie mógł spełnić Twojego żądania).
Nie powinieneś ufać $_FILES['upfile']['mime']
, sam sprawdź typ MIME. W tym celu możesz użyć fileinfo
rozszerzenia , które jest domyślnie włączone od 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.');
UWAGA: Nie zapomnij włączyć rozszerzenia w swoim php.ini
i zrestartować serwer:
extension=php_fileinfo.dll
W pytaniu połączonym jest kod Objective-C, aby pobrać typ MIME dla adresu URL pliku. Utworzyłem rozszerzenie Swift na podstawie tego kodu Objective-C, aby uzyskać typ 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
}
}
Ponieważ rozszerzenie może zawierać mniej więcej trzy znaki, poniższe testy sprawdzą rozszerzenie niezależnie od jego długości.
Spróbuj tego:
$allowedExtensions = array( 'mkv', 'mp3', 'flac' );
$temp = explode(".", $_FILES[$file]["name"]);
$extension = strtolower(end($temp));
if( in_array( $extension, $allowedExtensions ) ) { ///
aby sprawdzić wszystkie znaki po ostatnim „.”