2016-10-14 46 views
5

Próbuję zaimplementować prostą usługę sieciową przy użyciu nusoap. Serwer:Nusoap "SOAP-ENV: Xml był pusty, nie parsował" Wiadomość

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

Klient:

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

pliku WSDL jest generowany przez Instalacja NuSOAP, który jest następujący:

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

Przy dostępie zarówno plik serwera i pliku WSDL, oba działają, ale pojawia się komunikat o błędzie, gdy próbuję uzyskać dostęp do klienta:

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

Jakieś sugestie, co może być problemem?

Odpowiedz

13

W swoim nusoap. Serwer należy zmienić:

następująco:

@$server->service($HTTP_RAW_POST_DATA); 

na to:

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

Możesz usunąć @ jeśli chcesz sprawdzić powiadomień i ostrzeżeń.

Niektóre wyjaśnienia od http://php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data

Ta funkcja jest potępiany w PHP 5.6.0 i usunął od PHP 7.0.0. Jeśli ustawione na TRUE, PHP zawsze zapełni dane $ HTTP_RAW_POST_DATA zawierające surowe dane POST. W przeciwnym razie zmienna zostanie wypełniona tylko wtedy, gdy typ MIME danych nie zostanie rozpoznany.

Preferowaną metodą uzyskiwania dostępu do surowych danych POST jest php: // input, a $ HTTP_RAW_POST_DATA jest przestarzałe w PHP od wersji 5.6.0. Ustawienie always_populate_raw_post_data na -1 spowoduje włączenie nowego zachowania, które zostanie zaimplementowane w przyszłej wersji PHP, w której $ HTTP_RAW_POST_DATA nigdy nie zostanie zdefiniowane.

Bez względu na ustawienie, $ HTTP_RAW_POST_DATA nie jest dostępne z enctype = "multipart/form-data".

+0

Próbowałem z usługą @ $ server-> service (file_get_contents ("php: // input")); ale nie działa. następnie zmieniłem ustawienie php.ini na sposób, w jaki always_populate_raw_post_data na 1 nadal nie działa. Czy ktoś może mi pomóc? –

+0

@ $ server-> service (file_get_contents ("php: // input")); działa. @ BantyRoy Pobrałem i przetestowałem twoją parę klient/serwer i wydaje się, że działam (dostaję curry). Wygląda na to, że masz jakiś błąd konfiguracji na swoim serwerze lub jakiś inny problem związany z wersjami lub czymkolwiek. – erm3nda

+0

Dziękuję wam, pracowałem doskonale w PHP 7.0, trzy godziny błędów naprawiono d :) –