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.