在 PHP 中创建文件并将其上传到 FTP 服务器而不在本地保存

Posted

技术标签:

【中文标题】在 PHP 中创建文件并将其上传到 FTP 服务器而不在本地保存【英文标题】:Creating and uploading a file in PHP to an FTP server without saving locally 【发布时间】:2010-04-20 15:24:20 【问题描述】:

我在连接我正在工作的两个不同进程时遇到问题。我的任务是从数据库中提取数据,从数据中创建文件,然后将其上传到 FTP 服务器。

到目前为止,我已经使用此代码创建和下载了文件,$out 是一个包含完整文本文件的字符串:

if ($output == 'file')

    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Content-Length: ".strlen($out));
    header("Content-type: application/txt");
    header("Content-Disposition: attachment; filename=".$file_name);
    echo($out);

这适用于我只想在浏览器中运行脚本并下载文件,但我希望将其发送到 FTP 服务器。

我知道我与 FTP 服务器的连接工作正常,并且我正确导航到正确的目录,并且我已经从磁盘获取文件并使用 ftp_put() 将它们放在 FTP 上,但我是想把$out直接写成一个文件,在FTP服务器上用$filename作为它的名字。我可能误读了一些东西,但是当我尝试ftp_putftp_fput 时,他们似乎想要文件位置,而不是文件流。我可以考虑其他功能吗?

【问题讨论】:

【参考方案1】:

因为 cmets 忽略代码格式,所以我在这里而不是 cmets 回答。

你可以试试:

$fp = fopen('php://temp', 'r+'); fwrite($fp, $out); rewind($fp); ftp_fput($ftp_conn, $remote_file_name, $fp, FTP_ASCII);

这将创建一个临时流而不实际将其写入磁盘。我不知道还有什么办法

【讨论】:

【参考方案2】:

这是上面的matei's 解决方案,作为完整的函数 ftp_file_put_contents():

function ftp_file_put_contents($remote_file, $file_string) 

// FTP login details
$ftp_server='my-ftp-server.de'; 
$ftp_user_name='my-username'; 
$ftp_user_pass='my-password';

// Create temporary file
$local_file=fopen('php://temp', 'r+');
fwrite($local_file, $file_string);
rewind($local_file);       

// FTP connection
$ftp_conn=ftp_connect($ftp_server); 

// FTP login
@$login_result=ftp_login($ftp_conn, $ftp_user_name, $ftp_user_pass); 

// FTP upload
if($login_result) $upload_result=ftp_fput($ftp_conn, $remote_file, $local_file, FTP_ASCII);

// Error handling
if(!$login_result or !$upload_result)

    echo('<p>FTP error: The file could not be written to the FTP server.</p>');


// Close FTP connection
ftp_close($ftp_conn);

// Close file handle
fclose($local_file); 


// Function call
ftp_file_put_contents('my-file.txt', 'This text will be written to your text file via FTP.');

【讨论】:

【参考方案3】:

其实 ftp_put 需要的是本地文件的路径(作为字符串),所以尝试将数据写入临时文件,然后 ftp_put 将其发送到服务器

file_put_contents('/tmp/filecontent'.session_id(), $out); ftp_put($ftp_conn, $remote_file_name, '/tmp/filecontent'.session_id()); unlink('/tmp/filecontent'.session_id());

在这种情况下,您不需要发送您在示例中发送的标头。

【讨论】:

有没有办法做到这一点而不在文件系统上创建文件?【参考方案4】:

最简单的解决方案是使用file_put_contents 和FTP URL wrapper:

file_put_contents('ftp://username:pa‌​ssword@hostname/path/to/file', $out);

如果不起作用,可能是因为你没有URL wrappers enabled in PHP。


如果您需要更好地控制写入(传输模式、被动模式、偏移量、读取限制等),请使用 ftp_fputphp://temp (or the php://memory) stream 的句柄:

$conn_id = ftp_connect('hostname');

ftp_login($conn_id, 'username', 'password');
ftp_pasv($conn_id, true);

$h = fopen('php://temp', 'r+');
fwrite($h, $out);
rewind($h);

ftp_fput($conn_id, '/path/to/file', $h, FTP_BINARY, 0);

fclose($h);
ftp_close($conn_id);

(添加错误处理)


或者您可以直接在 FTP 服务器上打开/创建文件。如果文件很大,这特别有用,因为您不会将全部内容保存在内存中。

见Generate CSV file on an external FTP server in PHP。

【讨论】:

以上是关于在 PHP 中创建文件并将其上传到 FTP 服务器而不在本地保存的主要内容,如果未能解决你的问题,请参考以下文章

QNetworkManager 上传文件到 FTP 崩溃

在 XAMPP 中创建数据库(MySQL PDO)并将其与 php 代码连接

在内存中创建一个 Zip 文件

PHP 从FTP服务器下载文件并将其保存在本地文件中。

使用nodejs将文件写入特定目录并将其上传到数据库

Django 在 MEDIA_ROOT 文件夹中创建文件并将其保存到 FileField