Я знаю (из ответа на этот вопрос: .rar, .zip files MIME Type ), что большинство людей проверяют zip-файлы в PHP как application/zip
или application/octet-stream
, но у меня есть несколько вопросов об этом:
application/octet-stream
(учитывая, что application/octet-stream
можно использовать для описания многих других типов файлов, чем просто zip!). Я знаю, что могу проверить файл и другими способами, но подумал, что я должен попытаться сохранить все как можно проще application/x-external-editor
, но у PHP есть проблемы с ним (хотя единственная ошибка, которую я получаю, это Warning: ZipArchive::close() [ziparchive.close]: Invalid or unitialized Zip object
) – это где-нибудь документировано? Есть ли список фактических x-
mimetypes, с которыми может справиться PHP? редактировать
В ответ на следующие вопросы:
$_FILES['fileatt']['type']
, но с использованием mime_content_type()
дает тот же результат. Различные zip-файлы выглядят как одно из следующих: 'application/zip'
, 'application/x-compressed'
, 'application/x-zip-compressed'
, 'application/x-compressed'
, 'multipart/x-zip'
. Я не понял, почему у меня возникла ошибка, когда тип mime был обнаружен как application/x-external-editor
. Я также нашел другую вещь, которую я не совсем понимаю: когда я использую следующий код с файлом, который PHP читает как application/x-external-editor
:
if($zip->open($_FILES[fileatt]['tmp_name'])===TRUE) { echo "success"; } else { echo "error"; }
печатает «ошибку», но проверяет тип файла как
$res = $zip->open($_FILES[fileatt]['tmp_name']); if($res) { echo "success"; } else { echo "error"; }
печатает «успех»; в этом коде я предполагаю, что логическое значение эффективно использует ==
, а не ===
, но почему это должно иметь значение?
Ошибка:
$res = $zip->open($_FILES[fileatt]['tmp_name']); if($res===TRUE) { echo "success"; } else { echo $res; }
печатает 19
– какая ошибка ( http://uk3.php.net/manual/en/ziparchive.open.php ) относится к ?!
Никогда не доверяйте типу mime, это может быть легко подделано клиентом. Они могли бы представить exe и дать ему тип mime text/plain
если захотят.
Все zip-файлы начинаются со стандартной сигнатуры заголовка локального файла (0x04034b50), поэтому вы можете проверить, что первые 4 байта файла соответствуют байтам подписи zip. Дополнительную информацию см. В PKZIP Appnote .
Если у вас включено расширение zip , вы можете пойти еще дальше и попытаться открыть и прочитать zip, чтобы убедиться, что это полностью действующий почтовый файл.
Что-то вроде этого хорошо работает:
$zip = zip_open('/path/to/file.zip'); if (is_int($zip)) { echo "Error $zip encountered reading the file, is it a valid zip?"; } else { echo "Thanks for uploading a valid zip file!"; }
zip_open
возвращает ресурс, если он открыт успешно, в противном случае целое число, представляющее ошибку, которая произошла при чтении файла.
РЕДАКТИРОВАТЬ: Поразмыслить над некоторыми из ваших вопросов:
О application/octet-stream
: это, как вы сказали, очень общий тип. Это означает, что любой файл, содержащий 8-битные данные, в основном это все и что угодно. application/zip
является стандартным типом mime-типа де-факто, но некоторые клиенты будут использовать другие значения, как вы обнаружили. Также, учитывая тот факт, что клиент может легко подделать любой тип файла для использования application/zip
я бы не стал полагаться на $_FILES['fileatt']['type']
поскольку это может быть что угодно.
AFIK, mime_content_type()
просто смотрит на расширение файла и сопоставляет его с типом mime из файла mime.types в системе или встроенным в PHP. Если кто-то поставил расширение .zip
в exe
файл, он все равно будет регистрироваться как application/zip
. Я верю, что некоторые расширения могут рассматривать заголовок файла.
Zip::open()
возвращает TRUE
если файл был успешно открыт, или целочисленный код ошибки. Следовательно, ==
даст вам ложный положительный результат при ошибке, потому что любое ненулевое целое будет оценивать значение true, используя ==
поскольку оно будет отличать ненулевое целое число с TRUE
. Если вы хотите проверить возврат из Zip::open
вы всегда должны использовать $res === true
, чтобы проверить успех. Вы можете найти значения кодов ошибок здесь в комментарии в нижней части страницы.
Bottom Line: Поскольку вы сказали, что вы уже извлекаете почтовый индекс, это может быть менее проблематичным для проверки на основе типа mime, но вместо этого было бы проще просто попытаться открыть файл и перейти на основе возвращаемого значения open
, Если он вернет true, вы можете увидеть, что файл является допустимым zip (в этом случае, возможно, будут ошибки в файле, но они, по крайней мере, загрузили что-то похожее на zip-файл).
Надеюсь, что это поможет тебе.