Загрузка файла с помощью PHP сохраняет пустой файл

Я создал файл 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 вызывается на сервере.

Опечатка, дополнительное подчеркивание: readfile($filepath);

Alex Howansky 18.11.2022 18:10

Вы не хотите echo readfile. Оно отзывается само по себе.

ceejayoz 18.11.2022 18:12

Также обратите внимание, что вы не должны echo readfile(), просто сделайте readfile() саму по себе, так как это уже выгружает файл в выходной буфер. Вызывая также echo, вы выводите дополнительную информацию, в данном случае возвращаемое значение readfile(), которое представляет собой количество выводимых байтов.

Alex Howansky 18.11.2022 18:13

Я предполагаю, что цель регулярного выражения - сопоставить имя файла с расширением, но это не так. Финал [a-z] стоит в единственном числе, то есть строка должна заканчиваться одним символом. Это избыточно, потому что класс символов перед этим уже определяет один или несколько таких же символов. abstract.jpg соответствует, но также abstract, а также abs и a.b, вещи, которые не похожи на имена файлов с расширениями. Не изобретайте велосипед, здесь наверняка много вопросов с примерами регулярных выражений для сопоставления имен файлов.

Don't Panic 18.11.2022 23:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
5
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде все еще есть пара ошибок:

  1. Для вашего начального блока if нет закрывающих скобок

  2. Ваш preg_match - вы передаете ему переменную $file, которая не была объявлена. Я думаю, вы имеете в виду передать $filename. Если я не ошибаюсь, ваш код продолжается, потому что preg_match не возвращает false.

  3. Вы также передаете $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");, но бесполезно.

brvnbld 19.11.2022 03:45

Поищите в Интернете типы MIME — video/mp4 является допустимым типом MIME, поэтому, если он у вас не работает, возможно, исходный файл имеет определенный кодек или что-то в этом роде, я не уверен. Невозможно сказать, не имея возможности проанализировать исходный файл.

Jonathan Nathanson 19.11.2022 10:54

Другие вопросы по теме