Nusoap “SOAP-ENV: Xml was empty, didn't parse”

2019-06-16 15:58发布

问题:

I'm trying to implement a simple webservice using nusoap. Server:

<?php
require_once "nusoaplib/nusoap.php";

class food {

    public function getFood($type) {
        switch ($type) {
            case 'starter':
                return 'Soup';
                break;
            case 'Main':
                return 'Curry';
                break;
            case 'Desert':
                return 'Ice Cream';
                break;
            default:
                break;
        }
    }
}

$server = new soap_server();
$server->configureWSDL("foodservice", "urn:foodservice");

$server->register("food.getFood",
    array("type" => "xsd:string"),
    array("return" => "xsd:string"),
    "urn:foodservice",
    "urn:foodservice#getFood",
    "rpc",
    "encoded",
    "Get food by type");

@$server->service($HTTP_RAW_POST_DATA);
?>

Client:

<?php
require_once "nusoaplib/nusoap.php";

$client = new nusoap_client("http://localhost/SOAPServer.php?wsdl", true);
$error  = $client->getError();

if ($error) {
    echo "<h2>Constructor error</h2><pre>" . $error . "</pre>";
}

$result = $client->call("food.getFood", array("type" => "Main"));

if ($client->fault) {
    echo "<h2>Fault</h2><pre>";
    print_r($result);
    echo "</pre>";
} else {
    $error = $client->getError();
    if ($error) {
        echo "<h2>Error</h2><pre>" . $error . "</pre>";
    } else {
        echo "<h2>Main</h2>";
        echo $result;
    }
}

// show soap request and response
echo "<h2>Request</h2>";
echo "<pre>" . htmlspecialchars($client->request, ENT_QUOTES) . "</pre>";
echo "<h2>Response</h2>";
echo "<pre>" . htmlspecialchars($client->response, ENT_QUOTES) . "</pre>";
?>

The wsdl file is generated by nusoap, which is the following:

<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:foodservice" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:foodservice">
<types>
<xsd:schema targetNamespace="urn:foodservice">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"/>
</xsd:schema>
</types>
<message name="food.getFoodRequest">
<part name="type" type="xsd:string"/>
</message>
<message name="food.getFoodResponse">
<part name="return" type="xsd:string"/>
</message>
<portType name="foodservicePortType">
<operation name="food.getFood">
<documentation>Get food by type</documentation>
<input message="tns:food.getFoodRequest"/>
<output message="tns:food.getFoodResponse"/>
</operation>
</portType>
<binding name="foodserviceBinding" type="tns:foodservicePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="food.getFood">
<soap:operation soapAction="urn:foodservice#getFood" style="rpc"/>
<input>
<soap:body use="encoded" namespace="urn:foodservice" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" namespace="urn:foodservice" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="foodservice">
<port name="foodservicePort" binding="tns:foodserviceBinding">
<soap:address location="http://10.152.128.39/SOAPServer.php"/>
</port>
</service>
</definitions>

When accessing both the server file and the wsdl file, they both work, but I get the error message when I try to access the client:

    [faultcode] => SOAP-ENV:Client
    [faultactor] => 
    [faultstring] => error in msg parsing:
xml was empty, didn't parse!
    [detail] => 

Any suggestions what could be the problem?

回答1:

In your nusoap. Server you should change:

This:

@$server->service($HTTP_RAW_POST_DATA);

for this:

@$server->service(file_get_contents("php://input"));

You may remove the @ if you want to check notices and warnings.

Some explanation from http://php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data

This feature was DEPRECATED in PHP 5.6.0, and REMOVED as of PHP 7.0.0. If set to TRUE, PHP will always populate the $HTTP_RAW_POST_DATA containing the raw POST data. Otherwise, the variable is populated only when the MIME type of the data is unrecognised.

The preferred method for accessing raw POST data is php://input, and $HTTP_RAW_POST_DATA is deprecated in PHP 5.6.0 onwards. Setting always_populate_raw_post_data to -1 will opt into the new behaviour that will be implemented in a future version of PHP, in which $HTTP_RAW_POST_DATA is never defined.

Regardless of the setting, $HTTP_RAW_POST_DATA is not available with enctype="multipart/form-data".