I call myself an experienced PHP developer, but this is one drives me crazy. I'm trying to get release informations of a repository for displaying update-warnings, but I keep returning 403 errors. For simplifying it I used the most simple usage of GitHubs API: GET https://api.github.com/zen. It is kind of a hello world.
This works
directly in the browser
with a plain curl https://api.github.com/zen in a terminal
with a PHP-Github-API-Class like php-github-api
This works not
with a simple file_get_contents()from a PHP-Skript
This is my whole simplified code:
<?php
$content = file_get_contents("https://api.github.com/zen");
var_dump($content);
?>
The browser shows Warning: file_get_contents(https://api.github.com/zen): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden, the variable $content is a boolean and false.
I guess I'm missing some sort of http-header-fields, but neither can I find those informations in the API-Docs, nor uses my terminal curl-call any special header files and works.
This happens because GitHub requires you to send UserAgent header. It doesn't need to be anything specific. This will do:
$opts = [
'http' => [
'method' => 'GET',
'header' => [
'User-Agent: PHP'
]
]
];
$context = stream_context_create($opts);
$content = file_get_contents("https://api.github.com/zen", false, $context);
var_dump($content);
The output is:
string(35) "Approachable is better than simple."
Related
Trying to send the following XML data to URL below.
$xml="<?xml version='1.0' encoding='utf-8'?>
<Job>
<Name>Set-up - ".$client_name."</Name>
<Description></Description>
<ClientID>".$accountantid."</ClientID>
<StartDate>".$start_date."</StartDate>
<DueDate>".$due_date."</DueDate>
<TemplateID>".$templateid."</TemplateIDr>
</Job>";
$createjob_url="https:<url>apiKey=[apikey]&accountKey=[accountkey]";
$stream_options = array (
'http' => array (
'method' => "POST",
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'content' => $xml
)
);
$context=stream_context_create($stream_options);
$response=file_get_contents($createjob_url, false, $context);
echo "<p>".$response."</p>";
The response should come out 'OK', but its just blank.
The debug.log has the following error.
PHP Warning: file_get_contents(https:<url>?apiKey=[apikey]&accountKey=[accountkey]): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error
I noticed the URL changes the '&' to '&'. If I put the url directly into the browser, it doesnt work, however if I remove 'amp;' it gives me the OK response.
But then if I remove from the code 'false, $context' e.g. file_get_contents($createjob_url), the response comes back 'OK', so the URL is fine.
I am using Google App Engine hence unable to use cURL.
I assume it has something to do with my stream options? Any feedback would be greatly appreciated.
So looks like my issue was a couple of small things.
For the particular URL I was parsing to, I didnt need to have the XML tag, so removed <?xml version='1.0' encoding='utf-8'?>
They also wanted the content type as xml, so changed it to 'header' => "Content-type: text/xml"
Once I got these two sorted, all worked well :)
I'm having some issues with calling WordPress XML-RPC via cURL in PHP. It's a WordPress.com hosted blog, and the XML-RPC file is located at http://sunseekerblogbook.com/xmlrpc.php.
Starting yesterday (or at least, yesterday was when it was noticed), cURL has been failing with error #52: Empty reply from server.
The code snippet we're using is below:
$ch = curl_init('http://sunseekerblogbook.com/xmlrpc.php');
curl_setopt_array($ch, [
CURLOPT_HEADER => false,
CURLOPT_HTTPHEADER => [
'Content-Type: text/xml'
],
CURLOPT_POSTFIELDS => xmlrpc_encode_request('wp.getPosts', [
1,
WP_USERNAME,
WP_PASSWORD,
[
'number' => 15
]
]),
CURLOPT_RETURNTRANSFER => true
]);
$ret = curl_exec($ch);
$data = xmlrpc_decode($ret, 'UTF-8');
Using cURL directly however, everything returns exactly as expected:
$output = [];
exec('curl -d "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>wp.getPosts</methodName><params><param><value><int>1</int></value></param><param><value><string>' . WP_USERNAME . '</string></value></param><param><value><string>' . WP_PASSWORD . '</string></value></param><param><value><struct><member><name>number</name><value><int>15</int></value></member></struct></value></param></params></methodCall>" sunseekerblogbook.com/xmlrpc.php', $output);
$data = xmlrpc_decode(implode('', $output), 'UTF-8');
We've been successfully able to query WordPress since July 2013, and we're at a dead-end as to why this has happened. It doesn't look like PHP or cURL have been updated/changed recently on the server, but the first code snippet has failed on every server we've tried it on now (with PHP 5.4+).
Using the http://sunseekerblogbook.wordpress.com/xmlrpc.php link gives the same issue.
Is there anything missing from the PHP code that would cause this issue? That it's suddenly stopped working over 12 months down the line is what has flummoxed me.
Managed to fix it. Looking at the headers sent by cURL, the only differences were that the cURL command line uses Content-Type: application/x-www-form-urlencoded and that the user agent was set to User-Agent: curl/7.30.0.
The choice of content type didn't affect it, but setting a user agent sorted it! It seems WordPress.com (but not self-hosted WordPress.org sites running the latest v3.9.2) now requires a user agent for XML-RPC requests, though this hasn't been documented anywhere that I can find.
I'm trying to scrape data from some websites. For several sites it all seems to go fine, but for one website it doesn't seem to be able to get any HTML. This is my code:
<?php include_once('simple_html_dom.php');
$html = file_get_html('https://www.magiccardmarket.eu/?mainPage=showSearchResult&searchFor=' . $_POST['data']);
echo $html; ?>
I'm using ajax to fetch the data. When I log the returned value in my js it's completely empty.
Could it be due to the fact that this website is running on https? And if so, is there any way to work around it? (I've tried changed the url to http, but I get the same result)
Update:
If I var_dump the $html variable, I get bool(false).
My PHP error log says this:
[27-Feb-2014 22:20:50 Europe/Amsterdam] PHP Warning: file_get_contents(http://www.magiccardmarket.eu/?mainPage=showSearchResult&searchFor=tarmogoyf): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden
in /Users/leondewit/PhpstormProjects/Magic/stores/simple_html_dom.php on line 75
It's your user agent, file_get_contents doesn't send one by default, so:
$url = 'http://www.magiccardmarket.eu/?mainPage=showSearchResult&searchFor=tarmogoyf';
$context = stream_context_create(array('http' => array('header' => 'User-Agent: Mozilla compatible')));
$response = file_get_contents($url, false, $context);
$html = str_get_html($response);
echo $html;
When using the get_headers() php function in a deployed app, e.g.:
$aHeaders = get_headers("http://[...].mp3", 1);
echo $aHeaders['Content-Length'];
I get the following error:
PHP Warning: get_headers(http://[...].mp3): failed to open stream:
Response too large in /base/data/home/apps/[...]/main.php
The error doesn't appear when the file is small (e.g. 100kb).
I need to get the size of a file on an external server without having to download it. Also, I can't use curl as it is not supported by GAE. Any ideas?
do you try to do an HEAD request instead of a GET (that downloads all content)?
stream_context_set_default(
array(
'http' => array(
'method' => 'HEAD'
)
)
);
$headers = get_headers('http://[...].mp3', 1);
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);