PHP: Download a file from web to local machine - php

I have searched the web for 2 days and can not find the answer.
I am trying to create a routine which displays the files on a site I control, and allows the user to download a selected file to a local drive.
I am using the code below. When I uncomment the echo statements, it displays the correct source and destination directories, the correct file size and the echo after the fclose displays TRUE.
When I echo the source file ($data), it displays the correct content.
The $FileName variable contains the correct filename, which is either .doc/.docx or .pdf. I have tested both and neither saves anything into the destination directory, or anywhere else on my machine.
The source path ($path) is behind a login, but I am already logged in.
Any thoughts on why this is failing to write the file?
Thanks,
Hank
Code:
$path = "https://.../Reports/ReportDetails/$FileName";
/* echo "Downloading: $path"; */
$data = file_get_contents($path); /* echo "$data"; */
$dest = "C:\MyScans\\".$FileName; /* echo "<br />$dest"; */
$fp = fopen($dest,'wb');
if ( $fp === FALSE ) echo "<br />Error in fopen";
$result = fwrite($fp,$data);
if ( $result === FALSE ) echo "<br />Can not write to $dest";
/* else echo "<br />$result bytes written"; */
$result = fclose($fp); /* echo "<br />Close: $result"; */

I think (!) that you're a bit confused.
You mentioned
allows the user to download a selected file to a local drive.
But the path "C:\MyScans\\".$FileName is is the path on the webserver, not the path on the user's own computer.
After you do whatever to retrieve the desired file from the remote website:
Create a file from it and redirect the user to the file by using header('Location: /path/to/file.txt');
Insert the following header:
header('Content-disposition: attachment; filename=path/to/file.txt');
It forces the user to download the file. And that's probably what you want to do
Note: I have used the extension txt, but you can use any extension

you can use php Curl:
<?php
$url = 'http://www.example.com/a-large-file.zip';
$path = '/path/to/a-large-file.zip';
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);

Related

My php script won't open files that aren't in its root directory

This is a php script for a user login system that I am developing.
I need it to read from, and write to, the /students/students.txt file, but it won't even read the content already contained in the file.
<?php
//other code
echo "...";
setcookie("Student", $SID, time()+43200, "/");
fopen("/students/students.txt", "r");
$content = fread("/students/students.txt", filesize("/students/students.txt"));
echo $content;
fclose("/students/students.txt");
fopen("/students/students.txt", "w");
fwrite("/students/students.txt", $content."\n".$SID);
fclose("/students/students.txt");
//other code
?>
You are not using fopen() properly. The function returns a handle that you then use to read or edit the file, for example:
//reading a file
if ($handle = fopen("/students/students.txt", "r"))
{
echo "info obtained:<br>";
while (($buffer = fgets($handle))!==false)
{ echo $buffer;}
fclose($handle);
}
//writing/overwriting a file
if ($handle = fopen("/students/students.txt", "w"))
{
fwrite($handle, "hello/n");
fclose($handle);
}
Let me know if that worked for you.
P.S.: Ty to the commentators for the constructive feedback.
There are many ways to read/write to file as others have demonstrated. I just want to illustrate the mistake in your particular approach.
fread takes a file handle as param, NOT a string that represents the path to the file.
So your line:
$content = fread("/students/students.txt", filesize("/students/students.txt")); is incorrect.
It should be:
$file_handle = fopen("/students/students.txt", "r");
$content = fread($file_handle, filesize("/students/students.txt"));
Same thing when you write contents to file using fwrite. Its reference to the file is a File Handle opened using fopen NOT the filepath. when opening a file using fopen() you can also check if the $file_handle returned is a valid resource or is false. If false, it means the fopen operation was not successful.
So your code:
fopen("/students/students.txt", "w");
fwrite("/students/students.txt", $content."\n".$SID);
fclose("/students/students.txt");
Needs to be re-written as:
$file_handle = fopen("/students/students.txt", "w");
fwrite($file_handle, $content."\n".$SID);
fclose($file_handle);
You can see that fclose operates on file handles as well.
File Handle (as per php.net):
A file system pointer resource that is typically created using fopen().
Here are a couple of diagnostic functions that allow you to validate that a file exists and is readable. If it is a permission issue, it gives you the name of the user that needs permission.
function PrintMessage($text, $success = true)
{
print "$text";
if ($success)
print " [<font color=\"green\">Success</font>]<br />\n";
else
print(" [<font color=\"red\">Failure</font>]<br />\n");
}
function CheckReadable($filename)
{
if (realpath($filename) != "")
$filename = realpath($filename);
if (!file_exists($filename))
{
PrintMessage("'$filename' is missing or inaccessible by '" . get_current_user() . "'", false);
return false;
}
elseif (!is_readable($filename))
{
PrintMessage("'$filename' found but is not readable by '" . get_current_user() . "'", false);
return false;
}
else
PrintMessage("'$filename' found and is readable by '" . get_current_user() . "'", true);
return true;
}
I've re-written your code with (IMO) a cleaner and more efficient code:
<?php
$SID = "SOMETHING MYSTERIOUS";
setcookie("Student", $SID, time()+43200, "/");
$file = "/students/students.txt"; //is the full path correct?
$content = file_get_contents($file); //$content now contains /students/students.txt
$size = filesize($file); //do you still need this ?
echo $content;
file_put_contents($file, "\n".$SID, FILE_APPEND); //do you have write permissions ?
file_get_contents
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.
file_put_contents
This function is identical to calling fopen(), fwrite() and
fclose() successively to write data to a file. If filename does not
exist, the file is created. Otherwise, the existing file is
overwritten, unless the FILE_APPEND flag is set.
Notes:
Make sure the full path /students/students.txt is
correct.
Check if you've read/write permissions on /students/students.txt
Learn more about linux file/folder permissions or, if you don't access to the shell, how to change file or directory permissions via ftp
Try to do this:
fopen("students/students.txt", "r");
And check to permissions read the file.

copy, file_get_contents, file_put_contents doesn't get full content in new file

I'm trying to download a file that exists on different server and move it to my new server.
I've tried
$file = file_get_contents("https://exampleurl.com/file/download.txt");
file_put_contents("C:/directory/to/report/data.csv", $file);
as well
$remote_file_url = "https://exampleurl.com/file/download.txt";
$local_file = C:/directory/to/report/data.csv;
$copy = copy( $remote_file_url, $local_file );
But the file never completes, it cuts off towards the end of the file.
When I download the file directly from the url it's complete everytime.
I'm looking for a way to make sure the file is downloaded completely
Use Curl request generally file_get_contents timeout which causes this sort of errors and only the partial content gets loaded. Try this:
$ch=curl_init("https://exampleurl.com/file/download.txt"); //create a c url session
$timeout=300; //set time limit here depends upon the operations being done on the remote server currently its 5mins
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); //set timeout for request
$content = curl_exec($ch);//execute request
if($content)
{
$localfile = fopen("path to local file", "w"); //create or open a existing file
if(fwrite($localfile , $content)) //write data received
echo "success";
else
echo "unable to write file";
fclose($localfile ); //close the file
}
else //error occured while executing the request on the remote server
echo "Request Failed";

Fixing permissions for writing cUrl output to a text file

I am making a web application that grabs one page from the internet using cUrl and updates another page accordingly. I have been doing this by saving the HTML from cUrl and then parsing it on the other page. The issue is: I can't figure out what permissions I should use for the text file. I don't have it saved in my /public/ html folder, since I don't want any of the website's users to be able to see it. I only want them to be able to see the way it's parsed on the site.
Here is the cUrl code:
$perfidlist = "" ;
$sourcefile = "../templates/textfilefromsite.txt";
$trackerfile = "../templates/trackerfile.txt";
//CURL REQUEST 1 OF 2
$ch = curl_init("http://www.website.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
<more cUrl options omitted>
ob_start();
$curl2 = curl_exec($ch);
ob_end_clean();
curl_close($ch);
//WRITING FILES
$out = fopen($sourcefile, "r");
$oldfiletext = fread($out, filesize($sourcefile));
fclose($out);
$runcode = 1 ;
And the part where I save the text file:
/*only writing a file if the site has changed*/
if (strcmp($oldfiletext, $curl2) !==0)
{
$out = fopen($sourcefile, "w");
fwrite($out, $curl2);
fclose($out);
$tracker = fopen($trackerfile, "a+");
fwrite($tracker, date('Y/m/d H:i:s')."\n");
fclose($tracker);
$runcode = 1 ;
}
I am receiving an error at that last '$out = fopen($sourcefile, "w");' part that says:
Warning: fopen(../templates/textfilefromsite.txt): failed to open stream: Permission denied in /usr/share/nginx/templates/homedir.php on line 72
Any ideas?
The issue was with file/folder permissions. I ended up changing the permissions for the file to '666' meaning '-rw-rw-rw-' and it worked.

Downloading File from a URL using PHP script

Hi I want to download some 250 files from a URL which are in a sequence. I am almost done with it! Just the Problem is the structure of my URL is:
http://lee.kias.re.kr/~newton/sann/out/201409//SEQUENCE1.prsa
Where id is in a sequence but the file name "SEQUENCE1.psra" has a format "SEQUENCE?.psra".
Is there any way I can specify this format of file in my code? And also there are other files in folder, but only 1 with ".psra" ext.
Code:
<?php
// Source URL pattern
//$sourceURLOriginal = "http://www.somewebsite.com/document{x}.pdf";
$sourceURLOriginal = " http://lee.kias.re.kr/~newton/sann/out/201409/{x}/**SEQUENCE?.prsa**";
// Destination folder
$destinationFolder = "C:\\Users\\hp\\Downloads\\SOP\\ppi\\RSAdata";
// Destination file name pattern
$destinationFileNameOriginal = "doc{x}.txt";
// Start number
$start = 7043;
// End number
$end = 7045;
$n=1;
// From start to end
for ($i=$start; $i<=$end; $i++) {
// Replace source URL parameter with number
$sourceURL = str_replace("{x}", $i, $sourceURLOriginal);
// Destination file name
$destinationFile = $destinationFolder . "\\" .
str_replace("{x}", $i, $destinationFileNameOriginal);
// Read from URL, write to file
file_put_contents($destinationFile,
file_get_contents($sourceURL)
);
// Output progress
echo "File #$i complete\n";
}
?>
Its working if I directly specify the URL!
Error:
Warning: file_get_contents( http://lee.kias.re.kr/~newton/sann/out/201409/7043/SEQUENCE?.prsa): failed to open stream: Invalid argument in C:\xampp\htdocs\SOP\download.php on line 37
File #7043 complete
Its making the files but they are empty!
If there is a way in which I can download that whole folder(named with id in sequence) can also work! But how do we download the whole folder in a folder?
It may be possible file_get_contents() function is not working on your server.
Try this code :
function url_get_contents ($Url) {
if (!function_exists('curl_init')){
die('CURL is not installed!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
Here you go.
I didnt test the whole file_get_contents, file_put_contents part, but if you say its adding the files (albeit, blank) then I assume it still works here...
Everything else works fine. I left a var_dump() in so you can see what the return looks like.
I did what I suggested in my comment. Open the folder, parse the file list, grab the filename you need.
Also, I dont know if you read my original comments, but $sourceURLOriginal has an extra space at the beginning, which might have been giving you an issue.
<?php
$start=7043;
$end=7045;
$sourceURLOriginal="http://lee.kias.re.kr/~newton/sann/out/201409/";
$destinationFolder='C:\Users\hp\Downloads\SOP\ppi\RSAdata';
for ($i=$start; $i<=$end; $i++) {
$contents=file_get_contents($sourceURLOriginal.$i);
preg_match_All("|href=[\"'](.*?)[\"']|",$contents,$hrefs);
$file_list=array();
if (empty($hrefs[1])) continue;
unset($hrefs[1][0],$hrefs[1][1],$hrefs[1][2],$hrefs[1][3],$hrefs[1][4]);
$file_list=array_values($hrefs[1]);
var_dump($file_list);
foreach ($file_list as $index=>$file) {
if (strpos($file,'prsa')!==false) {
$needed_file=$index;
break;
}
}
file_put_contents($destinationFolder.'\doc'.$i.'.txt',
file_get_contents($sourceURLOriginal.$i.'/'.$file_list[$needed_file])
);
}

opening and viewing a file in php

how do i open/view for editing an uploaded file in php?
i have tried this but it doesn't open the file.
$my_file = 'file.txt';
$handle = fopen($my_file, 'r');
$data = fread($handle,filesize($my_file));
i've also tried this but it wont work.
$my_file = 'file.txt';
$handle = fopen($my_file, 'w') or die('Cannot open file: '.$my_file);
$data = 'This is the data';
fwrite($handle, $data);
what i have in mind is like when you want to view an uploaded resume,documents or any other ms office files like .docx,.xls,.pptx and be able to edit them, save and close the said file.
edit: latest tried code...
<?php
// Connects to your Database
include "configdb.php";
//Retrieves data from MySQL
$data = mysql_query("SELECT * FROM employees") or die(mysql_error());
//Puts it into an array
while($info = mysql_fetch_array( $data ))
{
//Outputs the image and other data
//Echo "<img src=localhost/uploadfile/images".$info['photo'] ."> <br>";
Echo "<b>Name:</b> ".$info['name'] . "<br> ";
Echo "<b>Email:</b> ".$info['email'] . " <br>";
Echo "<b>Phone:</b> ".$info['phone'] . " <hr>";
//$file=fopen("uploadfile/images/".$info['photo'],"r+");
$file=fopen("Applications/XAMPP/xamppfiles/htdocs/uploadfile/images/file.odt","r") or exit("unable to open file");;
}
?>
i am getting the error:
Warning: fopen(Applications/XAMPP/xamppfiles/htdocs/uploadfile/images/file.odt): failed to open stream: No such file or directory in /Applications/XAMPP/xamppfiles/htdocs/uploadfile/view.php on line 17
unable to open file
the file is in that folder, i don't know it wont find it.
It might be either:
A permissions issue on the server. If it's a linux machine, try chmod 754 Applications/XAMPP/xamppfiles/htdocs/uploadfile/images/file.odt (you may need root).
An issue with apache (or whatever webserver you might be using). Make sure you've defined a directory entry in the config file for that site. Documentation here.
Although, if I recall properly, an odt file will just be binary data rather than the text information. That might be what you're looking for, I don't know. If you just want to read the actual text, and you aren't interested in using some library to extract it, you need to save it as plain text. If you're actually trying to edit these files in the browser, you're gonna need a lot more than just fopen.
For text based files you can use file_get_contents and file_put_contents
However, ODT files are zip compressed XML files so you need to decompress them first:
$zip = new ZipArchive;
$res = $zip->open('Applications/XAMPP/xamppfiles/htdocs/uploadfile/images/file.odt');
if ($res === TRUE) {
$zip->extractTo('/tmp/myOdt.xml');
$zip->close();
}
$data = file_get_contents('/tmp/myOdt.xml');
$data .= 'add this to the end';
file_put_contents('path/to/file.txt', $data);
However, it seems your problem regards the actual path of the file. Try using a relative path instead: "images/file.odt"

Categories