PHP : file_get_contents($loc) fails - php

I just moved a project from localhost over to my remote server, and noticed that some of my scripts stopped working. Most importantly was one that relied upon file_get_contents() to fetch JSON values from another script.
PHP Version is 5.2.4
allow_url_fopen is ON
Warning: file_get_contents() [function.file-get-contents]: php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/html/2009/functions/functions.products.php on line 5
Warning: file_get_contents(http://data.example.com/new-data.php) [function.file-get-contents]: failed to open stream: Success in /var/www/html/2009/functions/functions.products.php on line 5
The script is being ran from: http://www.example.com
The location passed into the function is http://data.example.com/new-data.php
Note: Same domain name, but two different servers.
function getData() {
$location = "http://data.mysite.com/new-data.php";
$contents = file_get_contents($location);
$jsonVars = json_decode($contents);
return $jsonVars
}

Name or service not known
DNS is broke. Can you ping data.mysite.com from a shell on the machine (assuming you have one)?
Try replacing data.mysite.com with a fixed IP address for now.

Also you can try curl:
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, 'http://url.url');
$result = curl_exec($curl);
curl_close($curl);
And you get what you want in $result.

Look at your /etc/hosts on the remote server. If it's empty, you need to add '127.0.0.1 localhost' to it.
Unless it's one of the varieties of VPS where the loopback interface hits the outer machine; on those, you need to use your VPS's IP number instead of 127.0.0.1.

If you are sure it is not a DNS issue, try restarting Apache. This solved it for me after 20 minutes of head scratching.

Please include more information, does $contents contain anything? Remember to do json_decode($contents, true) if you want it as a php array otherwise its a stdClass that gets returned.
Could it have a problem resolving the hostname? is data.mysite.com the same machine as mysite.com?

Related

Can't access file via PHP script, but can open it in browser

I have an url with RSS feed:
$url = 'http://www.myurl.com/sth?format=RSS';
I can open it in a browser without a problem. But
$feed->load($url)
returned 'false'. So I started investigating:
$ch = curl_init($file);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print curl_error($ch); // prints 'couldn't connect to host'
echo "CODE: ".$retcode; // $retcode is 0
$file_headers = get_headers($file);
echo $file_headers[0]; // is null
So, what can be the reason for such behaviour? Is some port blocked on myurl.com server? Is there a way to work around it (like create local copy of the file and work on it)?
Probably the site has some block for external connections implemented, such check for User-Agent, referal...
maybe the server is doing some sniffing and doesnt serve anything on that url if it finds that curl is doing the work. you could try phantomJS and/or Selenium to get around such filters. Selenium has PHP bindings.
If you're on CentOS (known issue on that flavour), do the following to test and make sure that's the not issue. later you can later issue specific filtering.
> emacs /etc/selinux/config
locate following line
SELINUX=enforcing
Change this to
SELINUX=disabled
save the file and try again. it could be your localhost firewall if you can open it in a browser without a problem.
if this is an issue, set SELinux back to enforcing and issue
setsebool -P httpd_can_network_connect
if you want httpd to be able to connect to tcp ports

How to resolve cURL Error (7): couldn't connect to host?

I send an item code to a web service in xml format using cUrl(php). I get the correct response in localhost, but when do it server it shows
cURL Error (7): couldn't connect to host
And here's my code:
function xml_post($post_xml, $url)
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_xml);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
// curl_setopt($ch, CURLOPT_PORT, $port);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
if ($curl_errno > 0) {
echo "cURL Error ($curl_errno): $curl_error\n";
} else {
echo "Data received\n";
}
curl_close($ch);
echo $data;
}
I send the item code to the tally and fetch the details from it. I tried using both the versions php 4+ and php5+, nothing works out Any solution.
CURL error code 7 (CURLE_COULDNT_CONNECT)
is very explicit ... it means Failed to connect() to host or proxy.
The following code would work on any system:
$ch = curl_init("http://google.com"); // initialize curl handle
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
print($data);
If you can not see google page then .. your URL is wrong or you have some firewall or restriction issue.
“CURL ERROR 7 Failed to connect to Permission denied” error is caused, when for any reason curl request is blocked by some firewall or similar thing.
you will face this issue when ever the curl request is not with standard ports.
for example if you do curl to some URL which is on port 1234, you will face this issue where as URL with port 80 will give you results easily.
Most commonly this error has been seen on CentOS and any other OS with ‘SElinux’.
you need to either disable or change ’SElinux’ to permissive
have a look on this one
http://www.akashif.co.uk/php/curl-error-7-failed-to-connect-to-permission-denied
Hope this helps
If you have tried all the ways and failed, try this one command:
setsebool -P httpd_can_network_connect on
In PHP, If your network under proxy. You should set the proxy URL and port
curl_setopt($ch, CURLOPT_PROXY, "http://url.com"); //your proxy url
curl_setopt($ch, CURLOPT_PROXYPORT, "80"); // your proxy port number
This is solves my problem
In my case I had something like cURL Error (7): ... Operation Timed Out. I'm using the network connection of the company I'm working for. I needed to create some environment variables. The next worked for me:
In Linux terminal:
$ export https_proxy=yourProxy:80
$ export http_proxy=yourProxy:80
In windows I created (the same) environment variables in the windows way.
I hope it helps!
Regards!
Are you able to hit that URL by browser or by PHP script? The error shown is that you could not connect. So first confirm that the URL is accessible.
Check if port 80 and 443 are blocked. or enter - IP graph.facebook.com and enter it in etc/hosts file
you can also get this if you are trying to hit the same URL with multiple HTTP request at the same time.Many curl requests wont be able to connect and so return with error
This issue can also be caused by making curl calls to https when it is not configured on the remote device. Calling over http can resolve this problem in these situations, at least until you configure ssl on the remote.
In my case, the problem was caused by the hosting provider I was using blocking http packets addressed to their IP block that originated from within their IP block. Un-frickin-believable!!!
For a couple of days I was totally blocked on this. I'm very very new to networking/vms but was keen to try set it up myself instead of paying a hosting company to do it for me.
Context
I'm rebuilding the server side for an app that uses php routines to return various bits of data from internal sources as well as external APIs for a map based app. I have started an Oracle VM instance and have installed/set up Apache and php. All running totally fine, until one of my php routines tries to execute a cURL. I start implementing error logging to find that I don't even get a message - just '7', despite implementation being very similar to the above. My php routine accessing an internal file for data was running successfully so I was fairly sure it wasn't an Apache or php issue. I also checked my Apache error logs, nothing telling.
Solution
I nearly gave up - there's talk on disabling SELinux above and in other articles, I tried that and it did work for my purposes, but here's a really good article on why you shouldn't disable SELinux https://www.electronicdesign.com/technologies/embedded-revolution/article/21807408/dont-do-it-disabling-selinux
If temporarily disabling it works and like me you don't want to do this (but it confirms that SELinux is blocking you!), I found a neat little command that actually prints out any SELinux issues in a more readable fashion:
sealert -a /var/log/audit/audit.log
This returned the following:
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------
SELinux is preventing php-fpm from name_connect access on the tcp_socket port 443.
Great, I now get a bit more information than just '7'. Reading further down, I can see it actually makes suggestions:
***** Plugin catchall_boolean (24.7 confidence) suggests ******************
If you want to allow httpd to can network connect
Then you must tell SELinux about this by enabling the 'httpd_can_network_connect' boolean.
Do
setsebool -P httpd_can_network_connect 1
This has been mentioned further above but now I have a bit more context and an explanation as to what it does. I run the command, and I'm in business. Furthermore, my SELinux is still set to enforcing, meaning my machine is more secure.
There are many other suggestions logged out, if you're blocked it might be worth logging out/checking out /var/log/audit/audit.log.

file_get_contents and curl doesn't work, blocked tcp port problem

I'm trying to write a Joomla module which will parse json data from springer api. I have problem with the method "file_get_contents" and other replacements. My problem is that:
Warning: file_get_contents(http://www.example.com) [function.file-get-contents]: failed to open stream: A socket operation was attempted to an unreachable network. in C:\wamp\www\modules\mod_springer\mod_springer.php on line 72
After some search, I found out that it may be because of my company's firewall. Is there any way to overcome this problem like changing port I'm using or using another method, or am I stuck here?
Note: allow_url_fopen is enabled. I'm using wamp.
You're not stuck if you can convince the powers-that-be to allow you access through the firewall to the remote API to which you wish to connect. As long as you have a legitimate reason and the firewall access can be provisioned in a narrow scope (one specific IP and port), I don't see why you should have a problem getting this access.
Download cacert.pem file from here
Copy cacert.pem file to for example c:/wamp/bin/php/extras/ssl folder
Write or uncomment in php.pni curl.cainfo ="c:/wamp/bin/php/extras/ssl/cacert.pem" and save
Restart Wamp/Xampp server
DONE
It may be possible (MAYBE) to overcome the issue with cURLs proxy handling like:
curl_setopt($ch, CURLOPT_PROXY, "http://xxx.xxx.xxx.xxx:8080");
curl_setopt($ch, CURLOPT_PROXYPORT, 8080);
curl_setopt ($ch, CURLOPT_PROXYUSERPWD, "xxx:xxx");
This would depend on a few things like the permissions you have, if it is just a blocked port or if it is access control.

How to identify server IP address in PHP

How can I identify the server IP address in PHP?
Like this for the server ip:
$_SERVER['SERVER_ADDR'];
and this for the port
$_SERVER['SERVER_PORT'];
If you are using PHP version 5.3 or higher you can do the following:
$host= gethostname();
$ip = gethostbyname($host);
This works well when you are running a stand-alone script, not running through the web server.
for example:
$_SERVER['SERVER_ADDR']
when your on IIS, try:
$_SERVER['LOCAL_ADDR']
I came to this page looking for a way of getting my own ip address not the one of the remote machine connecting to me.
This will not work for a windows machine.
But in case someone searches for what I was looking for:
#! /usr/bin/php
<?php
$my_current_ip=exec("ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'");
echo $my_current_ip;
(Shamelessly adapted from How to I get the primary IP address of the local machine on Linux and OS X?)
Neither of the most up-voted answers will reliably return the server's public address. Generally $_SERVER['SERVER_ADDR'] will be correct, but if you're accessing the server via a VPN it will likely return the internal network address rather than a public address, and even when not on the same network some configurations will will simply be blank or have some other specified value.
Likewise, there are scenarios where $host= gethostname(); $ip = gethostbyname($host); won't return the correct values because it's relying on on both DNS (either internally configured or external records) and the server's hostname settings to extrapolate the server's IP address. Both of these steps are potentially faulty. For instance, if the hostname of the server is formatted like a domain name (i.e. HOSTNAME=yahoo.com) then (at least on my php5.4/Centos6 setup) gethostbyname will skip straight to finding Yahoo.com's address rather than the local server's.
Furthermore, because gethostbyname falls back on public DNS records a testing server with unpublished or incorrect public DNS records (for instance, you're accessing the server by localhost or IP address, or if you're overriding public DNS using your local hosts file) then you'll get back either no IP address (it will just return the hostname) or even worse it will return the wrong address specified in the public DNS records if one exists or if there's a wildcard for the domain.
Depending on the situation, you can also try a third approach by doing something like this:
$external_ip = exec('curl http://ipecho.net/plain; echo');
This has its own flaws (relies on a specific third-party site, and there could be network settings that route outbound connections through a different host or proxy) and like gethostbyname it can be slow. I'm honestly not sure which approach will be correct most often, but the lesson to take to heart is that specific scenarios/configurations will result in incorrect outputs for all of these approaches... so if possible verify that the approach you're using is returning the values you expect.
This is what you could use as an adaptation of the above examples without worrying about curl installed on your server.
<?php
// create a new cURL resource
$ch = curl_init ();
// set URL and other appropriate options
curl_setopt ($ch, CURLOPT_URL, "http://ipecho.net/plain");
curl_setopt ($ch, CURLOPT_HEADER, 0);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
// grab URL and pass it to the browser
$ip = curl_exec ($ch);
echo "The public ip for this server is: $ip";
// close cURL resource, and free up system resources
curl_close ($ch);
?>
Check the $_SERVER array
echo $_SERVER['SERVER_ADDR'];
The previous answers all give $_SERVER['SERVER_ADDR']. This will not work on some IIS installations. If you want this to work on IIS, then use the following:
$server_ip = gethostbyname($_SERVER['SERVER_NAME']);
If you are using PHP in bash shell you can use:
$server_name=exec('hostname');
Because $_SERVER[] SERVER_ADDR, HTTP_HOST and SERVER_NAME are not set.
I found this to work for me:
GetHostByName("");
Running XAMPP v1.7.1 on Windows 7 running Apache webserver.
Unfortunately it just give my gateway IP address.
I just created a simple script that will bring back the $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR'] in IIS so you don't have to change every variable. Just paste this text in your php file that is included in every page.
/** IIS IP Check **/
if(!$_SERVER['SERVER_ADDR']){ $_SERVER['SERVER_ADDR'] = $_SERVER['LOCAL_ADDR']; }
if(!$_SERVER['REMOTE_ADDR']){ $_SERVER['REMOTE_ADDR'] = $_SERVER['LOCAL_ADDR']; }
$serverIP = $_SERVER["SERVER_ADDR"];
echo "Server IP is: <b>{$serverIP}</b>";
You may have to use $HTTP_SERVER_VARS['server_ADDR'] if you are not getting anything from above answers and if you are using older version of PHP
You can use https://icanhazip.com and since Cloudflare owned this project sometimes it can be even more reliable.
$my_real_ip = file_get_contents('https://icanhazip.com/');
Check the $_SERVER array
echo $_SERVER['SERVER_ADDR'];
Here is one solution when the site is running behind a load-balancer, a reverse proxy server, or a CDN like CloudFront:
$conn = curl_init();
curl_setopt($conn, CURLOPT_URL, 'any.valid.url');
curl_exec($conn);
$WebServerIP = curl_getinfo($conn)['local_ip'];
To accurately get the external IP address, you can call checkip.amazonaws.com, a service provided by Amazon.
$ip = exec("curl https://checkip.amazonaws.com");
As we can see it's such a widespread problem that AWS has created that very tool for the world to use.
I would use that over other similar services, since it's provided by AWS and will probably be around for long.
Like this:
$_SERVER['SERVER_ADDR'];

PHP file() generates error: failed to open stream

I have a script with line:
$id = strtolower(implode('',file($ip_service . $ip)));
When executed the file function will be like file(http://www.url.com/filename.php?119.160.120.38)
On server A it works fine but on Server B it gives following error:
file(http://www.url.com/filename.php?xxx.xxx.xxx.xxx) [function.file]: failed to open stream: Connection timed out in /home/path/filename.php on line 22
Line 22 is the above line of code.
Server A has PHP 4.4.6, Server B has 4.4.8
Any help will be highly appreciated.
Using file() and/or file_get_contents() for accessing files across the internet is fairly error prone. For example, I don't think they follow redirects. The timeout period is also very short, not the typical network timeout. It's also difficult to do error capture to see why it failed.
I always use CURL for accessing files over the network. It takes a few more lines of code, but is much more reliable. Note, PHP CURL support may not be installed in your setup.
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_URL, 'http://www.url.com/filename.php?119.160.120.38');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
if ( $result==false ) {
echo curl_errno($ch).' '.curl_error($ch);
}
curl_close($ch);
Obviously you would want to do something beside echo out the error message if there was an error. The $result variable will have the contents of the file if it succeeds.
Your server couldn't establish a tcp/ip connection to the server hosting www.url.com in a given time period (20 seconds? 30 seconds? What ever the default is or what you have specified as timeout). The other server didn't even reject the connection actively, there just wasn't any response at all. Could be e.g. a firewall issue where some or all of your or the other server's packets where silently dropped.

Categories