How to call RESTful WCF-Service from PHP - php

I'm trying to send an request to an Self-Hosted WCF-Service with REST in PHP.
I want to send the object to the WCF service as an JSON Object.
I did not get it running yet.
Has anyone an example how to call the service out of PHP?
This is the Operation contract (The method is a POST method):
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
void Method1(AnObject object);
The best working Code in PHP is the following:
$url = "http://localhost:8000/webservice/Method1?object=$object";
$url1 = parse_url($url);
// extract host and path:
$host = $url1['host'];
$path = $url1['path'];
$port = $url1['port'];
// open a socket connection on port 80 - timeout: 30 sec
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if($fp)
{
// send the request headers:
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/json \r\n");
fputs($fp, "Content-length: ". strlen($object) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $object);
//
// $result = '';
// while(!feof($fp)) {
// // receive the results of the request
// $result .= fgets($fp, 128);
// }
}
else {
return array(
'status' => 'err',
'error' => "$errstr ($errno)"
);
}
// close the socket connection:
fclose($fp);
But this code does not send the object. In Debugging-Mode the Object is "null". I just see, that it enters the method.

I found the solution for my own problem:
$url = "http://localhost:1234/service/PostMethod";
$jsonObject = json_encode($transmitObject);
$options = array(
CURLOPT_HTTPHEADER => array(
"Content-Type:application/json; charset=utf-8",
"Content-Length:".strlen($jsonObject)));
$defaults = array(
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FORBID_REUSE => 1,
CURLOPT_TIMEOUT => 4,
CURLOPT_POSTFIELDS => $jsonObject
);
$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
curl_exec($ch);
curl_close($ch);

When you perform a POST on a WCF Rest service the raw request should look as below:
POST http://localhost:8000/webservice/Method1 HTTP 1.1
Content-Type: application/json
Host: localhost
{"object":{"ObjectId":1,"ObjectValue":60}
Assuming your AnObject looks as below:
[DataContract]
public class AnObject
{
[DataMember]
public int ObjectId {get;set;}
[DataMember]
public int ObjectValue {get;set;}
}
From your php code you are trying to send the object as a query string which is not going to work. Rather build your code to add the json string to the http body.
Use some tools like Fiddler or WireShark where you can intercept the request/response and inspect them. You can use them even to test the WCF Rest service by building a raw request.
Find some links that might be helpful:
Create a php Client to invoke a REST Service
php rest api call

I got work "der_chirurg" solution by adding parameter next to $path as below
original:
$url = "http://localhost:8000/webservice/Method1?object=$object";
fputs($fp, "POST $path HTTP/1.1\r\n");
changed to:
fputs($fp, "POST $path**?object=$object** HTTP/1.1\r\n");
and
instead of in the $url
$url = "http://localhost:8000/webservice/Method1
Finally:
url = "http://localhost:8000/webservice/Method1";
$url1 = parse_url($url);
// extract host and path:
$host = $url1['host'];
$path = $url1['path'];
$port = $url1['port'];
// open a socket connection on port 80 - timeout: 30 sec
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if($fp)
{
// send the request headers:
fputs($fp, "POST $path?value=test HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/json \r\n");
fputs($fp, "Content-length: ". strlen($param) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");

$jsonData = json_encode($object, JSON_PRETTY_PRINT);
$options = array(
'http'=>array(
'method' => "POST",
'ignore_errors' => true,
'content' => $jsonData,
'header' => "Content-Type: application/json\r\n" .
"Content-length: ".strlen($jsonData)."\r\n".
"Expect: 100-continue\r\n" .
"Connection: close"
)
);
$context = stream_context_create($options);
$result = #file_get_contents($requestUrl, false, $context);
Very important is JSON format.

Related

how do I call a php method in another Class in another file?

I have PHP code in a file 'index.php' which includes HTML. The purpose is to authenticate with Google Directory API. This is the setup of the code:
<?php
// Admin Google API settings
// Portal url:
define("CALLBACK_URL", "http://localhost/los-api/google/index.php"); //Callback URL
define("AUTH_URL", "https://accounts.google.com/o/oauth2/v2/auth"); //Used to get CODE (not Token!)
define("CLIENT_ID", "***.apps.googleusercontent.com"); // Personal
define("CLIENT_SECRET", "***"); // Personal
define("SCOPE", "https://www.googleapis.com/auth/admin.directory.device.chromeos
https://www.googleapis.com/auth/admin.directory.user
https://www.googleapis.com/auth/admin.directory.orgunit"); // Depends on what you want to do.
define("APIURL_DIRECTORY","https://www.googleapis.com/admin/directory/v1/customer/"); // For Google
Directory actions
define("CUSTOMER_ID","***"); // Personal, see: ....? voorbeeld
define("TOKEN_URL","https://oauth2.googleapis.com/token"); // URL to get Token (not code).
// Initiate code for access token
if(isset($_GET["code"])){
//DEBUG: echo "Code: ".$_GET["code"];
$url = TOKEN_URL."?";
$url .= "code=".$_GET["code"];
$url .= "&grant_type=authorization_code";
$url .= "&client_id=". urlencode(CLIENT_ID);
$url .= "&redirect_uri=". urlencode(CALLBACK_URL);
$url .= "&client_secret=". urlencode(CLIENT_SECRET);
$response = json_decode(exeCurl($url,"POST"), true);
if(isset($response)){
if(array_key_exists("access_token", $response)) {
$access_token = $response;
setcookie("LOStoken", $response['access_token'], time() + (86400 * 30), "/"); // 86400 = 1 day
}
}
} else {
if(isset($_POST['gettoken'])){
$url = AUTH_URL."?";
$url .= "response_type=code";
$url .= "&client_id=". urlencode(CLIENT_ID);
$url .= "&scope=". urlencode(SCOPE);
$url .= "&redirect_uri=". urlencode(CALLBACK_URL);
echo exeCurl($url,"GET"); //here i want to execute the 'exeCurl' function, which exists in a file 'curl.php' in the same folder
?>
curl.php
<?php
namespace CURL;
class cURL
{
// general curl method
function exeCurl($url,$method,$body="") {
$curl = curl_init(); // initiate curl
if(isset($_COOKIE["LOStoken"])){
$headers = array(
"Accept: */*",
"Accept-Encoding: gzip, deflate",
"Authorization: Bearer ". $_COOKIE["LOStoken"],
"Connection: keep-alive",
"Content-Length: ". strlen($body),
"Content-Type: application/json",
"cache-control: no-cache"
);
} else {
$headers = array(
"Accept: */*",
"Accept-Encoding: gzip, deflate",
"Cache-Control: no-cache",
"Content-Length: ". strlen($body),
"Connection: keep-alive",
"cache-control: no-cache"
);
}
// Set parameters for curl
$params = array(
CURLOPT_URL => $url, // API URL
CURLOPT_RETURNTRANSFER => true, // Return answer
CURLOPT_SSL_VERIFYPEER => false, // SSL, enable in production
//CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10, // Max redirect
CURLOPT_FOLLOWLOCATION => true, // If 301, follow redirect
CURLOPT_TIMEOUT => 30, // Max timeout
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, // HTTP version used
CURLOPT_CUSTOMREQUEST => $method, // HTTP method used
CURLOPT_HTTPHEADER => $headers); // HTTP headers
// Combine
curl_setopt_array($curl, $params);
// Curl ans
$response = curl_exec($curl);
$err = curl_error($curl); // fill with errors
curl_close($curl); // close
if ($err) {
echo "cURL Error #:" . $err; // if errors
}
if(array_key_exists("error", $response)) echo $response["error_description"];
return $response; // return ans
}
}
How do I achieve this? Through inheritance? Or to import 'curl.php' , quite stuck here
Require file, active class(with namespace thanks to #IncredibleHat for suggest) and use it how you want.
require 'curl.php'; $curlclass= new \CURL\cURL; echo $curlclass->exeCurl($url,"GET");

How to make a HTTP request to a REST service in PHP?

I was wondering if anyone could help me understand how I would go about getting the JSON back using this information? Should I use cURL or fsockopen?
GET /market/10000002/orders/buy/?type=https://api-sisi.testeveonline.com/types/683/ HTTP/1.1
Host: https://api-sisi.testeveonline.com
Authorization: Bearer jKVB8oaN9qboU5kQG4sWSoWxzSUaFkQaUyeisy8jWU3apRfYSgYsKpZGNbLh41xXEzuy-NDBX1FohEdEadaukQ2
Accept: application/vnd.ccp.eve.MarketOrderCollection-v1+json
I have tried doing this, but I have no clue whether or not this is a feasible way of doing it?
$fp = fsockopen("api.eveonline.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET /market/10000002/orders/buy/? type=https://api.eveonline.com/types/683/ HTTP/1.1\r\n";
$out .= "Host: https://api.eveonline.com\r\n";
$out .= "Authorization: Bearer ".auth."\r\n\r\n";
$out .= "Accept: application/vnd.ccp.eve.MarketOrderCollection-v1+json\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
Thanks
EDIT 1:
$opts = array('http' =>
array(
'method' => 'GET',
'header' => "Host: https://api.eveonline.com\r\n".
"Authorization: Bearer ".auth."\r\n".
"Accept: application/vnd.ccp.eve.MarketOrderCollection-v1+json\r\n"
)
);
$context = stream_context_create($opts);
$url = 'https://api.eveonline.com/';
$result = file_get_contents($url, false, $context);
This was my next attempt that I am still working on.
fsockopen is really not a good option for HTTP requests as you have to take care of everything yourself (such as compression, chunking, etc.). cURL sure is an option, but my favourite is just file_get_contents. You need to have allow_url_fopen set to On in the config, but that's not really a security risk and the function itself is very capable.

how do you enable php to enable to make http calls

After trying all night without any success, this is the code that I have should work but not working:
<?php
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://api.keynote.com/keynote/',
CURLOPT_USERAGENT => 'Codular Sample cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
if(!curl_exec($curl)){
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
// Close request to clear up some resources
curl_close($curl);
echo $resp;
?>
The error that I am getting is this:
Error: "Failed connect to api.keynote.com:80; No error" - Code: 7
On the server, I can manually bring up this url with any browser without any problems.
How do I make php connec to internet?
The thing is that fsockopen is used for opening socks (i.e connect to the specified port on the specified host/IP).
When you try to open sock to the host "http://google.com" it is like running "ping http://google.com" - you will get an error - as there is no such host "http://"
What you shout do is use http_get or curl
<?php
$response = http_get("http://www.example.com/", array("timeout"=>1), $info);
print_r($info);
?>
or remove the "http://"
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>

Google cpanel - Retrieving all shared contacts

I don't know if I'm missing something, but I just cant retrieve shared contacts from Google cpanel!?
The auth token is returned by the first request, but the next returns HTTP/1.1 401 Unknown authorization header
Docs:
https://developers.google.com/google-apps/domain-shared-contacts/
Code:
// Authentication
$post_data = array(
'accountType' => 'HOSTED',
'Email' => 'my_email#gmail.com',
'Passwd' => 'password',
'service' => 'cp',
'source' => 'the_source'
);
$post = http_build_query($post_data);
$fp = fsockopen('ssl://www.google.com', 443, $errno, $errstr, 20);
$header = "POST /accounts/ClientLogin HTTP/1.1\\r\n".
"Host: www.google.com\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($post)."\r\n".
"Connection: Close\r\n\r\n".$post;
fwrite($fp, $header);
$auth_response = '';
while($line = fgets($fp)){
$auth_response .= $line;
}
fclose($fp);
list($header, $content) = explode("\r\n\r\n", $auth_response);
preg_match('/\sauth=(.*)\s/i', $content, $matches);
$auth_token = $matches[1];
// Retrieve contacts
$response = '';
$fp = fsockopen('ssl://www.google.com', 443, $errno, $errstr, 20);
$write = "GET /m8/feeds/contacts/my_domain/full HTTP/1.1\r\n".
"Host: www.google.com\r\n".
"Authorization: my_email#gmail.com token=\"$auth_token\"\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n\r\n".
"Connection: Close\r\n\r\n";
fwrite($fp, $write);
while($line = fgets($fp)){
$response .= $line;
}
fclose($fp);
echo $response;
The ClientLogin docs state that auth header should be:
Authorization: GoogleLogin auth=yourAuthToken

PHP How To Send Raw HTTP Packet

I want to send a raw http packet to a webserver and recieve its response but i cant find out a way to do it. im inexperianced with sockets and every link i find uses sockets to send udp packets. any help would be great.
Take a look at this simple example from the fsockopen manual page:
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
The connection to the server is established with fsockpen. $out holds the HTTP request that’s then send with frwite. The HTTP response is then read with fgets.
If all you want to do is perform a GET request and receive the body of the response, most of the file functions support using urls:
<?php
$html = file_get_contents('http://google.com');
?>
<?php
$fh = fopen('http://google.com', 'r');
while (!feof($fh)) {
$html .= fread($fh);
}
fclose($fh);
?>
For more than simple GETs, use curl (you have to compile it into php). With curl you can do POST and HEAD requests, as well as set various headers.
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://google.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($ch);
?>
cURL is easier than implementing client side HTTP. All you have to do is set a few options and cURL handles the rest.
$curl = curl_init($URL);
curl_setopt_array($curl,
array(
CURLOPT_USERAGENT => 'Mozilla/5.0 (PLAYSTATION 3; 2.00)',
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => 'User:Password',
CURLOPT_RETURNTRANSFER => True,
CURLOPT_FOLLOWLOCATION => True
// set CURLOPT_HEADER to True if you want headers in the result.
)
);
$result = curl_exec($curl);
If you need to set a header that cURL doesn't support, use the CURLOPT_HTTPHEADER option, passing an array of additional headers. Set CURLOPT_HEADERFUNCTION to a callback if you need to parse headers. Read the docs for curl_setopt for more options.

Categories