2014-04-30 10 views
7

Quindi l'errore è:SoapServer, guasto sulla maniglia() - Procedura non impostare

PHP Fatal error: Procedure 'sup:set_availability' not present in XMLSoapServer.php

sto ricevendo questo errore sul mio ambiente di sviluppo (MAMP).

questo è causato da una stringa XML non valida, nel Quale spazio dei nomi 'sup' non è definito:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" 
    xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Body> 
     <sup:set_availability> 
      <SetAvailability> 
       ... 
      </SetAvailability> 
     </sup:set_availability> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

(Si tratta di una richiesta esterna, quindi non posso semplicemente andare e correggere la fonte - Beh, posso, ma almeno non con un breve preavviso.)

Il problema è che ho ricevuto 2 server che stanno elaborando la stessa richiesta. Senza l'errore Quindi la mia ricerca è quello di scoprire il motivo per cui :)

Alcuni dettagli:

  • Server 1: PHP 5.3.2
  • Server 2: php 5.4
  • Sviluppo: php 5.4

Cose che ho controllato fino ad ora:

  • il codice è lo stesso svn- checkout
  • non dev nascosto o di produzione unica impostazione
  • configurazione di Apache sono gli stessi
  • WSDL la cache è disabilitata, WSDL nella cache vengono cancellati
  • impostazioni di php.ini sono le stesse, con un'eccezione per libxml2:

Il server 1 ha la versione 2.6.26 server 2 con versione 2.7.7 - su cui la richiesta funziona come un fascino L'ambiente di sviluppo personale ha lixml2 versione 2.8.0 - e genera l'errore irreversibile.

La mia ipotesi è (o era) che libxml2 stia causando gli errori - ma non riesco a trovare alcuna risorsa su questo argomento - né sono riuscito a eseguire il downgrade della mia versione libxml2 locale a 2.6 o 2.7.

Quindi ... qualche idea su questo?

+0

Forse si disattiva la cache e chiaro WSDL cache su tutti e 3 i server o solo il tuo server di sviluppo? Forse il server 1 e 2 stanno usando una versione cache in cui questo problema non è presente? – FuzzyTree

+0

Disabilitato e cancellato su entrambi i server; non ha risolto il problema –

risposta

2

Non so quale sia il problema ... ma poiché il PHP nativo SoapClient mi è sempre sembrato un po '"opaco", mi piace usare lo Dklab_SoapClient library.

Usa Curl per recuperare i dati del sapone ed è molto più flessibile della classe nativa di PHP. Inoltre puoi anche estenderlo per aggiungere la tua funzionalità se ne hai bisogno :) Immagino che risolverebbe il tuo problema.

Tuttavia, se non volete utilizzare una libreria esterna, non ho idea di cosa potrebbe causare questo ...

+0

Non riguarda il client, riguarda il server. – hakre

+0

In effetti, è (probabilmente) il server. E poiché questo fa parte di un quadro grande/complesso, non posso sostituire facilmente le classi ... –

2

Penso che manca variabile passata a client.Check sapone con sapone con il cliente di lavoro oppure no

+0

Quale client di sapone? – hakre

+0

No, non il client. –

2

Suggerirò un angolo diverso per risolvere questo problema.

Invece di rompere il parser XML è possibile modificare la richiesta prima di assegnarla al parser XML. Aggiungere lo spazio dei nomi sup alla richiesta, se non è presente. Preferibilmente spingere questa modifica alla produzione e aggiornare/correggere i parser XML di produzione.

Una volta che la fonte esterna ottiene il loro software funzionante, rimuovere questo trucco.

+0

Ho dimenticato di menzionare; accanto al namespace 'sup' ci sono errori di namespace multipli (come da 20 a 30) come l'errore sup. Quindi aggiungere tutte quelle eccezioni non è una cosa molto carina da fare. anche l'utente 'hakre' presenta questa soluzione; funziona, ma non è la cosa più favorevole da fare. –

0

Sembra un problema con la configurazione del server. L'URI WSDL potrebbe essere errato per la macchina di sviluppo in modo tale che quando il server di sapone si introspeca al WSDL, non riesce a trovare quella funzione perché sta esaminando un server sbagliato.

L'XML tuttavia è ancora errato in quanto il prefisso dello spazio dei nomi rimane indefinito. Non mi aspetto che funzioni in modo sicuro poiché questo non è un XML valido e XML valido è richiesto per il funzionamento di SOAP.

Un test rapido con LIBXML 2.9.1 ha rivelato che il chunk XML difettoso viene caricato da DOMDocument con un avviso ma conservato (incluso il prefisso). Se si ottiene l'accesso al documento di richiesta sottostante, è possibile aggiungere il vostro proprio:

// just test code to mock a DOMDocument having the fault XML from question 
$doc = new DOMDocument(); 
$back = libxml_use_internal_errors(TRUE); 
$doc->loadXML($xml); 
libxml_use_internal_errors($back); 

// poc to add the prefix definition 
$doc->documentElement->setAttributeNS(
    'http://www.w3.org/2000/xmlns/', 'xmlns:sup', 'sup:uri' 
); 

Il documento quindi è:

<SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" 
     xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" 
     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
     xmlns:sup="sup:uri"> 
    <SOAP-ENV:Body> 
     <sup:set_availability> 
      <SetAvailability> 
       ... 
      </SetAvailability> 
     </sup:set_availability> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Come si può vedere la definizione di prefisso è stato aggiunto. È possibile intercettare la richiesta in entrata prima del SoapServer::handle(), modificarla e iniettarla in handle($soap_request).

  • azione SOAP: $_SERVER['HTTP_SOAPACTION']
  • Richiesta corpo: file_get_contents('php://input')
  • See: SoapServer::handle()