php file_get_contents cannot read xml service - php

I want to read and parse the xml data from an url.My url is:"http://xml.gamebookers.com/sports/bandy.xml".I can access xml data from browser.However,when i attempt to read it by using php it doesnt work.It errors like this:
Warning: file_get_contents(http://xml.gamebookers.com/sports/bandy.xml): failed to open stream: Connection timed out in
How can i fix this?Any comments on this?
Thanks in advance..

Please see here for an answer:
This error is most likely connected to
too many (HTTP) redirects on the way
from your script to the file you want
to open. The default redirection
limit should be 20. As 20
redirects are quite alot there could
be some error in the filename itself
(causing e.g. the webserver on the
other end to do some
spellcheck-redirects) or the other
server is misconfigured or there are
some security measures in place or...
If you feel the need to extend the 20
redirects you could use a stream
context.
$context = array(
'http'=>array('max_redirects' => 99)
);
$context = stream_context_create($context);
// hand over the context to fopen()
$data = file_get_contents('http://xml.gamebookers.com/sports/bandy.xml', false, $context);
// ...
Please see:
Streams
stream_context_create()
HTTP context options

Try the snippet:
$request_url = 'http://xml.gamebookers.com/sports/bandy.xml';
$xml = simplexml_load_file($request_url) or die("feed not loading");
/*
Then just parsing out child node of your xml.
for example
*/
foreach($xml->children() as $child)
{
echo $child->getName().": ".$child."";
}
Hope this help
PS: Open your PHP.INI and look for
allow_url_fopen = On // make sure it is ON

Related

File_get_contents failed to open stream: http request failed 404 not found

I need to add an svg file to a website and apply a class to this svg. This is frustrating, I've tried different solutions posted on here and none of them have worked for me. This worked on a different server, but after being moved to a new server it no longer works. Here is how I am calling it in the php:
<?php $svg = file_get_contents("http://www.folklorecoffee.com/wp-content/uploads/2018/04/folkloretextwhite-1.svg");
$dom = new DOMDocument();
$dom->loadHTML($svg);
foreach($dom->getElementsByTagName('svg') as $element) {
$element->setAttribute('class','logo-light');
}
$dom->saveHTML();
$svg = $dom->saveHTML();
echo $svg;?>
I'm getting these warnings:
WARNING: file_get_contents(http://www.folklorecoffee.com/wp-content/uploads/2018/04/folkloretextwhite-1.svg): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/folklorecoffee/public_html/wp-content/themes/lily/header.php on line 34
WARNING: DOMDocument::loadHTML(): Empty string supplied as input in /home/folklorecoffee/public_html/wp-content/themes/lily/header.php on line 36
But when I test the url in my browser, it comes up fine. Not sure why I'm getting a 404 error. What am I doing wrong? Thank you in advance!
The request is working for me:
echo $svg = file_get_contents("http://www.folklorecoffee.com/wp-content/uploads/2018/04/folkloretextwhite-1.svg"); // prints the SVG data as expected
You could try the same request via a different mechanism, such as cURL:
$url = "http://www.folklorecoffee.com/wp-
content/uploads/2018/04/folkloretextwhite-1.svg";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
echo $data; // prints the SVG data as expected
But if the URL is the same, I expect you will get the same result.
Given the above, the best answer is for you to do troubleshooting on your own about what is happening, since it is very specific to your setup.
You may gain some insight by looking at the Apache logs for the request. Does it show up? Does the URL it displays match what you expect?
Can you make other requests with file_get_contents to your domain that work? To the uploads folder? To other domains?
Check with your hosting provider to see if they can explain. There may be a configuration item that is interfering in some way.
Finally, you may want try investigating more carefully why the logo cannot be loaded from the file system. Is it a permissions issue? Can you load any file from the permissions directory?
I tried everyone's suggestions and I thank you all for taking your time to try to offer help, I was never able to get it to work and continued to get the same error.
Interestingly any file on my server that I tried to call with file_get_contents would get the 404 error. It didn't matter if I did a local path or the exact url, the paths were correct. Here's what it's interesting: it would work if I pointed to a file that was NOT on my server. So I'm thinking there must be a configuration setting somewhere that I would need to change. I do not know what this setting would be and if someone out there is reading this and experiencing the same issues I hope this helps point you in the right direction.
I was in a time crunch and decided instead to simply write the svg file in with an object tag and that did the trick for now. I'd prefer using a different method, and I'll revisit this again in the future and update this post if I figure out what would fix it. Thank you again for all of your help, I hope this helps someone else.

PHP curl put 500 error

I have a curl put request that works fine on my localhost but on the live server it throws back a 500 error. Here is my code:
public static function send( $xml )
{
$xml = str_replace( "\n", "", $xml );
//Write to temporary file
$put_data = tmpfile();
fwrite( $put_data, $xml );
fseek( $put_data, 0 );
$options = array(
CURLOPT_URL => 'http://*****************/cgi-bin/commctrl.pl?SessionId=' . Xml_helper::generate_session_id() . '&SystemId=live',
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPHEADER => array( 'Content-type: text/xml' ),
CURLOPT_PUT => TRUE,
CURLOPT_INFILE => $put_data,
CURLOPT_INFILESIZE => strlen( $xml )
);
$curl = curl_init();
curl_setopt_array( $curl, $options );
$result = curl_exec( $curl );
curl_close( $curl );
return $result;
}
I do have curl enabled on the server!
Does anyone have any ideas why it is not working on the server? I am on shared hosting if that helps.
I also have enabled error reporting at the top of the file but no errors show after the curl has completed. I just get the generic 500 error page.
Thanks
UPDATE:
I have been in contact with the client and they have confirmed that the information that is sent is received by them and inserted into their back office system. So it must be something to do with the response that is the cause. It is a small block of xml that is suppose to be returned.
ANOTHER UPDATE
I have tried the same script on a different server and heroku and I still get the same result.
ANOTHER UPDATE
I think I may have found the route of the issue. The script seems to be timing out because of a timeout on FastCGI and because I am on shared hosting I can not change it. Can any one confirm this?
FINAL UPDATE
I got in contact with my hosting provider and they confirmed that the script was timing out due to the timeout value on the server not the one I can access with any PHP function or ini_set().
If the error is, like you think it is, to do with a script timeout and you do not have access to the php.ini file - there is an easy fix
simply use set_time_limit(INT) where INT is the number of seconds, at the beginning of your script to override the settings in the php.ini file
Setting a timeout of set_time_limit(128) should solve all your problems and is generally accepted as a reasonable upper limit
More info can be found here http://php.net/manual/en/function.set-time-limit.php
Here are a few things to try:
Remove the variability in the script - for testing, hardcode the session id, so that the curl curl is the same. You cannot reliably test something, if it changes each time you run it.
Try using curl directly from the command line, via something like curl http://*****************/cgi-bin/commctrl.pl?SessionId=12345&SystemId=live. This will show you if the problem is really due to the computer itself, or something to do with PHP.
Check the logs on your server, probably something like /var/log/apache/error.log depending on what OS your server uses. Also look at the access log, so that you can see whether you are actually receiving the same request.
Finally, if you really run out of ideas, you can use a program like wireshark or tcpdump/WinDump to monitor the connection, so that you can compare the packets being sent from each computer. This will give you an idea of how they are different - are they being mangled by a firewall? Is php adding extra headers to one of them? Are different CURL defaults causing different data to be included?
I suspect your server does not support tmpfile(). Just to verify:
public static function send( $xml ) {
$xml = str_replace( "\n", "", $xml );
//Write to temporary file
$put_data = tmpfile();
if (!$put_data) die('tmpfile failed');
...
If you are on GoDaddy server check this out... https://stackoverflow.com/questions/9957397/tmpfile-returns-false-on-godaddy-server
Which server is actually showing the 500 ? from your code it seems the local server rather than the remote.
change
public static function send( $xml )
{
to
public static function send( $xml )
{
error_reporting(E_ALL);
if(!function_exists('curl_exec')) {
var_dump("NO CURL");
return false;
}
does that work ?
This is almost certainly NOT the php timeout setting.
If you are using FastCGI as you have stated then you need to edit this file:
/etc/httpd/conf.d/fcgid.conf
And change:
FcgidIOTimeout 3600
Then do:
service httpd restart
This was driving me insane for 3 days. The top voted answer to this is wrong!

PHP file_get_contents problem

I am having a problem with PHP's file_get_contents command.
$url = "http://api.rememberthemilk.com/services/rest/".$format.$auth_token.$filter."&api_sig=".$md5.$apikey.$method;
$content = file_get_contents($url);
$array = json_decode($content, true);
$taskname = $array['rsp']['tasks']['list']['taskseries']['name'];
$duedate = $array['rsp']['tasks']['list']['taskseries']['task']['due'];
($format, $auth_token, $filter, $md5, $apikey, $method are already defined in the script)
When I try to run this code this error is returned:
[function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 400 Bad request for line 101
line 101 = $content, = file_get_contents($url);
How to fix this? Thanks!!!
This url does not look great.
http://api.rememberthemilk.com/services/rest/?format=json&auth_token=AUTH_TOKEN&­filter=dueWithin:"3 days of today"&api_sig=API_SIG&api_key=API_KEY&method=rtm.tasks.getList
Encode the tokens as follows:
$filter = 'filter='.urlencode( 'dueWithin:"3 days of today"' );
Use urlencode().
Try printing the URL after concatenating the variables. Then paste the URL into the address bar of your browser and see what comes back. Because it's a web service call, your browser might not know what to do with the response. In that case you might get additional information using the command-line user agent "curl", e.g.
curl -v 'http://some-url'
curl is built in to Macs and other *nix machines and is also available for Windows.

PHP Get Content of HTTP 400 Response

I am using PHP with the Amazon Payments web service. I'm having problems with some of my requests. Amazon is returning an error as it should, however the way it goes about it is giving me problems.
Amazon returns XML data with a message about the error, but it also throws an HTTP 400 (or even 404 sometimes). This makes file_get_contents() throw an error right away and I have no way to get the content. I've tried using cURL also, but never got it to give me back a response.
I really need a way to get the XML returned regardless of HTTP status code. It has an important "message" element that gives me clues as to why my billing requests are failing.
Does anyone have a cURL example or otherwise that will allow me to do this? All my requests currently use file_get_contents() but I am not opposed to changing them. Everyone else seems to think cURL is the "right" way.
You have to define custom stream context (3rd argument of function file_get_contents) with ignore_errors option on.
As a follow-up to DoubleThink's post, here is a working example:
$url = 'http://whatever.com';
//Set stream options
$opts = array(
'http' => array('ignore_errors' => true)
);
//Create the stream context
$context = stream_context_create($opts);
//Open the file using the defined context
$file = file_get_contents($url, false, $context);

How to send cookies with file_get_contents

I'm trying to get the contents from another file with file_get_contents (don't ask why).
I have two files: test1.php and test2.php. test1.php returns a string, bases on the user that is logged in.
test2.php tries to get the contents of test1.php and is being executed by the browser, thus getting the cookies.
To send the cookies with file_get_contents, I create a streaming context:
$opts = array('http' => array('header'=> 'Cookie: ' . $_SERVER['HTTP_COOKIE']."\r\n"))`;
I'm retrieving the contents with:
$contents = file_get_contents("http://www.example.com/test1.php", false, $opts);
But now I get the error:
Warning: file_get_contents(http://www.example.com/test1.php) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
Does somebody knows what I'm doing wrong here?
edit:
forgot to mention: Without the streaming_context, the page just loads. But without the cookies I don't get the info I need.
First, this is probably just a typo in your question, but the third arguments to file_get_contents() needs to be your streaming context, NOT the array of options. I ran a quick test with something like this, and everything worked as expected
$opts = array('http' => array('header'=> 'Cookie: ' . $_SERVER['HTTP_COOKIE']."\r\n"));
$context = stream_context_create($opts);
$contents = file_get_contents('http://example.com/test1.txt', false, $context);
echo $contents;
The error indicates the server is returning a 404. Try fetching the URL from the machine PHP is running on and not from your workstation/desktop/laptop. It may be that your web server is having trouble reaching the site, your local machine has a cached copy, or some other network screwiness.
Be sure you repeat your exact request when running this test, including the cookie you're sending (command line curl is good for this). It's entirely possible that the page in question may load fine in a browser without the cookie, but when you send the cookie the site actually is returning a 404.
Make sure that $_SERVER['HTTP_COOKIE'] has the raw cookie you think it does.
If you're screen scraping, download Firefox and a copy of the LiveHTTPHeaders extension. Perform all the necessary steps to reach whatever page it is you want in Firefox. Then, using the output from LiveHTTPHeaders, recreate the exact same request requence. Include every header, not just the cookies.
Finally, PHP Curl exists for a reason. If at all possible, (I'm not asking!) use it instead. :)
Just to share this information.
When using session_start(), the session file is lock by PHP. Thus the actual script is the only script that can access the session file. If you try to access it via fsockopen() or file_get_contents() you can wait a long time since you try to open a file that has been locked.
One way to solve this problem is to use the session_write_close() to unlock the file and relock it after with session_start().
Example:
<?php
$opts = array('http' => array('header'=> 'Cookie: ' . $_SERVER['HTTP_COOKIE']."\r\n"));
$context = stream_context_create($opts);
session_write_close(); // unlock the file
$contents = file_get_contents('http://120.0.0.1/controler.php?c=test_session', false, $context);
session_start(); // Lock the file
echo $contents;
?>
Since file_get_contents() is a blocking function, both script won't be in concurrency while trying to modify the session file.
But i'm sure this is not the best manner to manipulate session with an extend connection.
Btw: it's faster than cURL and fsockopen()
Let me know if you find something better.
Just out of curiosity, are you attempting file_get_contents on a page that has a space in it? I remember trying to use fgc on a URL that had a space in the name and while my web browser parsed it just fine, fgc didn't. I ended up having to use a str_replace to replace ' ' with '%20'.
I would think that this should have been relatively easy to spot that though as it would report only half of the filename. Also, I noticed in one of these posts, someone used \r\n while defining the headers. Keep in mind that PHP doesn't like these to be in single quotes, but they work fine in double.
Make sure that file1.php exists on the server. Try opening it in your own browser to make sure!

Categories