Making a REST API request in PHP - php

Apologies for newbishness of this question. I'm looking into integrating one website's API into my own website. Here's some quotes from their documentation:
At the moment we only support XML,
when calling our API the HTTP Accept
header content type must be set to
“application/xml”.
The API uses the PUT request method.
I have the XML I want to send, and I have the URL I want to send it to, but how do I go about constructing a suitable HTTP Request in PHP that will also grab the XML that's returned?
Thanks in advance.

You can use file_get_contents and stream_context_create to create a request and read the response. Something like this will do it:
$opts = array(
"http" => array(
"method" => "PUT",
"header" => "Accept: application/xml\r\n",
"content" => $xml
)
);
$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);

This is actually what worked for me:
$fp = fsockopen("ssl://api.staging.example.com", 443, $errno, $errstr, 30);
if (!$fp)
{
echo "<p>ERROR: $errstr ($errno)</p>";
return false;
}
else
{
$out = "PUT /path/account/ HTTP/1.1\r\n";
$out .= "Host: api.staging.example.com\r\n";
$out .= "Content-type: text/xml\r\n";
$out .= "Accept: application/xml\r\n";
$out .= "Content-length: ".strlen($xml)."\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= $xml;
fwrite($fp, $out);
while (!feof($fp))
{
echo fgets($fp, 125);
}
fclose($fp);
}

Related

PHP fire and forget not working with remote server

I'm trying to send a request to a remote server using the fire-and-forget approach. This is my code:
function backgroundPost($url, $data = array()){
$parts=parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port'])?$parts['port']:80,
$errno, $errstr, 30);
if (!$fp) {
return false;
} else {
$encoded_data = json_encode($data);
$output = "POST ".$parts['path']." HTTP/1.1\r\n";
$output .= "Host: ".$parts['host']."\r\n";
$output .= "Content-Type: application/json\r\n";
$output .= "Content-Length: " . strlen($encoded_data) . "\r\n";
$output .= "Connection: Close\r\n\r\n";
$output .= $encoded_data;
fwrite($fp, $output);
fclose($fp);
return true;
}
}
//Example of use
backgroundPost('url-here', array("foo" => "bar"));
but the data that arrives is simply empty.
When I spin up the application locally and send the request to my own machine instead, the data does arrive.
Am I misunderstanding something about this pattern?
Why is it working when sending a request to my own machine but not a remote one?
Thanks!

How to make a request to over HTTPS via file_get_contents() without openssl by not verifying ssl?

I am making an application that deals with postbacks, and I wanted to make it so it would be able to postback to domains with https:// even if the person who is using the app doesn't have the openssl php extension. (It would warn them that their postbacks would be made non securely.)
I turned off openssl and tried the following, but it is giving me an error that I do not have https wrapper.
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
);
echo file_get_contents('https://httpbin.org/get?test=test', true, stream_context_create($arrContextOptions) );
Is it possible to make this request with file_get_contents?
Try this code:
<?php
$fp = fsockopen("ssl://somedomain/abc/", 2000 , $ErrNo, $ErrString, 30);
if (!$fp) {
echo "Error No : $ErrNo - $ErrString <br />\n";
} else {
$out = "POST / HTTP/1.1\r\n";
$out .= "Host: somedomain \r\n";
$out .= "Content-Type: application/xml; charset=utf-8;\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
I have research file_get_contents with --no-check-certificate
readmore here file_get_contents ignoring verify_peer=>false?

Socket programming: socket_read, fgets cannot get response

I am trying to get a response from a URL using socket programming, but nothing is working correctly. I am using PHP, and I am told by the developer I am working with that I need to open a socket, send a request, and then I should get a JSON response. the $message is the string that needs to be sent in order to receive a response.
This is what I have tried so far...
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678);
fputs($response, $message);
fgets($response, 2048);
$data = json_decode($response, true);
And then I go on to parse the JSON response.
I have also tried,
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678);
fputs($response, $message);
socket_read($response, 2048, PHP_NORMAL_READ);
$data = json_decode($response, true);
But then I get an error stating that socket_read is not the correct resource. Any help would be appreciated.
You need to do some error checking, at least. Maybe this will help:
$message = "api\tjson\tget\trooms\n";
$response = fsockopen("142.4.xxx.xxx", 5678, $errno, $errstr, 30);
if (!$response) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "POST /script.php HTTP/1.1\r\n";
$out .= "Host: www.webste.com\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= 'Content-Length: ' . strlen($message) . "\r\n\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($response, $out);
fwrite($response, $message);
while (!feof($response)) {
echo fgets($response, 128);
}
fclose($response);
}

server not sending custom header values

I'm using PHP 5.2.17 to get a remote page, the HTTP requests contains some cookie values but cookies are not delivered to the destination page.
$url = 'http://somesite.com/';
$opts = array(
'http' => array
(
'header' => array("Cookie: field1=value1; field2=value2\r\n")
)
);
$context = stream_context_create($opts);
echo file_get_contents($url, false, $context);
Can you help me find the problem?
Note: I can't use curl.
Thanks.
Are you sure the receiving code is working properly?
I can get your example to work with the receiving page simply echoing:
<?php
echo $_COOKIE['field1'] . '::' . $_COOKIE['field2']; // returns value1::value2
?>
Alternatively, the site could be requiring a user agent (anything). I had this problem earlier in reaching Wikipedia (not restricted by all Mediawiki software; apparently just for the Wikimedia sites). Set the user_agent property inside the 'http' array to whatever value you want. (However, if you do happen to be trying to reach Wikipedia, you might instead try their api.php: http://en.wikipedia.org/w/api.php ; if another Mediawiki site, use the same relative path)
Maybe allow_url_fopen is not enabled, check the value w/ ini_get: ini_get('allow_url_fopen');
You might also do a sanity check by calling file_get_contents() on any old page you know is publicly accessible.
Other than that your example code looks just fine.
Second Option, Socket Connection:
<?php
$fp = fsockopen("somesite.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: somesite.com\r\n";
$out .= "Cookie: field1=value1; field2=value2; path=/; domain=somesite.com;\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
echo PHP_EOL;
$url = 'http://somesite.com/';
$opts = array(
'http' => array
(
'header' => "Cookie: field1=value1; field2=value2\r\n"
)
);
$context = stream_context_create($opts);
file_get_contents($url, false, $context);

Need to change fsocketopen to CURL to be able to navigate redirects

I have a php script that I recently added an array to. The php script checks URL's from the array for a set of text also in the array. Everything works great except the script will not follow redirects or check sub-pages.
I have been told that this is a limitation of fsocketopen and that I need to use CURL.
If this is the case then I require some assistance converting this from using fsocketopen to CURL. Hopefully there is some way to get fsocketopen to follow redirects or at least access sub-pages.
function check($host, $find){
$fp = fsockopen($host, 80, $errno, $errstr, 10);
if (!$fp){
echo "$errstr ($errno)\n";
} else {
$header = "GET / HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "Connection: close\r\n\r\n";
fputs($fp, $header);
while (!feof($fp)) {
$str.= fgets($fp, 1024);
}
fclose($fp);
return (strpos($str, $find) !== false);
}
}
function alert($host){
$headers = 'From: Set your from address here';
mail('my-email#my-domain.com', 'Website Monitoring', $host.' is down' $headers);
}
$hostMap = array(
'www.my-domain.com' => 'content on site',
'www.my-domain2.com' => 'content on second site',
);
//if (!check($host, $find)) alert($host);
foreach ($hostMap as $host => $find){
if( !check( $host, $find ) ){
alert($host);
}
}
unset($host);
unset($find);
Apparently I wasn't clear in my question. I am looking for confirmation that fsocketopen cannot follow redirects or that it cannot go to a sub-page (url.com/subpage).
If this is the case, is CURL my best option and are there any examples I can look at?
When you get the data returned from feof(), you can parse out the redirect information from the headers and create connect to that, but that is kind of annoying and cURL does it on its own.
You should just be able to use
$ch = curl_init($host);
curl_setopt_array($ch, array(
CURLOPT_RETUNTRANSFER => true
, CURLOPT_FOLLOWLOCATION => true
, CURLOPT_HEADER => true
));
$str = curl_exec($ch);
cURL follows redirects by default using the Location: header.

Categories