2

Here's the situation... I have two servers, server 1 and server 2. server 1 downloads a csv file from server 2, deletes it off server 2, reads lines from it and does some processing.

While it is processing, the file on server 2 can be re-created or changed, adding more lines. After it is done processing, server 1 needs to upload the file back to server 2.

However, ftp_put() will completely overwrite the file on server 2. What I really want to do is append to the file on server 2 and not overwrite it. Is there any way to do this?

Brian Glaz
  • 15,468
  • 4
  • 37
  • 55

3 Answers3

3

Have you tried file_put_contents with the FILE_APPEND flag?

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • how can you include the ftp username and password though? – Brian Glaz Aug 29 '11 at 19:34
  • 1
    @Brian: `ftp://user:password@example.com/pub/file.txt` - just put it into the path, check the docs I linked for ftp(s):// in my answer for details. – hakre Aug 29 '11 at 20:01
  • @hakre Oh, ok. I got it now. Thanks! `file_put_contents` seems a lot easier than setting all of the `curl_opts`. Is there any advantage / disadvantage to using one over the other? – Brian Glaz Aug 29 '11 at 20:07
  • 1
    That's what I meant with "more accessible" in my answer. I would prefer using streams unless you need curl for something specific as it's a library. Streams are a cool feature of PHP. – hakre Aug 29 '11 at 20:13
  • `curl` makes me very sad. Whenever I see a script that has 10 lines of `curl_setopt` I die a little inside. – Halcyon Aug 29 '11 at 20:23
2

As shown in other answer, file_put_contents with FILE_APPEND flag is the easiest solution to append a chunk to the end of a remote file:

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

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


Though, if you actually have a matching local copy of a file, just with the new contents appended, it's easier to use a "hidden" feature of the ftp_put, the FTP_AUTORESUME:

$conn_id = ftp_connect('hostname');

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

$remote_path = '/path/to/file';
$local_path = 'file';
ftp_put($conn_id, $remote_path, $local_file, FTP_BINARY, FTP_AUTORESUME);

ftp_close($conn_id);

(add error handling)


If you do not have a matching local file, i.e. you are uploading a chunk of contents from memory, and you need a greater control over the writing (transfer mode, passive mode, etc), than you get with the file_put_contents, use the ftp_fput with a handle to the php://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, $chunk);
rewind($h);

// prevent ftp_fput from seeking local "file" ($h)
ftp_set_option($conn_id, FTP_AUTOSEEK, false);

$remote_path = '/path/to/file';
$size = ftp_size($conn_id, $remote_path);
$r = ftp_fput($conn_id, $remote_path, $h, FTP_BINARY, $size);

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

(again, add error handling)

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
2

Curl support appending for FTP:

curl_setopt($ch, CURLOPT_FTPAPPEND, TRUE ); // APPEND FLAG

This might be what you're looking for. Are you familiar with curl?

The other option is to use ftp:// / ftps:// streams, since PHP 5 they allow appending. See ftp://; ftps:// Docs. Might be easier to access.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • The parameter was renamed in libcurl, probably same for PHP: CURLOPT_APPEND A parameter set to 1 tells the library to append to the remote file instead of overwrite it. This is only useful when uploading to an FTP site. (This option was known as CURLOPT_FTPAPPEND up to 7.16.4) -- http://curl.haxx.se/libcurl/c/curl_easy_setopt.html – hakre Aug 29 '11 at 19:34
  • I found [this post](http://www.cre8asiteforums.com/forums/index.php?showtopic=67006) which basically uses a combination of both curl and ftp://. I think it's going to work. – Brian Glaz Aug 29 '11 at 19:55
  • @BrianGlaz link is broken, you have another example? – icy Feb 13 '18 at 17:48