Загрузка файла с помощью 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

Как вы служите этому? Как вы его вызываете? В этом вопросе фактически отсутствует минимальный воспроизводимый пример , что делает невозможным ответ. Я также не вижу места, где файл сохраняется. Пожалуйста, как новый пользователь здесь, также пройдите тур и прочитайте Как спросить.

Ulrich Eckhardt 18.11.2022 18:11

Вы не хотите 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
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
Тенденции развития PHP - почему люди выбирают его?
Тенденции развития PHP - почему люди выбирают его?
Framework ранее был известен как Personal Home Page, а затем был переименован в Hypertext Preprocessor. Это наиболее широко используемый язык для...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
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

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