I want to be able to read the contents of a file from its full domain and filepath, so something like:
http://www.example.com/files/file.txt
What I can't do in this instance is:
../files/file.txt
I have tried curl, fopen, file_get_contents and would rather use curl but cannot get it to work for any of them.
Is there an obvious reason why this isn't working that I am missing?
Here are the code snippets for each attempt, parhaps someone knows what's wrong with one of them?
Incidentally, if I could do ../files/file.txt it works for each option.
$file = "http://www.example.com/files/file.txt";
fopen:
$f=fopen($file,'r');
$data='';
while(!feof($f))
$data.=fread($f,$size);
fclose($f);
curl:
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$data = curl($file);
file_get_contents:
$data = file_get_contents($file);
Thanks in advance for all help.
file_get_contents works fine for URLs with PHP 4 >= 4.3.0 and PHP 5:
"A URL can be used as a filename with this function if the fopen wrappers have been enabled"
Many shared hosters have this option disabled, or are using an older version of PHP and are blocking loading external files using PHP's safe mode.
Start with enabling error_reporting and have a look at your hosters web site to see if he's blocking external files.
Perhaps url fopen are disabled on your hosting and urls from another domains are just disabled?
php.ini var allow_url_fopen must be on
Related
This question already has answers here:
How to scrape websites when cURL and allow_url_fopen is disabled
(4 answers)
Closed 9 years ago.
I've got several functions in my php app that relay on calls to file_get_contents(), file_put_contents, and getimagesize().
The problem is that when allow_url_fopen an allow_url_include are disabled in php.ini I'm getting errors on these critical functions.
Warning: getimagesize() [function.getimagesize]: URL file-access is
disabled in the server configuration in
/home/content/.../html/_sites/mysite/wp-content/themes/mytheme/functions.php
on line 2534
What are the options for working around these issues?
EDIT: These are all local files on the same webserver as the calling php script. Is there a preferred method for reading/writing file contents?
You can use curl to get remote pages. You can store the results of the curl request to a variable and echo() in place of using the url wrapper to fetch content.
In theory, you could also eval() the returned data. But running remotely fetched PHP code is a ENORMOUS security risk, any PHP code included in this way can literally do anything you can. DON'T DO IT! The same goes for allow_url_include too
If you have access to your webserver, you may have to find your php.ini file, for example:
/etc/php5/apache/php.ini
And use these options:
; http://php.net/allow-url-fopen
allow_url_fopen = On
; http://php.net/allow-url-include
allow_url_include = Off
If your using someking of hosting account, these options may be interactively available at a control panel.
The second solution might be to use cURL. I suppose you were trying to call getimagesize with an URL. Documentation here: http://php.net/manual/en/book.curl.php
$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
I am facing a issue such that i am able to link to a file that is present in an http server or a ftp server.. but i am not able to link to a file that is present in a file server..
ie, More Clearly..
if the URL is http://serverpath.com/images/image.jpg or ftp://serverpath.com/images/image.jpg or a remote path the file_exists function gives a true value but if a give a file server path like the similar path as //serverpath/public/images/image.jpg the file_exists function is giving a false value.
UPDATE
I am using PHP 5.4.4
There was a bug reported regarding this issue in the previous version of php ie below 5.3 and it was told that this issue has been solved in the versions above 5.3. Is there any change in the php.ini that we need to make change to enable. I searched but did not get the answer i expected
Please Help
use CURL:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http:\\www.somesite.com\somefile.html');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
curl_exec($ch) will return FALSE if no file is present or the actual data on success
However:
You'd better bind your shared folder to a logical hard drive with
net use E: \\servername\shareddirectory
doing this will allow you to access your remote file as it were on a local disk (say E:).
file_exists() should work if you give the "local" path E:\filepath\filename
Your php.ini allow_url_fopen is on?
I use following PHP function:
file_get_contents('http://example.com');
Whenever I do this on a certain server, the result is empty. When I do it anywhere else, the result is whatever the page's content may be. When I however, on the server where the result is empty, use the function locally - without accessing an external URL (file_get_contents('../simple/internal/path.html');), it does work.
Now, I am pretty sure it has something to do with a certain php.ini configuration. What I am however not sure about is, which one. Please help.
Complementing Aillyn's answer, you could use a function like the one below to mimic the behavior of file_get_contents:
function get_content($URL){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $URL);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
echo get_content('http://example.com');
The setting you are looking for is allow_url_fopen.
You have two ways of getting around it without changing php.ini, one of them is to use fsockopen(), and the other is to use cURL.
I recommend using cURL over file_get_contents() anyways, since it was built for this.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.your_external_website.com");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
is best for http url,
But how to open https url help me
The is related to the ini configuration setting allow_url_fopen.
You should be aware that enable that option may make some bugs in your code exploitable.
For instance, this failure to validate input may turn into a full-fledged remote code execution vulnerability:
copy($_GET["file"], ".");
The answers provided above solve the problem but don't explain the strange behaviour the OP described. This explanation should help anyone testing communication between sites in a development environment where these sites all reside on the same host (and the same virtualhost; I'm working with apache 2.4 and php7.0).
There's a subtlety with file_get_contents() I came across that is absolutely relevant here but unaddressed (probably because it's either barely documented or not documented from what I can tell or is documented in an obscure php security model whitepaper I can't find).
With allow_url_fopen set to Off in all relevant contexts (e.g. /etc/php/7.0/apache2/php.ini, /etc/php/7.0/fpm/php.ini, etc...) and allow_url_fopen set to On in the command line context (i.e. /etc/php/7.0/cli/php.ini), calls to file_get_contents() for a local resource will be allowed and no warning will be logged such as:
file_get_contents('php://input');
or
// Path outside document root that webserver user agent has permission to read. e.g. for an apache2 webserver this user agent might be www-data so a file at /etc/php/7.0/filetoaccess would be successfully read if www-data had permission to read this file
file_get_contents('<file path to file on local machine user agent can access>');
or
// Relative path in same document root
file_get_contents('data/filename.dat')
To conclude, the restriction allow_url_fopen = Off is analogous to an iptables rule in the OUTPUT chain, where the restriction is only applied when an attempt to "exit the system" or "change contexts" is made.
N.B. allow_url_fopen set to On in the command line context (i.e. /etc/php/7.0/cli/php.ini) is what I had on my system but I suspect it would have no bearing on the explanation I provided even if it were set to Off unless of course you're testing by running your scripts from the command line itself. I did not test the behaviour with allow_url_fopen set to Off in the command line context.
This will also give external links an absolute path without having to use php.ini
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.your_external_website.com");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
$result = preg_replace("#(<\s*a\s+[^>]*href\s*=\s*[\"'])(?!http)([^\"'>]+)([\"'>]+)#",'$1http://www.your_external_website.com/$2$3', $result);
echo $result
?>
Enable allow_url_fopen From cPanel Or WHM in PHP INI Section
Add:
allow_url_fopen=1
in your php.ini file. If you are using shared hosting, create one first.
I have a script that reads RSS feeds using fopen & fgets.
When trying to the feed at: http://rss.fok.nl/feeds/nieuws my script hangs until the max_timeout of the PHP is reached.
The thing is:
it worked perfectly (on the same url) until today.
it still works on my development mac MAMP server.
it doesn't work on the production WAMP server (php 5.2.8)
I tried fread with no success.
any ideas?
Well, it's more of a workaround than an answer, but I had to resort to it.
I used the following to switch over to curl, using this function:
function curl_get_file_contents($URL)
{
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_URL, $URL);
$contents = curl_exec($c);
curl_close($c);
if ($contents) return $contents;
else return FALSE;
}
I found it here: http://il.php.net/manual/en/function.file-get-contents.php
btw, in case anyone wants to dig deeper, according to other reports of fgets hanging, it seems it has something to do with the 'feof' or lack thereof...
Perhaps try to debug your connection using wireshark (Ethereal). This should give you the reason. Perhaps the webserver is blocking your requests because of the user-agent.
Can you download the file manually on the Windows machine?
We are using shared hosting and the follow features are disabled.
file_uploads = Off
allow_url_fopen = Off
allow_url_include = Off
We are unable to change hosting and need to figure out some workarounds. The hosting co is also not able/willing to enable these features.
For example:
We are calling 1 server from another in order to get content. So we do an include but since URL file include is disabled we are not sure what options we have to get the content on that second server and store it there using some kind of cache.
We control the content server fully (dedicated) so we can do whatever necessary just not sure if there is some easy solution to the problem.
Since you're looking to retrieve remote content the easiest way will be to write the functionality to fetch the content yourself with something like curl (php.net/curl)
Have you tried something like this:
http://www.humanumbrella.com/2007/12/08/how-to-download-a-remote-file-in-php-and-then-save-it/
It depends on how locked down the server is. The given examples (using curl functions or fsockopen) should not be hampered by the restrictions you mentioned.
You can solve your problem like this
a) Create mechanism in dedicated server to fetch any file (plus some kind of key based authentication and restrictions on paths where files can be fetched from)
eg: A url that says get_file?path=/path/to/file&key=security_key
b) Write a function to fetch this as if from a local file
function fetch_file($path) {
$ch = curl_init("http://www.example.com/get_file?path=$path&key=security_key");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
Then you can eval the returned string and that would be like including the file
eval fetch_file($path);
Another solution to write to the server if php file upload is prevented is to ftp the file on to your server and include the file.