Php как скачать файл с сервера
Перейти к содержимому

Php как скачать файл с сервера

ftp_fget

ftp_fget() загружает файл remote_filename с FTP-сервера и записывает его в переданный файловый дескриптор.

Список параметров

Открытый файловый дескриптор, в который будут сохранены данные.

Путь к удалённому файлу.

Режим передачи. Должен быть либо FTP_ASCII , либо FTP_BINARY .

Позиция начала загрузки в удалённом файле.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Список изменений

Версия Описание
8.1.0 Параметр ftp теперь ожидает экземпляр FTP\Connection ; ранее ожидался ресурс (resource).
7.3.0 Теперь параметр mode опционален. Раньше он был обязательным.

Примеры

Пример #1 Пример использования ftp_fget()

// путь к удалённому файлу
$remote_file = ‘somefile.txt’ ;
$local_file = ‘localfile.txt’ ;

// открываем файл для записи
$handle = fopen ( $local_file , ‘w’ );

// установка соединения
$ftp = ftp_connect ( $ftp_server );

// вход с именем пользователя и паролем
$login_result = ftp_login ( $ftp , $ftp_user_name , $ftp_user_pass );

// пытаемся скачать файл и сохранить его в $handle
if ( ftp_fget ( $ftp , $handle , $remote_file , FTP_ASCII , 0 )) <
echo «Произведена запись в $local_file \n» ;
> else <
echo «При скачивании $remote_file в $local_file произошла проблема\n» ;
>

// закрытие соединения и локального файла
ftp_close ( $ftp );
fclose ( $handle );
?>

Смотрите также

  • ftp_get() — Скачивает файл с FTP-сервера
  • ftp_nb_get() — Скачивает файл с FTP-сервера в асинхронном режиме и сохраняет его в локальный файл
  • ftp_nb_fget() — Скачивает файл с FTP-сервера в асинхронном режиме и сохраняет его в предварительно открытом файле

User Contributed Notes 6 notes

Another ftp_get_contents approach, using a temperary stream handler. Returns file contents as string.

<?php
function ftp_get_contents ( $conn_id , $filename ,
//Create temp handler:
$tempHandle = fopen ( ‘php://temp’ , ‘r+’ );

//Get file from FTP assuming that it exists:
ftp_fget ( $conn_id , $tempHandle , $filename , FTP_ASCII , 0 ));

//Getting detailed stats to check filesize:
$fstats = fstat ( $tempHandle );

return fread ( $tempHandle , $fstats [ ‘size’ ]);
>
?>

<?php
/**
* Function returns contents via FTP connection and returns it as string (right version. )
*/
function ftp_get_contents ( $conn_id , $filename ) <
//Create temp handler:
$tempHandle = fopen ( ‘php://temp’ , ‘r+’ );

//Get file from FTP:
if (@ ftp_fget ( $conn_id , $tempHandle , $filename , FTP_ASCII , 0 )) <
rewind ( $tempHandle );
return stream_get_contents ( $tempHandle );
> else <
return false ;
>
>
?>

if you are using windows ftp-server with cp1251 encoding there are some troubles with russian «я» in filename\path.

php use telnet to connect ftp-server and there are special symbol with code 255 in telnet protocol. You can try use ftp_raw($connection, ‘OPTS UTF8 ON’); and work in utf-8 (if server provides it).

P.S. sorry for my bad english

I was in need to synchronize two folders on two separate servers, one is a Windows server, and the other is a Linux server. I created this short and sweet function to help me do this. PLEASE NOTICE: This will not copy folders, and probably will fail if remote folder contains anything else than files.

function sync_folders($host, $port, $username, $password, $remote_dir, $local_dir, $passive_mode = true) <
$conn_id = ftp_connect($host, $port);
if (!$conn_id) return false; # fail to connect
if (!ftp_login($conn_id, $username, $password)) < ftp_close($conn_id); return false; ># fail to login
ftp_pasv($conn_id, $passive_mode);
if (!ftp_chdir($conn_id, $remote_dir)) < ftp_close($conn_id); return false; ># fail to change dir
if (substr($local_dir, -1) != ‘/’) $local_dir .= ‘/’;

$list = ftp_nlist($conn_id, ‘.’);
sort($list);
foreach ($list as $file) <
if (!file_exists($local_dir . $file)) <
$is_copied = ftp_get($conn_id, $local_dir . $file, $file, FTP_BINARY);
>
>
ftp_close($conn_id);
return true;
>

Отдача файлов на скачивание PHP

В PHP отправка файла в браузер на скачивание осуществляется в 2 этапа:

Отправка заголовков

Первый вариант с явным указанием типа файла mime:

Второй, application/octet-stream – «двоичный файл без указания формата».

Заголовок с размером файла – header('Content-Length: ' . filesize($file)); можно не указывать.

Чтение и вывод файла

Перед отправкой файла нужно убедится что буферизация вывода отключена с помощью ob_get_level() или сбросить и отключить ее функцией ob_end_clean() .

PHP class для скачки и закачки файлов на сервер

В интернете есть много информации о том как скачивать файлы с сервера и загружать файлы на сервер, а также между серверами. Но нигде нет простого решения которое было бы более ли менее универсально.

Я несколько дней убил на изучение всяких заголовков и вариаций использования cUrl, но собрать все воедино не выходило. Видел много разных подобных классов, но везде было либо частичное решение, либо очень запутанно, либо и то, и другое.

И лишь благодаря единичным статьям, кусочкам информации с форумов и всяким комментариям удалось собрать пазл воедино. Я не утверждаю что мое решение полностью универсально, но очень удобное во многих случаях, хотя это вам решать.

Если у кого-либо возникнет желание улучшить мое решение этого вопроса и хватает знаний в этом направлении, то я буду рад, если вы сделаете какие-либо исправления или добавления к коду который лежит в открытом доступе на GitHub.

А теперь к делу, функции класса CargaDes:

  1. Отдача файла через браузер без показа его места хранения и с возможностью докачки;
  2. Загрузка файла на сервер через браузер с индикатором прогресса;
  3. Скачивание файлов с удаленного сервера на свой сервер с индикатором прогресса;
  4. Загрузка файлов со своего сервера на удаленный сервер с индикатором прогресса.

Для начала нужно скачать и подключить класс CargaDes:

1. Отдача файла через браузер без показа его места хранения с возможностью докачки и регулирования скорости

Этот метод очень похож на Drupal и иже с ним:

Я добавил еще отдачу с помощью Apache, но должна быть включена директива XSendFile On

Сразу после выполнения метода браузер выдаст окно для сохранения файла

2. Загрузка файла/ов на сервер через браузер с индикатором прогресса

После выполнения метода появится кнопка для выбора файлов и кнопка для загрузки файлов. Индикатор будет появляться для каждого выбранного файла в отдельности.

3. Скачивание файлов с удаленного сервера на свой сервер

4. Отдаем файл на удаленный сервер со своего сервера

По итогу хочу сказать

Если этот класс поможет хотя бы одному человеку я буду очень рад этому. Как я уже говорил в начале буду рад конструктивной критике и дополнениям которые могут привести к улучшению класса. Ссылка на CargaDes.class.

Изменил в статье способы использования класса. И добавил описание того что изменилось в классе.

Вот закончил работу над ошибками, если это можно так назвать.

Что было сделано:

  1. Привел код к одному стилю с помощью PHPSTORM и старался соблюдать PSR;
  2. Убрал подчеркивания из названий функций;
  3. Полностью исключил jQuery;
  4. Убрал все статические методы;
  5. Сделал класс как пакет composer;
  6. cUrl портянку вынес в отдельный метод;
  7. Постарался соблюсти SRP;
  8. Сделал исключения и немного изменил вывод ошибок;
  9. Исправил тело конструкторов;
  10. Постарался улучшить конструкции if-else;
  11. Вынес js и html за пределы класса;
  12. Убрал закрывающий тег ?>;
  13. Добавил возможность перевода сообщений;
  14. Добавил папку с исполняющимися примерами.

Что было не сделано:

  1. Перевод комментариев на английский(если это все одно никому не надо, то зачем тратить время);
  2. Не сменил названия функций на более понятные(мне не ясно какие, если английские, то смотреть пункт N1);
  3. Автотесты смотрел, но это оч. сложно сделать универсально т.к. у каждого свои сценарии действий, хотя может я ошибаюсь, то если вы считаете это нужным в классе который никому не нужен у вас есть возможность мне в этом помочь;
  4. Возможно еще что-то, но я уже не знаю что и у вас есть такая возможность мне об этом сказать.

В целом я постарался исправить, то о чем говорили в комментариях, если будут найдены еще какие либо недочеты или ошибки — пишите постараюсь исправить.

Благодарю за конструктивную критику webdevium и alutskevich, если бы мог, то плюсанул бы вам обязательно.

Так же благодарю всех остальных т.к. у меня появилось понимание моей главной ошибки и родилось пару идей.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *