Я создал файл download.php на своем сервере vps, в котором есть несколько изображений. Если пользователи запрашивают файл с помощью этого файла, файл сохраняется на устройствах. Но это создает пустой файл. Это код.
<?php
if (isset($_GET['file']))
{
$filename = $_GET["file"];
if (preg_match('/^[^.][-a-z0-9_.]+[a-z]$/i', $file)){
$filepath = "images/" . $file;
if (file_exists($filepath)) {
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$filename."\"");
readfile($filepath);
}
}
?>
Я исправил опечатки и удалил эхо, все так же, файл загружается, когда download.php?file=abstract.jpg вызывается на сервере.
Как вы служите этому? Как вы его вызываете? В этом вопросе фактически отсутствует минимальный воспроизводимый пример , что делает невозможным ответ. Я также не вижу места, где файл сохраняется. Пожалуйста, как новый пользователь здесь, также пройдите тур и прочитайте Как спросить.
Вы не хотите echo readfile. Оно отзывается само по себе.
Также обратите внимание, что вы не должны echo readfile(), просто сделайте readfile() саму по себе, так как это уже выгружает файл в выходной буфер. Вызывая также echo, вы выводите дополнительную информацию, в данном случае возвращаемое значение readfile(), которое представляет собой количество выводимых байтов.
Я предполагаю, что цель регулярного выражения - сопоставить имя файла с расширением, но это не так. Финал [a-z] стоит в единственном числе, то есть строка должна заканчиваться одним символом. Это избыточно, потому что класс символов перед этим уже определяет один или несколько таких же символов. abstract.jpg соответствует, но также abstract, а также abs и a.b, вещи, которые не похожи на имена файлов с расширениями. Не изобретайте велосипед, здесь наверняка много вопросов с примерами регулярных выражений для сопоставления имен файлов.
В вашем коде все еще есть пара ошибок:
Для вашего начального блока if нет закрывающих скобок
Ваш preg_match - вы передаете ему переменную $file, которая не была объявлена. Я думаю, вы имеете в виду передать $filename. Если я не ошибаюсь, ваш код продолжается, потому что preg_match не возвращает false.
Вы также передаете $file для создания переменной $filepath, так что опять же, он просто пытается загрузить images/ вместо полного пути.
Этот код работает:
<?php
if (isset($_GET['file']))
{
$filename = $_GET["file"];
if (preg_match('/^[^.][-a-z0-9_.]+[a-z]$/i', $filename)){
$filepath = "images/" . $filename;
if (file_exists($filepath)) {
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$filename."\"");
readfile($filepath);
}
}
}
Спасибо, это сработало. Что установить header content type для файлов mp4? Пробовал header("Content-Type: video/mp4");, но бесполезно.
Поищите в Интернете типы MIME — video/mp4 является допустимым типом MIME, поэтому, если он у вас не работает, возможно, исходный файл имеет определенный кодек или что-то в этом роде, я не уверен. Невозможно сказать, не имея возможности проанализировать исходный файл.
Опечатка, дополнительное подчеркивание: readfile($filepath);