Stream ftp file to browser - php

I am trying to retrieve and stream a file to the browser from an ftp site.
The error is:
Warning: ftp_nb_get() expects parameter 2 to be string, resource given
I know that it is a resource but how do I get around this?
if(isset($_GET['filename'])){
$requestfilename = $_GET['filename'];
if($sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP)){
stream_set_write_buffer($sockets[0], 0);
stream_set_timeout($sockets[1], 0);
if($ftp_connection = ftp_connect($ftp_server)){
if (#ftp_login($ftp_connection, $ftp_user, $ftp_pass)) {
if(#ftp_chdir($ftp_connection, $ftp_dir_new)){
if($ret = ftp_nb_get($ftp_connection, $sockets[0], $requestfilename, FTP_BINARY)){
while(ftp_nb_continue($ftp_connection)==FTP_MOREDATA){
$contents = stream_get_contents($sockets[1]);
if($contents !== false) {
echo $contents;
flush();
}
}
if ($ret != FTP_FINISHED) $error[] = 'There was an error downloading the file...';
}else{
$error[] = "Could not ftp_nb_get file from $ftp_server";
}
}else{
$error[] = "Couldn't cd to $ftp_dir_new";
}
} else {
$error[] = "Couldn't connect as $ftp_user";
}
}else{
$error[] = "Couldn't connect to $ftp_server";
}
}else{
$error[] = "Unable to create socket pair";
}
if($sockets){
fclose($sockets[0]);
fclose($sockets[1]);
}
if( ! empty($ftp_connection)) ftp_close($ftp_connection);
}

So you're looking for an alternative to ftp_nb_get() that allows you to write to STDOUT or an arbitrary stream, instead of a local file?
I've not used this module at all, but it looks like ftp_nb_fget does what you want.

I know it's an old topic, but I came across this code and found small bug. Maybe someone uses it and has problem making it work.
This code won't work for very small files because ftp_nb_continue won't return FTP_MOREDATA even once. To fix this you need to change while loop to:
while($ret == FTP_MOREDATA){
$contents = stream_get_contents($sockets[1]);
if($contents !== false) {
echo $contents;
flush();
}
$ret = ftp_nb_continue($ftp_connection);
}

Related

PHP data processing not outputting

Hi I am trying to get this external text file to print inside my php document. The code looks fine to me however when I echo it does not output anything and I am not sure why this is. Can anybody help me out as I am new to this.
$location = '/Applications/MAMP/htdocs/PHPLabs/branches.txt';
$fp = fopen($location, 'r');
if ($fp) {
$readin = fread($fp);
fclose($fp);
} else {
echo 'Can\'t open input.txt';
}
Not sure what you're trying to 'echo' but have you checked if the file exists in the first place?
Your code could be written as:
$location = '/Applications/MAMP/htdocs/PHPLabs/branches.txt';
if (file_exists($location) && $data = file_get_content($location)){
echo $data;
} else {
echo 'File not found';
}
if (file_exists($location) && $file = fopen($location, 'r')){
$file_content = fread($file, filesize($location));
fclose($file);
} esle {
echo 'File not found';
}
See here for more: http://php.net/manual/en/function.file-get-contents.php, http://php.net/manual/en/function.filesize.php

how to upload a base64_decode($data) using ftp?

Im trying to upload a mp3 file to my ftp server:
$data = substr($_POST['data'], strpos($_POST['data'], ",") + 1);
$decodedData = base64_decode($data);
$filename = urldecode($_POST['fname']);
$cid = ftp_connect("foo.com");
$result = ftp_login($cid, "rodrigo#foo.com","password");
if ((!$cid) || (!$result)) {
echo "connection failed"; die;
} else {
echo "connected";
}
ftp_pasv ($cid, true);
ftp_chdir($cid, "my_folder");
if (ftp_put($cid, $filename, $decodedData, FTP_BINARY)) {
//...
} else {
//...
}
I have this warning:
Warning: ftp_put(���) [function.ftp-put]: failed to open stream: Invalid argument in...
I cant find out how to send a valid argument
You will need to create a file that you can pass, the below example writes the file to memory instead of a file on your disk ... but you may want to write it to disk depending on the size.
$tmp = fopen('php://memory', 'r+');
fputs($tmp, $decodedData);
rewind($tmp);
if (ftp_fput($cid, $filename, $tmp, FTP_BINARY)) {
}

How to modify PHP FTP upload script to download files instead

I have found a PHP script for transferring FTP files, and it works exactly as I need for one part of my project. The script can upload files via FTP to another server just fine, and can output the progress as it goes.
The code I am using is:
$fp = fopen($local_file, 'r');
$conn_id = ftp_connect($source_ftp_server);
$login_result = ftp_login($conn_id, $source_ftp_user_name, $source_ftp_user_pass);
$ret = ftp_nb_fput($conn_id, $remote_file, $fp, FTP_BINARY);
while ($ret == FTP_MOREDATA) {
// Establish a new connection to FTP server
if(!isset($conn_id2)) {
$conn_id2 = ftp_connect($source_ftp_server);
$login_result2 = ftp_login($conn_id2, $source_ftp_user_name, $source_ftp_user_pass);
}
// Retreive size of uploaded file.
if(isset($conn_id2)) {
clearstatcache(); // <- this must be included!!
$remote_file_size = ftp_size($conn_id2, $remote_file);
}
// Calculate upload progress
$local_file_size = filesize($local_file);
if (isset($remote_file_size) && $remote_file_size > 0 ){
$i = ($remote_file_size/$local_file_size)*100;
printf("%d%% uploaded<br>", $i);
flush();
}
$ret = ftp_nb_continue($conn_id);
}
if ($ret != FTP_FINISHED) {
echo "<span style='color:red;'><b>There was an error uploading the file...</b></span><br>";
exit(1);
}
else {
echo "<br>Files successfully uploaded!<br><br>";
}
fclose($fp);
I took out some unimportant parts, such as extra information that is echoed by the script, etc.
This code works perfectly for uploading files to the other server. However, I also need to download a file from the server using FTP as well.
I'd really like to use the same code as above, with the progress indicator, etc, but am not sure how to modify this code to download a file instead of uploading one.
It may be a couple of simple changes are all that is needed.
Are there any parts of this code in particular that will need to be changed, or can this not work the same for downloads as it does for uploads?
I'd really appreciate it if someone could point me in somewhat of the right direction to sort this out.
Is it as simple as changing the ftp_nb_fput command to a ftp_nb_get command? I don't really understand all of this code so it's difficult to tell what would need to be changed.
Thanks for your help.
You are looking for ftp_get
Looks like it should be used something like the following:
$conn_id = ftp_connect($source_ftp_server);
$login_result = ftp_login($conn_id, $source_ftp_user_name, $source_ftp_user_pass);
$success = ftp_get($conn_id, $local_file, $server_file, FTP_BINARY);
http://php.net/manual/en/function.ftp-get.php
Here's the script, with the necessary modifications to make it download a file instead:
$fp = fopen($local_file2, 'w+');
$conn_id = ftp_connect($source_ftp_server);
$login_result = ftp_login($conn_id, $source_ftp_user_name, $source_ftp_user_pass);
$ret = ftp_nb_fget($conn_id, $fp, $remote_file2, FTP_BINARY);
while ($ret == FTP_MOREDATA) {
// Establish a new connection to FTP server
if(!isset($conn_id2)) {
$conn_id2 = ftp_connect($source_ftp_server);
$login_result2 = ftp_login($conn_id2, $source_ftp_user_name, $source_ftp_user_pass);
}
// Retreive size of source file.
if(isset($conn_id2)) {
clearstatcache(); // <- this must be included!!
$remote_file2_size = ftp_size($conn_id2, $remote_file2);
}
// Calculate download progress
$local_file2_size = filesize($local_file2);
if (isset($remote_file2_size) && $remote_file2_size > 0 ){
$i = ($local_file2_size/$remote_file2_size)*100;
printf("%d%% downloaded<br>", $i);
}
$ret = ftp_nb_continue($conn_id);
}
if ($ret != FTP_FINISHED) {
echo "<span style='color:red;'><b>There was an error downloading the file...</b></span><br>";
exit(1);
}
echo "<br>Files successfully downloaded!<br><br>";
fclose($fp);

modify permissions for files created by php script

How (or can) I change the following php script so that when it creates a new file, it gives the file r/w permission?
<?php
if(isset($_GET['data'])) {
$data = $_GET['data'] . "\n";
$ip = $_GET['ip'];
$ret = file_put_contents('/opt/tomcat7/webapps/servlets/WEB-INF/logs/' . $ip, $data, LOCK_EX);
if($ret === false) {
die('There was an error writing the lab data file');
}
else {
echo "$ret bytes written to file";
}
}
else {
die('no data to process');
}
?>
Try chmod function.
For example chmod("/somedir/somefile", 0755)

PHP not writing to file from one source

I have an issue I can't seem to find the solution for. I am trying to write to a flat text file. I have echoed all variables out on the screen, verified permissions for the user (www-data) and just for grins set everything in the whole folder to 777 - all to no avail. Worst part is I can call on the same function from another file and it writes. I can't see to find the common thread here.....
function ReplaceAreaInFile($AreaStart, $AreaEnd, $File, $ReplaceWith){
$FileContents = GetFileAsString($File);
$Section = GetAreaFromFile($AreaStart, $AreaEnd, $FileContents, TRUE);
if(isset($Section)){
$SectionTop = $AreaStart."\n";
$SectionTop .= $ReplaceWith;
$NewContents = str_replace($Section, $SectionTop, $FileContents);
if (!$Handle = fopen($File, 'w')) {
return "Cannot open file ($File)";
exit;
}/*
if(!flock($Handle, LOCK_EX | LOCK_NB)) {
echo 'Unable to obtain file lock';
exit(-1);
}*/
if (fwrite($Handle, $NewContents) === FALSE) {
return "Cannot write to file ($File)";
exit;
}else{
return $NewContents;
}
}else{
return "<p align=\"center\">There was an issue saving your settings. Please try again. If the issue persists contact your provider.</p>";
}
}
Try with...
$Handle = fopen($File, 'w');
if ($Handle === false) {
die("Cannot open file ($File)");
}
$written = fwrite($Handle, $NewContents);
if ($written === false) {
die("Invalid arguments - could not write to file ($File)");
}
if ((strlen($NewContents) > 0) && ($written < strlen($NewContents))) {
die("There was a problem writing to $File - $written chars written");
}
fclose($Handle);
echo "Wrote $written bytes to $File\n"; // or log to a file
return $NewContents;
and also check for any problems in the error log. There should be something, assuming you've enabled error logging.
You need to check for number of characters written since in PHP fwrite behaves like this:
After having problems with fwrite() returning 0 in cases where one
would fully expect a return value of false, I took a look at the
source code for php's fwrite() itself. The function will only return
false if you pass in invalid arguments. Any other error, just as a
broken pipe or closed connection, will result in a return value of
less than strlen($string), in most cases 0.
Also, note that you might be writing to a file, but to a different file that you're expecting to write. Absolute paths might help with tracking this.
The final solution I ended up using for this:
function ReplaceAreaInFile($AreaStart, $AreaEnd, $File, $ReplaceWith){
$FileContents = GetFileAsString($File);
$Section = GetAreaFromFile($AreaStart, $AreaEnd, $FileContents, TRUE);
if(isset($Section)){
$SectionTop = $AreaStart."\n";
$SectionTop .= $ReplaceWith;
$NewContents = str_replace($Section, $SectionTop, $FileContents);
return $NewContents;
}else{
return "<p align=\"center\">There was an issue saving your settings.</p>";
}
}
function WriteNewConfigToFile($File2WriteName, $ContentsForFile){
file_put_contents($File2WriteName, $ContentsForFile, LOCK_EX);
}
I did end up using absolute file paths and had to check the permissions on the files. I had to make sure the www-data user in Apache was able to write to the files and was also the user running the script.

Categories