PHP ini file_get_contents external url
Asked Answered
S

8

48

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.

Stets answered 15/8, 2010 at 17:23 Comment(0)
G
47

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.

Gottschalk answered 15/8, 2010 at 17:24 Comment(3)
This is not entirely correct. You can use cURL with file_get_contents() with the configure option --with-curlwrappers.Contentious
@Contentious I don't understand. Please elaborate.Gottschalk
If you compile the curl extension with --with-curlwrappers, curl will be used to make a HTTP request whenever you do file_get_contents("http://example.com/stuff"). My point was that curl and file_get_contents are not orthogonal, it's not "use one or the other".Contentious
C
51

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');
Chippewa answered 15/8, 2010 at 18:26 Comment(1)
this is awesome.. I just replaced aall of my "filt_get_content($url).... functions to "get_content($url) and placed your function the top of file.. and wow.. all functions run so smoothly..Elude
G
47

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.

Gottschalk answered 15/8, 2010 at 17:24 Comment(3)
This is not entirely correct. You can use cURL with file_get_contents() with the configure option --with-curlwrappers.Contentious
@Contentious I don't understand. Please elaborate.Gottschalk
If you compile the curl extension with --with-curlwrappers, curl will be used to make a HTTP request whenever you do file_get_contents("http://example.com/stuff"). My point was that curl and file_get_contents are not orthogonal, it's not "use one or the other".Contentious
S
5
$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

Simulation answered 28/2, 2013 at 9:55 Comment(0)
C
4

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"], "."); 
Contentious answered 15/8, 2010 at 17:24 Comment(0)
G
3

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.

Gui answered 5/6, 2017 at 17:2 Comment(0)
P
1

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
?>
Pigeonwing answered 25/7, 2012 at 12:50 Comment(0)
H
1

Enable allow_url_fopen From cPanel Or WHM in PHP INI Section

H answered 1/2, 2021 at 19:9 Comment(0)
I
0

Add:

allow_url_fopen=1

in your php.ini file. If you are using shared hosting, create one first.

Insightful answered 31/3, 2012 at 8:10 Comment(1)
You may also add some background information so people know why and not only what to do.Cerys

© 2022 - 2024 — McMap. All rights reserved.