在PHP中创建文件并将其上载到FTP服务器,而无需本地保存

时间:2021-08-17 16:00:06

I'm having a problem connecting two different processes that I have working. I've been tasked with pulling data out of a database, creating a file from the data, and then uploading it to an FTP server.

我有一个问题,连接我工作的两个不同的过程。我的任务是从数据库中取出数据,从数据中创建一个文件,然后将其上传到FTP服务器。

So far, I have the file being created and downloadable using this code, $out being a string that contains the complete text file:

到目前为止,我已经用这段代码创建并下载了这个文件,$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);
}

This works when I want to just run the script in a browser and download the file, but I'm looking to instead send it to an FTP server.

当我想在浏览器中运行这个脚本并下载这个文件时,它就可以工作了,但是我想把它发送到FTP服务器上。

I know my connection to the FTP server is working just fine, and I'm correctly navigating to the correct directory, and I've taken files from disk and put them on the FTP using ftp_put(), but I'm looking to take $out and write it directly as a file with $filename as its name on the FTP server. I may be misreading things, but when I tried ftp_put and ftp_fput, it seemed that they want file locations, not file streams. Is there a different function I could consider?

我知道我的连接到FTP服务器工作很好,我正确导航到正确的目录,我已经从磁盘文件并使用函数放在FTP(),但我想取出美元和美元把它直接写成文件,FTP服务器上的文件名作为它的名字。我可能读错了东西,但是当我尝试ftp_put和ftp_fput时,它们似乎想要文件位置,而不是文件流。我可以考虑别的函数吗?

4 个解决方案

#1


14  

I've answered here instead of the comments since comments ignore code formatting.

由于注释忽略了代码格式,所以我在这里代替注释进行了回答。

you could try:

你可以试试:


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

this will create a temporary stream without actually writing it to disk. I don't know any other way

这将创建一个临时流,而无需实际将其写入磁盘。我不知道还有别的办法

#2


4  

Here is matei's solution from above as complete function ftp_file_put_contents():

这里是来自上面的matei的解决方案,作为完整的函数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


3  

Actually ftp_put expects the path to the local file (as a string), so try to write the data in a temporary file and then ftp_put it to the server

实际上,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()); 

In this case you don't need to send the headers you were sending in your example.

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

#4


0  

The easiest solution is using file_put_contents with FTP URL wrapper:

最简单的解决方案是使用带有FTP URL包装器的file_put_contents:

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

If it does not work, it's probably because you do not have URL wrappers enabled in PHP.

如果它不工作,可能是因为PHP中没有启用URL包装器。


If you need greater control over the writing (transfer mode, passive mode, offset, reading limit, etc), use the ftp_fput with a handle to the php://temp (or the php://memory) stream:

如果您需要更好地控制写入(传输模式、被动模式、偏移量、读取限制等),请使用带有php:// /temp(或php:/内存)流句柄的ftp_fput:

$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);

(add error handling)

(添加错误处理)


Or you can open/create the file directly on the FTP server. That's particularly useful, if the file is large, as you won't have keep whole contents in memory.

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

See Generate CSV file on an external FTP server in PHP.

请参阅在PHP中的外部FTP服务器上生成CSV文件。

#1


14  

I've answered here instead of the comments since comments ignore code formatting.

由于注释忽略了代码格式,所以我在这里代替注释进行了回答。

you could try:

你可以试试:


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

this will create a temporary stream without actually writing it to disk. I don't know any other way

这将创建一个临时流,而无需实际将其写入磁盘。我不知道还有别的办法

#2


4  

Here is matei's solution from above as complete function ftp_file_put_contents():

这里是来自上面的matei的解决方案,作为完整的函数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


3  

Actually ftp_put expects the path to the local file (as a string), so try to write the data in a temporary file and then ftp_put it to the server

实际上,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()); 

In this case you don't need to send the headers you were sending in your example.

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

#4


0  

The easiest solution is using file_put_contents with FTP URL wrapper:

最简单的解决方案是使用带有FTP URL包装器的file_put_contents:

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

If it does not work, it's probably because you do not have URL wrappers enabled in PHP.

如果它不工作,可能是因为PHP中没有启用URL包装器。


If you need greater control over the writing (transfer mode, passive mode, offset, reading limit, etc), use the ftp_fput with a handle to the php://temp (or the php://memory) stream:

如果您需要更好地控制写入(传输模式、被动模式、偏移量、读取限制等),请使用带有php:// /temp(或php:/内存)流句柄的ftp_fput:

$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);

(add error handling)

(添加错误处理)


Or you can open/create the file directly on the FTP server. That's particularly useful, if the file is large, as you won't have keep whole contents in memory.

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

See Generate CSV file on an external FTP server in PHP.

请参阅在PHP中的外部FTP服务器上生成CSV文件。