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.
Related
I am using two files (test1.php and test2.php)
In test1.php having multi_curl code
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "test2.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
And in the second (test2.php) I am put the error_log() for creating the log.
error_log('test message', 3, ABSPATH.'error_log12.txt');
When, I am hitting the first file through browser it'll create correct log into define location but when, I am hitting first file through terminal it will not create that log.
Please anyone suggest me, what was the reason behind it.
Depending on your platform, version, and possibly the phase of the moon, PHP can maintain several php.ini files for various invocation methods, including CLI, FPM, and whatever other adapters you may have installed. I would expect the file you're not explicitly setting error logging in to behave in whatever way those respective ini files define, so that's the first place I'd look.
I have a problem where my hosting company won't let me run a cron job in this format from my control panel:
/usr/bin/php /home/sites/MYDOMAIN.com/index.php?option=com_community&task=cron
Or:
www.MYDOMAINNAME.com/index.php?option=com_community&task=cron
Now if i run the second job in a browser i.e.:
www.MYDOMAINNAME.com/index.php?option=com_community&task=cron
this works fine in a browser
My support says I have to create a file to run the URL. The only problem is I don’t know how to run a URL in PHP. I have asked a few sites. But nothing. My file is called bump.php and has the following code:
lynx -dump http://www.MYDOMAIN.com/index.php?option=com_community&task=cron
this is what i have in the file
<?php
echo file_get_contents('DOMAIN.com/index.php?option=com_community&task=cron');
?>
You have to access the file in question via your webserver, not directly by file access. If you access it by file-access, it will just return the php code and not execute it.
There are several options on how to access files via webserver. One is your shown method with file_get_contents. You will need to add http:// in front of the url to tell PHP that you want it accessed remotly and not as a local file.
file_get_contents is not allways configured to allow remotely downloading files. In these cases, it will not work. You can check this link to see the configuration setting for remote accessing files:
http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
Another solution is to use the curl extension (if available)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
http://www.php.net/manual/en/function.curl-exec.php
There are other extensions if curl is also not available...
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
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?
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.