Why does the file not upload? PHP and FTP [duplicate] - php

I am having some JSON data that I encoded it with PHP's json_encode(), it looks like this:
{
"site": "site1",
"nbrSicEnt": 85,
}
What I want to do is to write the data directly as a file onto an FTP server.
For security reasons, I don't want the file to be created locally first before sending it to the FTP server, I want it to be created on the fly. So without using tmpfile() for example.
When I read the php documentations for ftp_put:
bool ftp_put ( resource $ftp_stream , string $remote_file ,
string $local_file , int $mode [, int $startpos = 0 ] )
Ones needs to create a local file (string $local_file) before writing it to the remote file.
I am looking for a way to directly write into the remote_file. How can I do that using PHP?

The file_put_contents is the easiest solution:
file_put_contents('ftp://username:pa‌​ssword#hostname/path/to/file', $contents);
If it does not work, it's probably because you do not have URL wrappers enabled in PHP.
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:
$conn_id = ftp_connect('hostname');
ftp_login($conn_id, 'username', 'password');
ftp_pasv($conn_id, true);
$h = fopen('php://temp', 'r+');
fwrite($h, $contents);
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.
See Generate CSV file on an external FTP server in PHP.

According to Can you append lines to a remote file using ftp_put() or something similar? and Stream FTP Upload with PHP? you should be able to do something using either CURL or PHP's FTP wrappers using file_put_contents().
$data = json_encode($object);
file_put_contents("ftp://user:pass#host/dir/file.ext", $data, FILE_APPEND);

Related

How to create a PDF in PHP and transfer it over FTP [duplicate]

I am having some JSON data that I encoded it with PHP's json_encode(), it looks like this:
{
"site": "site1",
"nbrSicEnt": 85,
}
What I want to do is to write the data directly as a file onto an FTP server.
For security reasons, I don't want the file to be created locally first before sending it to the FTP server, I want it to be created on the fly. So without using tmpfile() for example.
When I read the php documentations for ftp_put:
bool ftp_put ( resource $ftp_stream , string $remote_file ,
string $local_file , int $mode [, int $startpos = 0 ] )
Ones needs to create a local file (string $local_file) before writing it to the remote file.
I am looking for a way to directly write into the remote_file. How can I do that using PHP?
The file_put_contents is the easiest solution:
file_put_contents('ftp://username:pa‌​ssword#hostname/path/to/file', $contents);
If it does not work, it's probably because you do not have URL wrappers enabled in PHP.
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:
$conn_id = ftp_connect('hostname');
ftp_login($conn_id, 'username', 'password');
ftp_pasv($conn_id, true);
$h = fopen('php://temp', 'r+');
fwrite($h, $contents);
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.
See Generate CSV file on an external FTP server in PHP.
According to Can you append lines to a remote file using ftp_put() or something similar? and Stream FTP Upload with PHP? you should be able to do something using either CURL or PHP's FTP wrappers using file_put_contents().
$data = json_encode($object);
file_put_contents("ftp://user:pass#host/dir/file.ext", $data, FILE_APPEND);

PHP input stream returning 0 data - Laravel

I'm trying to get chunked uploads working on a form in my Laravel 4 project. The client side bit works so far, the uploads are chunking in 2MB chunks, and data is being sent from the browser. There's even have a handy progress bar in place to show the upload progress.
The problem is on the PHP side, as I'm unable to write the contents of the upload stream to disk. The system always ends up with a 0 byte file created. The idea is to append the chunks to the already uploaded file as they arrive.
The project is built on Laravel 4, so I'm not sure if Laravel reads the php://input stream and does something with it. Since php://input can only be read once, it possibly means that by the time when my controller actually tries to read it the stream, it would be empty.
The controller looks as follows:
public function upload()
{
$filename = Config::get('tms.upload_path') . Input::file('file')->getClientOriginalName();
file_put_contents($filename, fopen('php://input', 'r'), FILE_APPEND);
}
The file is being created, but it's length always remains at 0 bytes. Any ideas how I can coax the contents of the php://input stream out of the system?
afaik fopen returns a pointer to file, and not an stream, so probably it is not good as a parameter for file_put_contents
can you try with this workaround, instead of your file_put_contents?
$putdata = fopen("php://input", "r");
$fp = fopen($filename, "a");
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
fclose($fp);
fclose($putdata);
The answer to this is simple, I needed to turn off multipart/form-data and use file_get_contents("php://input") to read the contents and pass the result to file_put_contents() like so:
file_put_contents($filename, file_get_contents("php://input"), FILE_APPEND);
This works and fixes my problems.

Send partial of FTP stream to php://output

I have a PHP-server that serves audio-files by streaming them from an FTP-server not publicly available.
After sending the approriate headers, I just stream the file to the client using ftp_get like this:
ftp_get($conn, 'php://output', $file, FTP_BINARY);
For reasons that has to do with Range headers, I must now offer to only send a part of this stream:
$start = 300; // First byte to stream
$stop = 499; // Last byte to stream (the Content-Length is then $stop-$start+1)
I can do it by downloading the entire content temporarily to a file/memory, then send the desired part to the output. But since the files are large, that solution will cause a delay for the client who has to wait for the file to first be downloaded to the PHP-server before it even starts to download to the client.
Question:
How can I start streaming to php://output from an FTP-server as soon as the first $start bytes have been discarded and stop streaming when I've reached the '$stop' byte?
Instead of using PHP's FTP extension (eg. ftp_get), it is possible to open a stream using PHP's built-in FTP wrapper.
The following code would stream parts of an FTP-file to php://output:
$start = 300; // First byte to stream
$stop = 499; // Last byte to stream
$url = "ftp://username:password#server.com/path/file.mp3";
$ctx = stream_context_create(array('ftp' => array('resume_pos' => $start)));
$fin = fopen($url, 'r', false, $ctx);
$fout = fopen('php://output', 'w');
stream_copy_to_stream($fin, $fout, $stop-$start+1);
fclose($fin);
fclose($fout);
While stream_copy_to_stream has an $offset parameter, using it resulted in an error because the stream was not seekable. Using the context option resume_pos worked fine however.

Save large files from php stdin

Advise me the most optimal way to save large files from php stdin, please.
iOS developer sends me large video content to server and i have to store it in to files.
I read the stdin thread with video data and write it to the file. For example, in this way:
$handle = fopen("php://input", "rb");
while (!feof($handle)) {
$http_raw_post_data .= fread($handle, 8192);
}
What function is better to use? file_get_contents or fread or something else?
I agree with #hek2mgl that treating this as a multipart form upload would make most sense, but if you can't alter your input interface then you can use file_put_contents() on a stream instead of looping through the file yourself.
$handle = fopen("php://input", "rb");
if (false === file_put_contents("outputfile.dat", $handle))
{
// handle error
}
fclose($handle);
It's cleaner than iterating through the file, and it might be faster (I haven't tested).
Don't use file_get_contents because it would attempt to load all the content of the file into a string
FROM PHP DOC
file_get_contents() is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance.
Am sure you just want to create the movie file on your server .. this is a more efficient way
$in = fopen("php://input", "rb");
$out = fopen('largefile.dat', 'w');
while ( ! feof($in) ) {
fwrite($out, fread($in, 8192));
}
If you use nginx as web server i want to recommend nginx upload module with possibility to resume upload.

Stream FTP upload in chunks with PHP?

Is it possible to stream an FTP upload with PHP? I have files I need to upload to another server, and I can only access that server through FTP. Unfortunately, I can't up the timeout time on this server. Is it at all possible to do this?
Basically, if there is a way to write part of a file, and then append the next part (and repeat) instead of uploading the whole thing at once, that'd save me. However, my Googling hasn't provided me with an answer.
Is this achievable?
OK then... This might be what you're looking for. Are you familiar with curl?
CURL can support appending for FTP:
curl_setopt($ch, CURLOPT_FTPAPPEND, TRUE ); // APPEND FLAG
The other option is to use ftp:// / ftps:// streams, since PHP 5 they allow appending. See ftp://; ftps:// Docs. Might be easier to access.
The easiest way to append a chunk to the end of a remote file is to use file_put_contents with FILE_APPEND flag:
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.
If you need a greater control over the writing (transfer mode, passive mode, etc), or you cannot use 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);
(add error handling)

Categories