SoapFault exception: [SOAP-ENV:Client] looks like we got no XML document
This error can have to reasons:
1: Your server script has some hidden output like spaces before or afher <?php ... ?> or echoing some text
2: You have a bug in your server script;
resulting in a error message output
Test your server script by calling it direct from the browser.
The result should be a clean output like :
−<SOAP-ENV:Envelope>
−<SOAP-ENV:Body>
−<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Bad Request. Can't find HTTP_RAW_POST_DATA</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This tell's you there was a request but without data; This is OK
Now if you get the error when calling with your soap client;
remember that your server now will call other functions in the server.php script because it now has some data to process
SOAP
- Einführung
- Installation/Konfiguration
- Vordefinierte Konstanten
- SOAP — SOAP Funktionen
- is_soap_fault — Prüft, ob eine SOAP-Aufruf fehlgeschlagen ist.
- SoapClient->__call() — Ausführen eines SOAP-Aufrufs (deprecated)
- SoapClient->__construct() — SoapClient-Konstruktor
- SoapClient->__doRequest() — Ausführen einer SOAP-Anfrage
- SoapClient->__getFunctions() — Gibt eine Liste der SOAP-Funktionen zurück
- SoapClient->__getLastRequest() — Gibt die letzte SOAP-Anfrage zurück
- SoapClient->__getLastRequestHeaders() — Gibt den letzten SOAP-Anfrage-Header zurück
- SoapClient->__getLastResponse() — Gibt die letzte SOAP-Antwort zurück
- SoapClient->__getLastResponseHeaders() — Gibt den letzten SOAP-Antwort-Header zurück
- SoapClient->__getTypes() — Gibt eine Liste der SOAP-Typen zurück
- SoapClient->__setCookie() — Setzt Cookie, der bei SOAP-Anfragen verschickt wird
- SoapClient->__soapCall() — Aufrufen einer SOAP-Funktion
- SoapFault->__construct() — SoapFault-Konstruktor
- SoapHeader->__construct() — SoapHeader-Konstruktor
- SoapParam->__construct() — SoapParam-Konstruktor
- SoapServer->addFunction() — Hinzufügen einer oder mehrerer Funktionen, die SOAP-Anfragen bearbeiten sollen.
- SoapServer->__construct() — SoapServer-Konstruktor
- SoapServer->fault() — Behandlung von SoapServer-Fehlern
- SoapServer->getFunctions() — Gibt eine Liste aller definierten Funktionen zurück
- SoapServer->handle() — Behandeln von SOAP-Anfragen
- SoapServer->setClass() — Setzt eine Klasse die SOAP-Funktionen anbietet
- SoapServer->setPersistence() — Versetzt einen SoapServer in den Persistenz-Modus
- SoapVar->__construct() — SoapVar-Konstrutkor
- use_soap_error_handler — Definiert, ob der SOAP-Error-Handler benutzt werden soll oder ob der vorherige Wert zurückgegeben werden soll.
SOAP
aeg at mallxs dot nl
28-May-2008 02:19
28-May-2008 02:19
nodkz at mail dot ru
24-May-2008 11:25
24-May-2008 11:25
PROBLEM (with SOAP extension under PHP5) of transferring object, that contains objects or array of objects. Nested object would not transfer.
SOLUTION:
This class was developed by trial and error by me. So this 23 lines of code for most developers writing under PHP5 solves fate of using SOAP extension.
<?php
/*
According to specific of organization process of SOAP class in PHP5, we must wrap up complex objects in SoapVar class. Otherwise objects would not be encoded properly and could not be loaded on remote SOAP handler.
Function "getAsSoap" call for encoding object for transmission. After encoding it can be properly transmitted.
*/
abstract class SOAPable {
public function getAsSOAP() {
foreach($this as $key=>&$value) {
$this->prepareSOAPrecursive($this->$key);
}
return $this;
}
private function prepareSOAPrecursive(&$element) {
if(is_array($element)) {
foreach($element as $key=>&$val) {
$this->prepareSOAPrecursive($val);
}
$element=new SoapVar($element,SOAP_ENC_ARRAY);
}elseif(is_object($element)) {
if($element instanceof SOAPable) {
$element->getAsSOAP();
}
$element=new SoapVar($element,SOAP_ENC_OBJECT);
}
}
}
// ------------------------------------------
// ABSTRACT EXAMPLE
// ------------------------------------------
class PersonList extends SOAPable {
protected $ArrayOfPerson; // variable MUST be protected or public!
}
class Person extends SOAPable {
//any data
}
$client=new SoapClient("test.wsdl", array( 'soap_version'=>SOAP_1_2, 'trace'=>1, 'classmap' => array('Person' => "Person", 'PersonList' => "PersonList") ));
$PersonList=new PersonList;
// some actions
$PersonList->getAsSOAP();
$client->someMethod($PersonList);
?>
So every class, which will transfer via SOAP, must be extends from class SOAPable.
As you can see, in code above, function prepareSOAPrecursive search another nested objects in parent object or in arrays, and if does it, tries call function getAsSOAP() for preparation of nested objects, after that simply wrap up via SoapVar class.
So in code before transmitting simply call $obj->getAsSOAP()
