Я хочу загрузить файл на FTP-сервер, но содержимое файла хранится в переменной, а не в локальном файле. Я хочу избежать использования файла; это во избежание угроз безопасности при работе с конфиденциальными данными в (возможно) ненадежной системе (*) , а также для минимизации (уже низких) накладных расходов на обработку файлов.
Но FTP API FTP предлагает только загрузку файлов из локальных файлов с помощью функции ftp_put
или (когда файл уже открыт как дескриптор файла) ftp_fput
.
В настоящее время я использую эту функцию с временным файлом, в котором я пишу содержимое перед загрузкой:
$tmpfile = tmpfile(); fwrite($tmpfile, $content); fseek($tmpfile, 0); ftp_fput($ftp, $filename, $tmpfile, FTP_BINARY);
Существует ли более простой способ без использования файлов на локальном (PHP) сайте?
Существует ftp_raw
который можно использовать для отправки произвольных команд, поэтому я могу вручную выполнить команду PUT
, однако я не вижу способа вручную записывать данные на канал данных …
Я не знаю, важно ли это, но FTP-соединение ftp_ssl_connect
SSL ( ftp_ssl_connect
).
(*) Рассмотрим сценарий, в котором злоумышленник имеет контроль только для чтения во всей файловой системе.
Это может быть не окончательное решение, но я думаю, это все же лучше, чем оригинальный подход:
Вы можете избежать временных файлов в файловой системе, используя поток памяти PHP . В основном это оболочка дескриптора файла, которая (за кулисами) не использует никакого фактического файла, а вместо этого некоторого фрагмента памяти.
Таким образом, вы по-прежнему используете дескриптор файла (поэтому ftp_fput
доволен), но нет фактического файла (поэтому на диск не записывается файл, а накладные расходы остаются минимальными).
$tmpfile = fopen('php://memory', 'r+'); fputs($tmpfile, $content); rewind($tmpfile); // or fseek
Обратите внимание, что при загрузке нескольких файлов вы можете дополнительно минимизировать накладные расходы за счет повторного использования одного и того же дескриптора файла для всех файлов (если, конечно, вы не распараллеливаете процедуру). В этом случае также перемотайте файл после ftp_fput
а также ftruncate($tmpfile, 0)
его, используя ftruncate($tmpfile, 0)
.
fopen должен иметь возможность подключаться через ftp:
http://php.net/manual/en/function.fopen.php
а затем используйте команду fwrite для записи строки в соединение:
http://php.net/manual/en/function.fwrite.php
Второй параметр fwrite – это строка, которая должна быть записана – вам не нужен файл.
Без локального файла (ftp_fput):
$stream = fopen('php://memory','r+'); fwrite($stream, $newFileContent); rewind($stream); $success = ftp_fput($connectionId, "remoteFileName", $stream, FTP_BINARY); fclose($stream);
—– Содержимое FTP PUT (php 7.0) —
$tmpFile = tmpfile(); fwrite($tmpFile, $contents); rewind($tmpFile); $tmpMetaData = stream_get_meta_data($tmpFile); if (ftp_put($ftpObj, $remoteFile, $tmpMetaData['uri'], FTP_ASCII)) { echo "success"; }else { echo "fail" } fclose($tmpFile);