How to call RESTful WCF-Service from PHP

2019-07-13 03:23发布

问题:

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.

回答1:

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); 


回答2:

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:

  1. Create a php Client to invoke a REST Service

  2. php rest api call



回答3:

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");


回答4:

 $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.



标签: php json wcf rest