Lezioni di informatica

Stiamo scrivendo un'applicazione client-server SOAP in PHP. Microsoft è fuori dai giochi?

(PHP5 >= 5.0.1)

SoapClient::SoapClient — Costruttore SoapClient

Parametri

wsdl

URI del WSDL file o NULLO se lavori in non WSDL modalità.

Durante lo sviluppo, la memorizzazione nella cache WSDL potrebbe essere disabilitata utilizzando il file soap.wsdl_cache_ttl php.ini altrimenti le modifiche apportate al file WSDL non avranno effetto fino al soap.wsdl_cache_ttlè scaduto.

opzioni

Una serie di opzioni. Se si lavora in modalità WSDL, questo parametro è facoltativo. Se si lavora in modalità non WSDL, il file posizione E uri le opzioni devono essere impostate, dove posizioneè l'URL del server SOAP a cui inviare la richiesta e uriè lo spazio dei nomi di destinazione del servizio SOAP.

IL stile E utilizzo le opzioni funzionano solo in modalità non WSDL. Nella modalità WSDL provengono dal file WSDL.

IL soap_version l'opzione specifica se utilizzare il client SOAP 1.1 (predefinito) o SOAP 1.2.

Per l'autenticazione HTTP, il login E parola d'ordine le opzioni possono essere utilizzate per fornire credenziali. Per effettuare una connessione HTTP tramite un server proxy, le opzioni host_proxy, porta proxy, proxy_login E password_proxy sono disponibili anche Per l'utilizzo dell'autenticazione del certificato client HTTPS local_cert E frase d'accesso opzioni. Un'autenticazione può essere fornita nel file autenticazione opzione. Il metodo di autenticazione può essere uno dei due SOAP_AUTHENTICATION_BASIC(predefinito) o SOAP_AUTHENTICATION_DIGEST.

IL compressione l'opzione consente di utilizzare la compressione delle richieste e delle risposte HTTP SOAP.

IL codifica l'opzione definisce la codifica interna dei caratteri. Questa opzione non modifica la codifica delle richieste SOAP (è sempre utf-8), ma converte le stringhe in essa.

IL traccia L'opzione consente il tracciamento della richiesta in modo da poter risalire agli errori. L'impostazione predefinita è FALSO

IL mappa di classe l'opzione può essere utilizzata per mappare alcuni tipi WSDL su classi PHP. Questa opzione deve essere un array con tipi WSDL come chiavi e nomi di classi PHP come valori.

Impostazione del valore booleano traccia L'opzione consente l'uso dei metodi SoapClient->__getLastRequest , SoapClient->__getLastRequestHeaders , SoapClient->__getLastResponse e SoapClient->__getLastResponseHeaders .

IL eccezioni opzione è un valore booleano che definisce se gli errori soap generano eccezioni di tipo SoapFault .

IL connesione finita l'opzione definisce un timeout in secondi per la connessione al servizio SOAP. Questa opzione non definisce un timeout per i servizi con risposte lente. Per limitare il tempo di attesa per il completamento delle chiamate, è disponibile l'impostazione default_socket_timeout.

IL typemap l'opzione è un array di mappature di tipi. La mappatura dei tipi è un array con chiavi nome_tipo, tipo_ns(URI dello spazio dei nomi), da_xml(callback che accetta un parametro di stringa) e a_xml(callback che accetta un parametro di oggetto).

IL cache_wsdl l'opzione è una di WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORIA O WSDL_CACHE_BOTH.

IL utente_agente l'opzione specifica la stringa da utilizzare Agente utente intestazione.

IL contesto_stream l'opzione è per il contesto.

IL caratteristiche l'opzione è una maschera di bit di SOAP_SINGLE_ELEMENT_ARRAYS, SOAP_USE_XSI_ARRAY_TYPE, SOAP_WAIT_ONE_WAY_CALLS.

IL keep_alive l'opzione è un valore booleano che definisce se inviare il file Connessione: Keep-Alive intestazione o Connessione: chiusa .

Registro delle modifiche

Versione Descrizione
5.4.0 Nuovo keep_alive opzione.

Esempi

Esempio 1 SoapClient::SoapClient() esempio

$client = new SoapClient("some.wsdl");

$client = nuovo SoapClient ("some.wsdl" , array("soap_version" => SOAP_1_2 ));

$client = nuovo SoapClient ("some.wsdl" , array("login" => "some_name" ,
"password" => "qualche_password" ));

$client = nuovo SoapClient ("some.wsdl" , array("proxy_host" => "localhost" ,
"porta_proxy" => 8080 ));

$client = nuovo SoapClient ("some.wsdl" , array("proxy_host" => "localhost" ,
"porta_proxy" => 8080,
"proxy_login" => "qualche_nome" ,
"proxy_password" => "qualche_password" ));

$client = nuovo SoapClient ("some.wsdl", array("local_cert" => "cert_key.pem" ));

$client = new SoapClient (null , array("location" =>
"uri" => "http://test-uri/" ));

$client = new SoapClient (null, array("location" => "http://localhost/soap.php" ,
"uri" => "http://test-uri/" ,
"stile" => SOAP_DOCUMENT,
"usa" => SOAP_LITERAL ));

$client = new SoapClient("some.wsdl" ,
array("compressione" => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP ));

$server = nuovo SoapClient ("some.wsdl" , array("encoding" => "ISO-8859-1" ));

classe Il mio libro(
pubblico $titolo ;
pubblico $autore;
}

$server = nuovo SoapClient ("books.wsdl" , array("classmap" => array("book" => "MyBook" )));

?>

Chris Gunawardena

Per monitorare le chiamate SOAP in entrata e in uscita da un server UNIX:

Sudo tcpdump -nn -vv -A -s 0 -i eth0 dst o src host xxx.xxx.xxx.xxx e porta 80

E usa sempre "cache_wsdl" => WSDL_CACHE_NONE

svenr su selfhtml punto org

L'opzione "classmap" in realtà è una mappatura dal "ComplexType" utilizzato all'interno di SOAP alle tue classi PHP.

Non confondere i nomi dei tag XML restituiti per la tua richiesta con questi ComplexTypes. SOAP consente loro di essere diversi.

Avevo qualcosa del genere:
...


FooBar

TagName non è la chiave che vuoi inserire nella tua mappa di classe, devi conoscere il nome del ComplexType a cui fa riferimento questo TagName. Queste informazioni sono contenute nella risorsa WSDL.

paulovitorbal su Gmail punto com

Quando si utilizzano i certificati, nel parametro "local_cert", utilizzare il contenuto del file, non il nome del file.

Nuovo soapclient("http://localhost/index.php?wsdl ", array("local_cert"=>file_get_contents("./key.pem"),"passphrase"=>"password"));

In PHP, puoi avere proprietà private definite nelle classi che usi nella tua mappa di classe. Quindi, se crei una proprietà privata $foo nella tua classe e l'elemento SOAP ha un elemento figlio , il contenuto di $foo verrà impostato sul contenuto di . In questo modo puoi controllare l'accesso alle proprietà nelle tue classi.

(Nota: questo non funziona con HPHP di Facebook).

willem punto stuursma presso hyves punto nl

Se desideri utilizzare le classi in uno spazio dei nomi diverso nella mappa delle classi, utilizza semplicemente la barra rovesciata nel nome della classe di destinazione.

Esempio:
$classmap = array("risultato" => "MyNamespace\\Risultato" );
?>

È necessario specificare due volte la barra rovesciata perché è il carattere di escape nelle stringhe.

simonlang a gmx punto cap

Esempio per un client soap con autenticazione HTTP su un proxy:

nuovo SoapClient(
"servizio.wsdl" ,
vettore(
// Roba per lo sviluppo.
"traccia" => 1 ,
"eccezioni" => vero,
"cache_wsdl" => WSDL_CACHE_NONE,
"funzionalità" => SOAP_SINGLE_ELEMENT_ARRAYS,

// Credenziali di autenticazione per la richiesta SOAP.
"login" => "nome utente",
"password" => "password" ,

// URL proxy.
"proxy_host" => "esempio.com" , // Non aggiungere lo schema qui (http o https). Non funzionerà.
"porta_proxy" => 44300,

// Credenziali di autenticazione per il proxy.
"proxy_login" => NULL,
"proxy_password" => NULL,
);
?>
Fornire un URL a un file WSDL sul server remoto (che è anch'esso protetto con l'autenticazione HTTP) non ha funzionato.Ho scaricato il WSDL e l'ho archiviato sul server locale.

Asaf Meller

Una configurazione soap php .net completamente funzionante:
Appunti
1. web.config sul server .net deve funzionare con l'associazione basichttp.
2. i parametri alle funzioni soap devono essere passati come:
array("nome_parm1"=>"valore_parm1",
"parm2_nome"=>"parm2_valore"...)

header("Tipo di contenuto: testo/semplice");

Tentativo (
$opzioni = array(
"versione_soap" => SOAP_1_1,
"eccezioni" => vero,
"traccia" => 1 ,
"cache_wsdl" => WSDL_CACHE_NONE
);
$client = nuovo SoapClient ( "http://www.example.com/end_point.wsdl", $opzioni);

) catch (Eccezione $e ) (
eco "

Errore di eccezione!

" ;
echo $e -> getMessage();
}

Echo "in esecuzione HelloWorld:";

Tentativo (
$risposta = $cliente -> HelloWorld();

}
catch (Eccezione $e)
{
echo "Eccezione rilevata: " , $e -> getMessage (), "\n" ;
}

Print_r($risposta);
?>
buona fortuna!
Asaf.

faebu a faebu punto cap

Sto riscontrando gli stessi problemi quando provo a caricare un campo WDSL protetto dall'autenticazione http di base, poiché i parametri login e password vengono utilizzati solo per la richiesta ma non durante la lettura del file wdsl. Utilizzo semplicemente la seguente soluzione alternativa scaricando il file xml in una posizione non protetta sul mio server. Tieni presente che questo non supporta alcun tipo di memorizzazione nella cache.

la classe SoapAuthClient estende SoapClient (
/**
* Poiché il pacchetto SOAP PHP non supporta l'autenticazione di base
* questa classe scarica il file WDSL utilizzando il pacchetto cURL e
* crea una copia locale del wdsl sul tuo server.
*Assicurati di fornire il seguente parametro aggiuntivo nel file
* $opzioniArray:
* wdsl_local_copy => vero
*/

Privato $cache_dir = "/home/example/htdocs/cache/" ;
privato $cache_url = "http://www.example.com/cache/";

Funzione SoapAuthClient ($wdsl, $opzioni) (
if (isset($opzioni ["wdsl_local_copy"]) &&
$opzioni ["wdsl_local_copy"] == vero &&
isset($opzioni ["accedi"]) &&
isset($opzioni ["password"])) (

$file = md5(uniqid()). ".xml";

If (($fp = fopen ($this -> cache_dir . $file , "w")) == false ) (
lancia una nuova eccezione ( "Impossibile creare il file WDSL locale (". $questo -> dir_cache . $file. ")");
}

$ch = curl_init();
$credito = ($opzioni["login"]. ":" . $opzioni["password" ]);
curl_setopt($ch, CURLOPT_URL, $wdsl);
curl_setopt($canale, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt ($canale, CURLOPT_USERPWD, $credito);
curl_setopt($canale, CURLOPT_TIMEOUT, 15);
curl_setopt ($canale, CURLOPT_FILE, $fp);
if (($xml = curl_exec ($ch )) === false ) (
//curl_close($canale);
fclose($fp);
scollega ($this -> cache_dir. $file);

Genera una nuova eccezione (curl_error ($ ch));
}

Curl_close($canale);
fclose($fp);
$wdsl = $questo -> cache_url . $file;
}

Annulla impostazione ($ opzioni ["wdsl_local_copy"]);
unset($opzioni ["wdsl_force_local_copy"]);

Echo $wdsl;
genitore :: __construct ($wdsl, $opzioni);

Scollega ($this -> cache_dir. $file);
}
}
?>

tatupheba su Gmail punto com

Ciao gente!

Un suggerimento per gli sviluppatori:

Quando si programmano alcuni server soap, impostare la direttiva "soap.wsdl_cache_enabled" nel file php.ini su 0:

Soap.wsdl_cache_enabled=0

Altrimenti verranno visualizzati un sacco di strani errori che dicono che il tuo wsdl non è corretto o manca.

In questo modo ti risparmierai un sacco di dolori inutili.

titan su phpdevshell punto org

Va notato che se si riceve un errore di ritorno: "Riferimento oggetto non impostato su un'istanza di un oggetto.". Ciò potrebbe essere dovuto a qualcosa di semplice come il passaggio di parametri errati. Quando guardi questo XML:



corda
appuntamento
appuntamento

Il tuo codice dovrebbe assomigliare a questo:

Tentativo (
$opzioni = array(
"versione_soap" => SOAP_1_2,
"eccezioni" => vero,
"traccia" => 1 ,
"cache_wsdl" => WSDL_CACHE_NONE
);
$client = nuovo SoapClient ( "http://esempio.com/doc.asmx?WSDL", $opzioni);
// Nota dove si trovano i tag "Get" e "request" nell'XML
$risultati = $client -> Ottieni (array("richiesta" =>array("CustomerId" => "1234" )));
) catch (Eccezione $e ) (
eco "

Errore di eccezione!

" ;
echo $e -> getMessage();
}

$risultati = $client -> Ottieni (array("richiesta" =>array("CustomerId" => "842115" )));
?>

Se il tuo file WSDL contiene un parametro con un tipo base64Binary, non dovresti utilizzare base64_encode() quando passi le tue variabili soap. Quando si esegue la richiesta, la libreria SOAP base64 codifica automaticamente i tuoi dati, altrimenti li codificherai due volte.

Frammento WSDL:

$stringa = "dati_che_vuoi_inviare___come_xml_in_soap";
$dati_soap = array(
"foo" => "bar" ,
//"content" => base64_encode($string) // non farlo
"content" => $string //fai questo
);
$risposta = $client -> Invia ($soap_data);
?>

marcovtwout su hotmail punto com

Essendo nuovo in SOAP, ho cercato per un po' il motivo per cui il mio messaggio riceveva una risposta in soapUI, ma non con il mio codice php. Il servizio specifico a cui mi stavo rivolgendo fornisce un HTTP 202 Accettato in caso di successo (nessuna risposta), ma restituisce un messaggio SOAP in caso di errori.

Situazione:
Utilizzando una connessione client (autenticata) e un file WDSL, le chiamate SOAP con tipo "One-Way" non forniscono un'intestazione di risposta, anche se è prevista una risposta.

Soluzione:
Quando si chiama il costruttore client, impostare SOAP_WAIT_ONE_WAY_CALLS in $options["features"].

tim su tdinternet punto com

PHP 5.2.11 sembra non essere molto esigente riguardo alla correttezza di un WSDL.

Altri client SOAP si lamentavano di problemi di schema e spazio dei nomi, mentre SoapClient di PHP funzionava perfettamente. La risoluzione di questi problemi per gli altri client tuttavia danneggiava SoapClient di PHP al punto che gli oggetti passati al metodo SOAP diventavano array vuoti sul lato server.

Lezione appresa: alcuni elementi avevano il prefisso xsd: e altri no: assicurati assolutamente che il tuo WSDL sia corretto e coerente (sto usando un WSDL_Gen.php ottimizzato).

James punto Ellis su Gmail punto com

Ho riscontrato problemi nell'ottenere risposte da un server SOAP Coldfusion, senza problemi evidenti nel SoapClient utilizzato.

Alla fine ho scoperto che il server accettava solo richieste SOAP 1.1 e non 1.2. Non sono sicuro che si tratti di un'impostazione Coldfusion a livello di sistema, ma se colpisci lo stesso muro, prova a impostare l'opzione SoapClient "soap_version" sulla costante SOAP_1_1 (che è l'impostazione predefinita ma la mia era impostata su 1.2 poiché il client veniva riutilizzato per un altro servizio )

ajcartmell e fonant punto com

Sembra che ci sia un problema con la specifica di stringhe vuote per le opzioni proxy_host e proxy_port nelle recenti versioni di PHP (da una versione successiva alla 5.2.9 e uguale o precedente alla 5.2.11).

Fornire valori di stringa vuoti per proxy_host e proxy_port causa errori di tipo "host non trovato": fornire NULL o FALSE funziona correttamente.

bhargav punto khatana su Gmail punto com

Mi ci è voluta più di una settimana per capire come implementare le intestazioni WSSE (Web Service Security) nel SOAP PHP nativo. Non ci sono molte risorse disponibili su questo argomento, quindi ho pensato di aggiungerlo qui a beneficio della comunità.

Passaggio 1: crea due classi per creare una struttura per le intestazioni WSSE

classe clsWSSEAuth(
privato $Nomeutente;
$Password privata;
funzione __construct ($nome utente, $password) (
$questo -> Nome utente = $nomeutente;
$questo -> Password = $password;
}
}

Classe clsWSSEToken(
privato $NomeutenteToken;
funzione __costrutto ($innerVal)(
$this -> UsernameToken = $innerVal;
}
}
?>
Passaggio 2: creare variabili soap per nome utente e password

$nomeutente = 1111;
$password = 1111;

//Verifica con il tuo provider quale spazio dei nomi di sicurezza sta utilizzando.
$strWSSENS = "http://schemas.xmlsoap.org/ws/2002/07/secext";

$objSoapVarUser = new SoapVar($nomeutente, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
?>
Passaggio 3: crea un oggetto per la classe di autenticazione e passa soap var

$objWSSEAuth = nuovo clsWSSEAuth ($objSoapVarUser, $objSoapVarPass);
?>
Passaggio 4: crea SoapVar dall'oggetto della classe Auth

$objSoapVarWSSEAuth= nuova SoapVar ($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, "UsernameToken", $strWSSENS);
?>
Passaggio 5: crea un oggetto per la classe token

$objWSSEToken = nuovo clsWSSEToken ($objSoapVarWSSEAuth);
?>
Passaggio 6: crea SoapVar dall'oggetto della classe Token

$objSoapVarWSSEToken= nuova SoapVar ($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, "UsernameToken", $strWSSENS);
?>
Passaggio 7: creare SoapVar per il nodo "Sicurezza".

$objSoapVarHeaderVal=nuova SoapVar ($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, "Sicurezza", $strWSSENS);
?>
Passaggio 8: creare un oggetto intestazione dalla soapvar di sicurezza

$objSoapVarWSSEHeader= nuovo SoapHeader ($strWSSENS, "Sicurezza", $objSoapVarHeaderVal, true, "http://abce.com");

//Il terzo parametro qui rende "mustUnderstand=1
//Il quarto parametro genera "actor="http://abce.com ""
?>
Passaggio 9: creare un oggetto di Soap Client

$objClient = nuovo SoapClient ($WSDL, $arrOptions);
?>
Passaggio 10: imposta le intestazioni per l'oggetto soapclient

$objClient -> __setSoapHeaders (array($objSoapVarWSSEHeader ));
?>
Passaggio 11: chiamata finale al metodo

$objResponse = $objClient -> __soapCall ($strMethod, $requestPayloadString);
?>

peter presso webacoustics punto com

Ho scoperto che il recupero WSDL fallisce quando si utilizza l'autenticazione di base nel soapclient. Quindi ho implementato la seguente soluzione alternativa utilizzando wget. Mi rendo conto che wget potrebbe non essere un'opzione per alcuni ambienti, in tal caso cURL sarebbe la cosa più semplice successiva.

$wsdl = get_wsdl ( "https://example.com/soap/service?wsdl");
$this -> client = new SoapClient ($wsdl, array("user" => "someuser", "password" => "somepassword"));

Funzione privata get_wsdl ($url) (
globale $g ;
$url = escapeshellarg($url);
$cache_file = "/tmp/soap.wsdl." . md5($url);

//recupera solo un nuovo wsdl ogni ora
if(! file_esiste ($cache_file) || filectime ($cache_file)< time () - 3600 ) {
$agente = escapeshellarg("--user-agent=($g["useragent"])");
mwexec("wget ​​--quiet --timeout=5 ( $agent ) --no-check-certificate --output-document=($file_cache) ($url)");
if(! file_esiste ($cache_file )) (
lancia una nuova eccezione ("Impossibile caricare WSDL su ( $url )" );
}
}
ritorno
$file_cache;
}
?>

Meltir e Meltir punto com

Per coloro che combattono con i server proxy autenticati NTLM, ecco una soluzione che sto utilizzando atm:

/**
* Un figlio di SoapClient con supporto per l'autenticazione proxy NTLM
*
* @autore Meltir
*
*/
la classe NTLM_SoapClient estende SoapClient (

Funzione pubblica __construct ($wsdl, $options = array()) (
if (empty($opzioni ["proxy_login"]) || vuoto($opzioni ["proxy_password"])) lancia una nuova eccezione ( "Login e password richiesti per l'autenticazione NTLM!");
$questo -> proxy_login = $opzioni ["proxy_login"];
$questo -> proxy_password = $opzioni ["proxy_password"];
$questo -> proxy_host = (vuoto($opzioni ["proxy_host"])? "host locale": $opzioni[ "host_proxy"]);
$questo-> porta proxy= (vuoto($opzioni[ "porta proxy"]) ? 8080 : $opzioni[ "porta proxy"]);
genitore:: __costruire($wsdl, $opzioni);
}

/**
* Chiama un URL utilizzando curl con autenticazione ntlm
*
* @param stringa $url
* @param stringa $dati
* @return stringa
* @genera SoapFault in caso di errore di connessione curl
*/
funzione protettacallCurl($URL, $dati) {
$maniglia= curl_init();
curl_setopt($maniglia, CURLOPT_HEADER, falso);
curl_setopt($maniglia, CURLOPT_URL, $URL);
curl_setopt($maniglia, CURLOPT_FAILONERROR, VERO);
curl_setopt($maniglia, CURLOPT_HTTPHEADER,Vettore("Client PHP SOAP-NTLM"));
curl_setopt($maniglia, CURLOPT_RETURNTRANSFER, VERO);
curl_setopt($maniglia, CURLOPT_POSTFIELDS, $dati);
curl_setopt($maniglia, CURLOPT_PROXYUSERPWD, $questo-> proxy_login. ":" . $questo-> password_proxy);
curl_setopt($maniglia, CURLOPT_PROXY, $questo-> host_proxy. ":" . $questo-> porta proxy);
curl_setopt($maniglia, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
$risposta= curl_exec($maniglia);
se (vuoto(
$risposta)) {
lanciarne di nuovi
SoapFault("Errore CURL: ". curl_errore($maniglia), curl_errno($maniglia));
}
arriccia_chiudi($maniglia);
ritorno
$risposta;
}

Funzione pubblica __doRequest($richiesta, $posizione, $azione, $versione, $solo andata= 0 ) {
ritorno
$questo-> callCurl($posizione, $richiesta);
}

}
?>

Richiede arricciatura e potrebbe essere esteso, ma funziona per le mie esigenze semplici.

Eric punto Caron su Gmail punto com

Pensiero sottolineato da Jan su bestbytes e discusso nel bug n. 27777, una fonte comune di "Parsing WSDL: Impossibile trovare" "l'errore deriva dal tentativo di accedere a un WSDL protetto dall'autenticazione HTTP. Passare login/password nel 2° parametro non sempre funziona; quindi se incontri questo messaggio di errore e stai tentando di accedere a un file WSDL protetto, prova a passare il nome utente e la password con il primo parametro.

Anonimo

Ho dovuto lottare con un comportamento piuttosto strano quando provavo a utilizzare i servizi web Parlay X standard senza successo. Tuttavia, ho trovato un rimedio al mio problema.

Il problema che ho dovuto affrontare riguardava un'errata richiesta di autenticazione di base HTTP non valida inviata al servizio web. Sebbene stessi inviando le credenziali corrette, ricevevo un errore di autenticazione. Risulta che PHP stava inviando richieste HTTP a un altro endpoint che non è esposto direttamente tramite il servizio Web e che quell'endpoint non richiede l'autenticazione.

Il mio rimedio a questo problema è stato utilizzare queste semplici righe nell'esempio dell'utilizzo del metodo sendSms Paraly-X.

Innanzitutto, creando un client soap senza opzioni di autenticazione HTTP:

$cliente= nuovoSoapClient($wsdl_url);
?>

La richiesta precedente memorizzerà nella cache wsdl nella directory /tmp. Subito dopo questa costruzione creiamo un altro client soap, questa volta con opzioni di autenticazione HTTP:

Tentativo (
$cliente= nuovoSoapClient($wsdl_url, vettore("login"=> "grifone",
"parola d'ordine"=> "parola d'ordine"));
) presa (
Eccezione $e) {
printf("Errore: inviaSms: %s\n", $e-> __accordare());
ritorno
falso;
}
?>

Ora dovrebbe funzionare senza alcun problema. Senza la seconda chiamata, PHP chiamerà sendSms senza credenziali risultando in un tentativo fallito a causa della mancanza di informazioni di autenticazione. Ho trovato questa procedura la più semplice.

Questo processo dovrebbe essere eseguito ogni volta che scade il wsdl memorizzato nella cache, o semplicemente si può aumentare il time-to-live per il wsdl memorizzato nella cache da php.ini

jon punto gilbert e net-entwicklung punto de

Tieni presente che la creazione di un client soap per un URL non valido (prova cosa succede quando un servizio non è disponibile, giusto?) di solito genera un'eccezione che può essere intercettata con try..catch. Tuttavia, se xdebug è attivo, verrà visualizzato un errore fatale, che ovviamente non può essere rilevato.

sloloem su Gmail punto com

Ho avuto un problema nel discutere l'uso di classmap e mi ci è voluto un po' di tempo per capirlo. Presumevo che il tipo WSDL a cui si riferivano i documenti fosse il nome dell'elemento restituito nel SOAP, quindi,

E mi chiedevo perché mappare
"classmap"=>array("nodo"=>"MioNodo")

Fatto niente.
Questo perché nel mio WSDL ho definito il nodo come:

La mappa di classe di cui avevo bisogno era:
"classmap"=>array("nodeType"=>"MyNode")

Sono riuscito a trovare i nomi dei tipi utilizzando SoapClient->__getTypes()
Successivamente, ho capito dove avrei potuto cercare all'interno del WSDL il nome del tipo di cui avevo bisogno.

Non so se mi sono perso qualcosa di dolorosamente ovvio, ma forse questo può chiarire alcuni documenti.

Jon

Abbiamo riscontrato alcuni problemi utilizzando SoapClient connettendoci a un server esterno tramite Microsoft ISA (attualmente v.2006 ma questo potrebbe applicarsi anche ad altre versioni). Forniamo proxy_host, proxy_port, proxy_login e proxy_password ma il server ISA riporta il login nel suo registra come "anonimo".

Il nostro amministratore di sistema ritiene che ciò sia dovuto al fatto che PHP non fornisce informazioni NTLN (protocollo di sicurezza di Windows) nel formato corretto (e se debba funzionare con proxy proprietari è ovviamente un altro dibattito). Abbiamo provato "nome utente", "DOMINIO\nome utente" senza alcun effetto. La soluzione è aggiungere un'eccezione nel server ISA per il nome host/IP di destinazione; è quindi possibile fornire null per proxy_login e proxy_password e la connessione dovrebbe quindi funzionare come previsto.

In una nota leggermente correlata, se riscontri problemi assicurati che il numero di porta sia fornito come numero intero. Alcune versioni di PHP non utilizzeranno il proxy con SoapClient se il numero di porta viene fornito come stringa.

Jan su bestbytes punto de

PUOI ottenere un wsdl, se è richiesta l'autenticazione di base:

$accedi = "berto";
$password= "password bert";

$cliente= nuovoSoapClient(
"http://". urlencode($accedi) . ":" . urlencode($password) . "@www.server.com/percorso/del/wsdl",
vettore(
"login"=> $accedi,
"parola d'ordine"=> $password
)
);

?>

informazioni su nicksilvestro punto net

Per chiunque abbia problemi con ArrayOf_xsd_string e riceva un errore simile a "Nessun deserializzatore definito per il tipo di array (http://www.w3.org/2001/XMLSchema)string"
Prova a utilizzare il parametro "features", impostato su SOAP_USE_XSI_ARRAY_TYPE: questo assicura che venga utilizzato il deserializzatore corretto.

Per esempio,
$cliente= nuovoSoapClient("alcuni.wsdl", vettore("caratteristiche"=> SOAP_USE_XSI_ARRAY_TYPE));
?>

cecchino

stavo cercando un buon esempio e non sono riuscito a trovarne uno,
finalmente l'ho trovato da qualche parte (ho dimenticato dove), penso che sia questo
il miglior esempio per effettuare una richiesta soap con più parametri

$params->AWSAccessKeyId = AMAZON_API_KEY;
$params->Request->SearchIndex = "Libri";
$params->Richiesta->Parole chiave = "php5 oop";

$amazon = new SoapClient("http://webservices.amazon.com
/AWSECommerceService/AWSECommerceService.wsdl");
$risultato = $amazon->itemSearch($params);

alex su reutone virgola com

Per connettere PHP SOAP a MS SOAP (CRM/EXCHANGE/...) ho creato alcune classi utilizzando la spiegazione seguente e in altri posti.
www.reutone.com/heb/articles.php?instance_id=62&actions=show&id=521

naugtur su Gmail punto com

Eccezione SoapFault: sembra che non sia presente alcun documento XML è già stato menzionato che si verifica quando il tuo server restituisce qualcosa in precedenza ... > etichetta.

Per tutti quelli che hanno problemi con questo, Enessun accesso al codice del server:
Ecco come creare un proxy che pulisca le risposteperVoi

php
/**
* Lezione semplice tratta da una nota di James Ellis
*/
classeProxy_Clientsi estendeSoapClient{
protetto
$cacheDocument= "" ;
funzione pubblica
__costruire($wsdl, $opzioni) {
genitore:: __costruire($wsdl, $opzioni);
}

/**
* SetCacheDocument() imposta il contenuto del documento precedentemente memorizzato nella cache
*/
funzione pubblicaSetCacheDocument($documento) {
$questo-> cacheDocument= $documento;
}

/**
* __doRequest() sovrascrive lo standard SoapClient per gestire una richiesta locale
*/
funzione pubblica__doRequest() {
ritorno
$questo-> cacheDocument;
}
}

//inserisci questo codice nella tua funzione o ovunque tu abbia impostato tutte le variabili richieste

$cliente= nuovoSoapClient($wsdl_url, $array_impostazioni);
$vuoto= $cliente-> $metodo($parametri); //chiamalo per ottenere una risposta dal server

$stringa_risposta= $cliente-> __getLastResponse();

//questa parte rimuove materiale
$inizio= strpos($stringa_risposta, ");
$fine= strrpos($stringa_risposta, ">" );
$stringa_risposta= sost($stringa_risposta, $inizio, $fine- $inizio+ 1 );

//prepara il tuo proxy
$procura= nuovoProxy_Client($wsdl_url, $array_impostazioni);
//e riempilo con la risposta del server
$procura-> SetCacheDocument($stringa_risposta);

$e_finalmente_il_risultato_è= $procura-> $metodo($parametri);

stampa_r($e_finalmente_il_risultato_è); //questo ti permette di vedere cosa c'è

?>

$method è il nome del metodo, ad esempio $method="getVersion";
$params - parametri tipici per un metodo soap

Suggerimenti per gli utenti:

    Se conosci il file WSDL, puoi impostare un collegamento rapido ai moduli client utilizzando
    http://www.?template=/clientform.html&fn=soapform
    &SoapTemplate=none&SoapWSDL=Il tuo_file_WSDL
    O
    http://www..html?SoapWSDL=Il tuo_file_WSDL

    Il server memorizza nella cache i file WSDL durante le normali operazioni per migliorare le prestazioni. Se apporti modifiche a un file WSDL, seleziona il file NO casella di controllo.

Suggerimenti per gli sviluppatori:

    Utilizzo<documentazione> quando possibile nel file WSDL per fornire istruzioni. Verrà visualizzato nel modulo cliente.

    Utilizza il tipo di enumerazione se un elemento ha un numero fisso di valori. Verranno visualizzati come caselle a discesa.

Caratteristiche principali:

    Supporta sia lo schema XML del 1999 che quello del 2001. Lo strumento utilizza lo schema definito nel file WSDL per costruire richieste SOAP.

    Supporta array e array di strutture. Sono supportati solo gli array unidimensionali. Siamo spiacenti, nessun array sparsi.

    In grado di serializzare tipi di dati complessi e matrici di tipi di dati complessi, anche strutture incorporate multilivello.

    Gestione di ID/HREF sia nei messaggi SOAP che nelle definizioni di schema.

    Supporta sia la sezione SOAP 5/7 che le codifiche documento/letterale.

Dettagli tecnici-- Associazione dinamica dei servizi SOAP

Un'associazione è un contratto tra la logica del client e la logica del server. Esistono due tipi di associazioni in SOAP: associazione di oggetti (o associazione SOAP) e associazione di parametri. La maggior parte dei toolkit SOAP esegue collegamenti di oggetti statici generando oggetti proxy lato client. Il problema è che, a differenza del modulo di programmazione tradizionale in cui gli oggetti/interfacce sono stabili, i servizi web sono soggetti a modifiche in qualsiasi momento senza preavviso, perché spesso sono posseduti/controllati da terze parti. Un altro problema si verifica quando il numero di servizi web a cui accedere aumenta, il codice sorgente generato potrebbe rapidamente diventare un incubo per la manutenzione. Infine, quando non si conoscono i servizi web a cui accedere, cosa più spesso probabile, l'associazione anticipata diventa impossibile, o quantomeno difficile. Generare un oggetto proxy per un servizio da costruire in futuro è un progetto di ricerca interessante.

Il client SOAP generico dimostra i collegamenti dinamici (o collegamenti di runtime) di servizi e parametri SOAP. Un oggetto viene generato in fase di esecuzione quando viene specificato il file WSDL e i valori dei parametri vengono associati a un messaggio SOAP appena prima della consegna. La tecnica dell'associazione tardiva (o associazione ritardata) potrebbe ridurre notevolmente i costi di manutenzione, poiché un singolo client può essere utilizzato per accedere a molti servizi Web.

Qui a LeaseWeb lavoriamo molto con i servizi web SOAP per integrare tra loro le nostre applicazioni interne. Soprattutto durante lo sviluppo e il test delle nostre applicazioni poiché abbiamo bisogno della capacità di esercitarci con le API SOAP.

$ curl -sS http://leaseweb.github.io/php-soap-client/installer | php

Questo scaricherà il file phar nella directory di lavoro corrente e lo renderà eseguibile in modo da poterlo utilizzare immediatamente invocando:

$ ./soap_client

Per installare l'ultima versione master puoi ottenere il codice sorgente direttamente da GitHub, creare un pacchetto del tuo file .phar e installarlo utilizzando GNU Make.
Per poter creare il file .phar è necessario che sia installato Composer. Per saperne di più sul compositore fare riferimento alla loro eccellente documentazione.

# Installa il client soap php $ git clone https://github.com/LeaseWeb/php-soap-client.git $ cd php-soap-client $ compositer.phar install $ make $ sudo make install

Se ricevi un'eccezione phar di compilazione non riuscita durante l'esecuzione, devi impostare phar.readonly = Off nel tuo php.ini. Su una macchina di sviluppo questo va bene, ma sii consapevole dei rischi per la sicurezza quando imposti phar.readonly su Off .

Il comando make install precedente installerà l'applicazione soap_client in /usr/local/bin e la renderà eseguibile in modo da poterla chiamare facilmente in questo modo:

$ soap_client php-soap-client versione 2.1.3 Utilizzo: comando Opzioni: ... Comandi disponibili: call Chiama il servizio remoto con il `metodo` specificato e invia la risposta a stdout. help Visualizza la guida per un comando list Elenca i comandi list-methods Ottieni un elenco dei metodi disponibili per chiamare sul telecomando. request Genera una richiesta SOAP formattata xml per il metodo specificato e invia l'output a stdout. wsdl Ottieni il WSDL di un servizio soap.

Da questo punto in poi presupponiamo che tu abbia installato soap_client.phar sul tuo sistema in /usr/local/bin/soap_client e che la directory /urs/local/bin sia nel tuo $PATH .

Diciamo che vorremmo vedere quali metodi sono disponibili sul servizio remoto http://www.webservicex.net/ConvertTemperature.asmx. Potremmo impartire il seguente comando:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" metodi di elenco

Che produrrà quanto segue:

ConvertiTemp

Se esegui il comando precedente con l'opzione -vvv otterrai un output più dettagliato.
In questo caso l'unico metodo disponibile è ConvertTemp . Vediamo come appare una richiesta XML SOAP per questo metodo:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" richiesta ConvertTemp 0

Se desideri effettuare una richiesta SOAP al metodo ConvertTemp sul servizio remoto, utilizza il comando secondario call:

$ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" chiamata --editor ConvertTemp

Notare l'opzione --editor dopo il sottocomando call. Se utilizzi il flag --editor, soap_client aprirà l'editor specificato nella variabile di ambiente $EDITOR in modo da poter modificare l'XML della richiesta prima di inviarlo.

Se emetti la stessa richiesta più volte, puoi salvare una richiesta soap come file XML locale e passarla a /dev/stdin del comando di chiamata soap_client:

# Ottieni l'xml della richiesta e memorizzalo localmente $ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" request ConvertTemp > my_sample_request.xml # Ora modifica my_sample_request.xml # Ora puoi chiamare il Metodo ConvertTemp con questa richiesta pre-preparata $ soap_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" chiama ConvertTemp< my_sample_request.xml

Poiché ripeterai frequentemente i comandi soap_client in breve tempo mentre esplori un servizio Web remoto, puoi risparmiare tempo impostando una variabile di ambiente SOAPCLIENT_ENDPOINT che contiene l'URL del WSDL. Quando questa variabile di ambiente è impostata, puoi omettere l'opzione della riga di comando --endpoint. Facciamolo ora e chiamiamo il metodo ConvertTemp:

$ export SOAPCLIENT_ENDPOINT="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" $ soap_client call ConvertTemp< my_sample_request.xml

Volevo sapere quanti sono 107,6 gradi Fahrenheit in Celsius, quindi il mio my_sample_request.xml contiene:

$ cat mia_richiesta_campione.xml 107.6 gradi Fahrenheit laureaCelsius

$ soap_client chiama ConvertTemp< my_sample_request.xml stdClass Object ( => 42)

La risposta è 42.

Se preferisci vedere le risposte in formato XML puoi utilizzare l'opzione della riga di comando --xml:

$ soap_client chiamata --xml ConvertTemp< my_sample_request.xml 42

Questo tutorial dovrebbe fornirti informazioni sufficienti per iniziare a esplorare, testare e/o sviluppare API SOAP.
In un futuro post sul blog, continuerò l'argomento del client php soap. Stiamo attualmente lavorando per comprimere l'archivio .phar per il web.

Parte lirica.

Immagina di aver implementato o di implementare un determinato sistema che dovrebbe essere accessibile dall'esterno. Quelli. c'è un determinato server con cui devi comunicare. Ad esempio un server web.

Questo server può eseguire molte azioni, lavorare con il database, eseguire alcune richieste di terze parti ad altri server, eseguire alcuni calcoli, ecc. vivere ed eventualmente svilupparsi secondo lo scenario a lui noto (cioè secondo lo scenario degli sviluppatori). Non è interessante per una persona comunicare con un server del genere, perché potrebbe non essere in grado/volere fornire belle pagine con immagini e altri contenuti di facile utilizzo. È scritto e funziona per funzionare e fornire dati quando richiesto, senza preoccuparsi che siano leggibili dall'uomo, il cliente se ne occuperà da solo.

Altri sistemi, accedendo a questo server, possono già disporre dei dati ricevuti da questo server a propria discrezione: elaborarli, accumularli, fornirli ai propri clienti, ecc.

Bene, una delle opzioni per comunicare con tali server è SOAP. Protocollo di scambio messaggi SOAP xml.

Parte pratica.

Un servizio web (questo è il nome di ciò che fornisce il server e di ciò che utilizzano i client) consente di comunicare con il server con messaggi chiaramente strutturati. Il fatto è che il servizio web non accetta alcun dato. Il servizio web risponderà con un errore a qualsiasi messaggio che non rispetti le regole. L'errore, tra l'altro, sarà anche in formato xml con una struttura chiara (il che non è vero per il testo del messaggio).

WSDL (linguaggio di descrizione dei servizi Web). Anche le regole in base alle quali vengono composti i messaggi per il servizio web sono descritte utilizzando xml e hanno anch'esse una struttura chiara. Quelli. Se un servizio Web offre la possibilità di chiamare un metodo, deve consentire ai client di sapere quali parametri vengono utilizzati per questo metodo. Se il servizio Web prevede una stringa per Metodo1 come parametro e la stringa deve essere denominata Param1, queste regole verranno specificate nella descrizione del servizio Web.

Non solo tipi semplici, ma anche oggetti e raccolte di oggetti possono essere passati come parametri. La descrizione di un oggetto si riduce alla descrizione di ciascun componente dell'oggetto. Se un oggetto è composto da più campi, viene descritto ciascun campo, il suo tipo, il nome (quali sono i possibili valori). I campi possono anche essere di tipo complesso e così via fino a quando la descrizione dei tipi termina con quelli semplici: stringa, booleano, numero, data... Tuttavia, alcuni tipi specifici possono risultare semplici, è importante che i client riesce a capire quali valori possono contenere.

Per i clienti è sufficiente conoscere l'url del servizio web; il wsdl sarà sempre nelle vicinanze da cui potrete avere un'idea dei metodi e dei relativi parametri che questo servizio web mette a disposizione.

Quali sono i vantaggi di tutti questi fronzoli:

  • Nella maggior parte dei sistemi, la descrizione dei metodi e dei tipi avviene automaticamente. Quelli. il programmatore sul server deve solo dire che questo metodo può essere chiamato tramite un servizio web e la descrizione wsdl verrà generata automaticamente.
  • La descrizione, che ha una struttura chiara, è leggibile da qualsiasi cliente soap. Quelli. qualunque sia il servizio web, il cliente capirà quali dati riceve il servizio web. Utilizzando questa descrizione, il client può costruire la propria struttura interna di classi di oggetti, le cosiddette. bind" e. Di conseguenza, il programmatore che utilizza il servizio web deve scrivere qualcosa come (pseudocodice):

    NewUser:=TSoapUser.Create("Vasya","Pupkin","admin"); soap.AddUser(NuovoUtente);

  • Convalida automatica.

    • convalida XML. xml deve essere ben formato. XML non valido: invia immediatamente un errore al client, lascia che sia lui a risolverlo.
    • convalida dello schema. xml deve avere una determinata struttura. xml non corrisponde allo schema: invia immediatamente un errore al client, lascia che sia lui a risolverlo.
    • La verifica dei dati viene eseguita dal server soap in modo che i tipi di dati e le restrizioni corrispondano alla descrizione.
  • L'autorizzazione e l'autenticazione possono essere implementate utilizzando un metodo separato. nativamente. o utilizzando l'autorizzazione http.
  • I servizi web possono funzionare sia tramite il protocollo soap che tramite http, cioè tramite richieste get. Cioè, se i parametri sono dati semplici (senza struttura), puoi semplicemente chiamare il solito get www.site.com/users.asmx/GetUser?Name=Vasia o post. Tuttavia, questo non è ovunque e non sempre.
  • ...vedi su Wikipedia

Ci sono anche molti svantaggi:

  • Dimensioni del messaggio irragionevolmente grandi. Bene, qui la natura stessa di XML è tale che il formato è ridondante, più tag, più informazioni inutili. Inoltre il sapone aggiunge la sua ridondanza. Per i sistemi Intranet il problema del traffico è meno acuto che per Internet, quindi il soap per le reti locali è più richiesto, in particolare Sharepoint dispone di un servizio web soap con il quale è possibile comunicare con successo (con alcune limitazioni).
  • La modifica automatica della descrizione di un servizio Web può danneggiare tutti i client. Ebbene, è così per qualsiasi sistema, se non è supportata la retrocompatibilità con i vecchi metodi, tutto cadrà...
  • Non un aspetto negativo, ma uno svantaggio. Tutte le chiamate ai metodi devono essere atomiche. Ad esempio, quando lavoriamo con un database, possiamo avviare una transazione, eseguire diverse query, quindi eseguire il rollback o il commit. Non ci sono transazioni nel sapone. Una richiesta, una risposta, la conversazione è finita.
  • Gestire la descrizione di cosa c'è sul lato server (è tutto descritto correttamente?) e cosa c'è sul client (cosa mi è stato descritto qui?) può essere piuttosto difficile. Ci sono state diverse volte in cui ho dovuto occuparmi del lato client e convincere il programmatore del server che i suoi dati erano descritti in modo errato, ma lui non riusciva a capirne assolutamente nulla, perché la generazione automatica e non dovrebbe, è una questione di Software. E l'errore, naturalmente, era nel codice del metodo; il programmatore semplicemente non lo ha visto.
  • La pratica dimostra che gli sviluppatori di servizi web sono terribilmente lontani dalle persone che utilizzano questi servizi web. In risposta a qualsiasi richiesta (valida dall'esterno), potrebbe arrivare un errore incomprensibile "Errore 5. Va tutto male". Tutto dipende dalla coscienza degli sviluppatori :)
  • Sono sicuro che ancora non ricordo qualcosa...

Ad esempio, esiste un servizio web aperto belavia:

  • http://86.57.245.235/TimeTable/Service.asmx - punto di ingresso, è presente anche una descrizione testuale dei metodi per sviluppatori di terze parti.
  • http://86.57.245.235/TimeTable/Service.asmx?WSDL - descrizione wsdl di metodi e tipi di dati ricevuti e restituiti.
  • http://86.57.245.235/TimeTable/Service.asmx?op=GetAirportsList - descrizione di un metodo specifico con un esempio del tipo di richiesta xml e di risposta xml.

Puoi creare e inviare manualmente una richiesta come:

POST /TimeTable/Service.asmx HTTP/1.1 Host: 86.57.245.235 Tipo di contenuto: text/xml; charset=utf-8 Content-Length: lunghezza SOAPAction: "http://webservices.belavia.by/GetAirportsList" ru

la risposta arriverà:

HTTP/1.1 200 OK Data: lunedì 30 settembre 2013 00:06:44 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Versione: 4.0.30319 Controllo cache: privato, max -age=0 Tipo di contenuto: text/xml; charset=utf-8 Lunghezza contenuto: 2940

PS In precedenza, il servizio web Aeroflot era stato aperto, ma dopo che 1C ha aggiunto il supporto soap a 8ku, un gruppo di beta tester 1C lo ha installato con successo. Adesso lì qualcosa è cambiato (non conosco l’indirizzo, puoi cercarlo se ti interessa).
Dichiarazione di non responsabilità di ZZY. Ha parlato al livello quotidiano. Puoi calciare.

Ciao a tutti!
È successo così che recentemente ho iniziato a sviluppare servizi web. Ma oggi l'argomento non riguarda me, ma come possiamo scrivere il nostro servizio Web XML basato sul protocollo SOAP 1.2.

Spero che dopo aver letto l'argomento sarai in grado di:

  • scrivere la propria implementazione server di un'applicazione web;
  • scrivere la propria implementazione client di un'applicazione web;
  • scrivere la descrizione del proprio servizio web (WSDL);
  • inviare gli array client dello stesso tipo di dati al server.

Come avrai intuito, tutta la magia verrà eseguita utilizzando PHP e le classi SoapClient e SoapServer integrate. Il nostro coniglio sarà un servizio per l'invio di messaggi SMS.

1 Dichiarazione del problema

1.1 Confini

All'inizio propongo di affrontare il risultato che otterremo alla fine dell'argomento. Come annunciato sopra, scriveremo un servizio per l'invio di messaggi SMS e, più precisamente, riceveremo messaggi da diverse fonti tramite il protocollo SOAP. Dopodiché valuteremo in che forma arrivano sul server. Il processo di accodamento dei messaggi per l'ulteriore recapito al provider, sfortunatamente, va oltre lo scopo di questo post per molte ragioni.

1.2 Quali dati cambieremo?

Ottimo, abbiamo deciso i confini! Il prossimo passo da compiere è decidere quali dati scambieremo tra il server e il client. Su questo argomento ti consiglio di non cavillare troppo e di rispondere subito da solo alle domande principali:

  • Quali dati minimi devono essere inviati al server per inviare un messaggio SMS a un abbonato?
  • Quali dati minimi devono essere inviati dal server per soddisfare le esigenze del cliente?

Qualcosa mi dice che per questo è necessario inviare quanto segue:

  • numero di cellulare e
  • testo del messaggio SMS.

In linea di principio bastano queste due caratteristiche per inviare, ma immagino subito il caso di un SMS con gli auguri di compleanno che ti arrivi alle 3 del mattino, ovvero alle 4! In questo momento sarò molto grato a tutti per non essersi dimenticati di me! Pertanto, invieremo anche al server e

  • data di invio del messaggio SMS.

La prossima cosa che vorrei inviare al server è:

  • Tipo di messaggio.

Questo parametro non è obbligatorio, ma può esserci molto utile se abbiamo bisogno di dire velocemente al capo quanti nostri clienti abbiamo “deliziato” con le nostre novità, e anche fare delle belle statistiche in merito.

Eppure ho dimenticato qualcosa! Se riflettiamo un po' di più, vale la pena notare che il client può inviare al server un messaggio SMS o più messaggi alla volta. In altre parole, un pacchetto di dati può contenere da uno a infiniti messaggi.

Di conseguenza, otteniamo che per inviare un messaggio SMS abbiamo bisogno dei seguenti dati:

  • Numero di cellulare,
  • testo del messaggio SMS,
  • ora di invio del messaggio SMS all'abbonato,
  • tipo di messaggio.

Abbiamo risposto alla prima domanda, ora dobbiamo rispondere alla seconda domanda. E forse mi permetterò di scherzare un po’. Pertanto dal server invieremo solo dati booleani, il cui significato ha il seguente significato:

  • TRUE – il pacchetto ha raggiunto con successo il server, ha superato l'autenticazione ed è stato messo in coda per l'invio al provider SMS
  • FALSO – in tutti gli altri casi

Questo conclude la descrizione della dichiarazione del problema! E infine, passiamo alla parte divertente: scopriamo che tipo di strana bestia è questo SOAP!

2 Cos'è il SAPONE?

In generale, inizialmente non avevo intenzione di scrivere nulla su cosa sia SOAP e volevo limitarmi ai collegamenti al sito w3.org con le specifiche necessarie, nonché ai collegamenti a Wikipedia. Ma alla fine ho deciso di scrivere una breve nota su questo protocollo.

E inizierò la mia storia con il fatto che questo protocollo di scambio dati appartiene a un sottoinsieme di protocolli basati sul cosiddetto paradigma RPC (Remote Procedure Call), il cui antipodo è REST (Representational State Transfer). Puoi leggere di più a riguardo su Wikipedia; i collegamenti agli articoli sono alla fine dell'argomento. Da questi articoli dobbiamo comprendere quanto segue: “L'approccio RPC consente l'utilizzo di un numero limitato di risorse di rete con un gran numero di metodi e un protocollo complesso. Con l’approccio REST, il numero di metodi e la complessità del protocollo sono strettamente limitati, il che significa che il numero di risorse individuali può essere elevato”. Cioè, per noi, questo significa che sul sito nel caso dell'approccio RPC ci sarà sempre un input (link) al servizio e quale procedura chiamare per elaborare i dati in arrivo che trasmettiamo insieme ai dati, mentre con l'approccio REST nel nostro Il sito presenta molti input (link), ognuno dei quali accetta ed elabora solo determinati dati. Se qualcuno che legge sa spiegare la differenza tra questi approcci in modo ancora più semplice, assicurati di scrivere nei commenti!

La prossima cosa che dobbiamo sapere su SOAP è che questo protocollo utilizza lo stesso XML come trasporto, il che da un lato è molto buono, perché Il nostro arsenale include immediatamente tutta la potenza di uno stack di tecnologie basate su questo linguaggio di markup, vale a dire XML-Schema, un linguaggio per descrivere la struttura di un documento XML (grazie Wikipedia!), che consente la convalida automatica dei dati ricevuti dal server dai clienti.

E così, ora sappiamo che SOAP è un protocollo utilizzato per implementare chiamate di procedure remote e utilizza XML come trasporto! Se leggi l'articolo su Wikipedia, puoi anche imparare da lì che può essere utilizzato su qualsiasi protocollo a livello di applicazione e non solo in combinazione con HTTP (sfortunatamente, in questo argomento considereremo solo SOAP su HTTP). E sai cosa mi piace di più di tutto questo? Se non ci sono ipotesi, allora darò un suggerimento: SOAP!... Ancora nessuna ipotesi?... Sei sicuro di aver letto l'articolo su Wikipedia?... In generale, non ti torturerò ulteriormente. Pertanto, andrò direttamente alla risposta: "SOAP (dall'inglese Simple Object Access Protocol - simple protocollo accesso agli oggetti; fino alla specifica 1.2)". La cosa più notevole di questa riga è in corsivo! Non so quali conclusioni hai tratto da tutto ciò, ma vedo quanto segue: poiché questo protocollo non può in alcun modo essere definito "semplice" (e apparentemente anche w3 è d'accordo con questo), dalla versione 1.2 ha smesso di essere decrittografato in qualche modo ! E divenne noto come SOAP, semplicemente SOAP, punto e basta.

Bene, ok, per favore scusami, abbiamo preso la cosa un po' da parte. Come ho scritto prima, XML viene utilizzato come trasporto e i pacchetti che viaggiano tra il client e il server sono chiamati buste SOAP. Se consideri la struttura generale della busta, ti sembrerà molto familiare, perché... assomiglia al markup di una pagina HTML. Ha una sezione principale - Avvolgere, che include sezioni Intestazione E Corpo, O Colpa. IN Corpo i dati vengono trasmessi ed è una sezione obbligatoria della busta, mentre Intestazioneè facoltativo. IN Intestazione potranno essere trasmessi consensi o altri dati non direttamente riferibili ai dati di input delle procedure del servizio web. Di Colpa non c'è niente di speciale da dire, tranne che arriva al client dal server in caso di errori.

Qui è dove finisce la mia storia di revisione sul protocollo SOAP (esamineremo gli inviluppi stessi e la loro struttura in modo più dettagliato quando il nostro client e server impareranno finalmente a eseguirli l'uno con l'altro) e ne inizia una nuova - sul compagno SOAP chiamato WSDL(Linguaggio di descrizione dei servizi Web). Sì, sì, questa è proprio la cosa che spaventa la maggior parte di noi anche solo dal provare a implementare la nostra API su questo protocollo. Di conseguenza, di solito reinventiamo la nostra ruota con JSON come trasporto. Allora, cos'è il WSDL? WSDL è un linguaggio per descrivere servizi web e accedervi, basato sul linguaggio XML (c) Wikipedia. Se questa definizione non ti chiarisce l'intero significato sacro di questa tecnologia, allora proverò a descriverla con parole mie!

WSDL è progettato per consentire ai nostri client di comunicare normalmente con il server. A tale scopo il file con estensione “*.wsdl” descrive le seguenti informazioni:

  • Quali spazi dei nomi sono stati utilizzati?
  • Quali schemi di dati sono stati utilizzati?
  • Quali tipi di messaggi si aspetta il servizio Web dai client?
  • Quali dati appartengono a quali procedure del servizio web,
  • Quali procedure contiene il servizio web?
  • Come dovrebbe il cliente chiamare le procedure del servizio web,
  • A quale indirizzo devono essere inviate le chiamate dei clienti?

Come puoi vedere, questo file è l'intero servizio web. Specificando l'indirizzo del file WSDL nel client, sapremo tutto su qualsiasi servizio web! Di conseguenza, non abbiamo bisogno di sapere assolutamente nulla su dove si trova il servizio web stesso. Tutto quello che devi sapere è la posizione del suo file WSDL! Scopriremo presto che il SOAP non è così spaventoso come dicono i proverbi russi.

3 Introduzione allo schema XML

Ora sappiamo molto su cosa sia SOAP, cosa c'è al suo interno e abbiamo una panoramica dello stack tecnologico che lo circonda. Poiché, prima di tutto, SOAP è un metodo di interazione tra un client e un server e il linguaggio di markup XML viene utilizzato come mezzo di trasporto, in questa sezione capiremo un po' come avviene la convalida automatica dei dati utilizzando schemi XML.

Il compito principale del diagramma è descrivere la struttura dei dati che elaboreremo. Tutti i dati negli schemi XML sono suddivisi in semplice(scalare) e complesso(strutture) tipi. I tipi semplici includono i seguenti tipi:

  • linea,
  • numero,
  • valore booleano,
  • data di.

Qualcosa di molto semplice che non ha estensioni all'interno. Il loro antipodo sono i tipi complessi complessi. L’esempio più semplice di un tipo complesso che viene in mente a tutti sono gli oggetti. Ad esempio, un libro. Il libro è composto da proprietà: autore, Nome, prezzo, Numero ISBN eccetera. E queste proprietà, a loro volta, possono essere di tipo semplice o complesso. E il compito dello schema XML è descriverlo.

Suggerisco di non andare lontano e scrivere uno schema XML per il nostro messaggio SMS! Di seguito la descrizione xml del messaggio SMS:

71239876543 Messaggio di prova 2013-07-20T12:00:00 12

Il nostro diagramma di tipo complesso sarà simile al seguente:

Questa voce recita come segue: Abbiamo una variabile " Messaggio" tipo " Messaggio" ed esiste un tipo complesso chiamato " Messaggio", che consiste in un insieme sequenziale di elementi " telefono" tipo corda, « testo" tipo corda, « data" tipo appuntamento, « tipo" tipo decimale. Questi tipi sono semplici e sono già definiti nella descrizione dello schema. Congratulazioni! Abbiamo appena scritto il nostro primo schema XML!

Penso che il significato degli elementi " elemento" E " tipocomplesso"Tutto ti è diventato più o meno chiaro, quindi non ci concentreremo più su questi e passiamo direttamente all'elemento compositore" sequenza" Quando usiamo l'elemento compositore " sequenza“Si informa che gli elementi in esso contenuti devono sempre essere posizionati nella sequenza specificata nello schema e sono tutti obbligatori. Ma non disperare! Ci sono altri due elementi compositore negli schemi XML: " scelta" E " Tutto" Compositore" scelta" annuncia che deve esserci uno degli elementi elencati in esso, e il compositore " Tutto» – qualsiasi combinazione degli elementi elencati.

Come ricorderete, nella prima sezione dell'argomento abbiamo concordato che in un pacchetto possono essere trasmessi da uno a infiniti messaggi SMS. Pertanto, propongo di capire come tali dati vengono dichiarati nello schema XML. La struttura generale del pacchetto potrebbe assomigliare a questa:

71239876543 Messaggio di prova 1 2013-07-20T12:00:00 12 71239876543 Messaggio di prova N 2013-07-20T12:00:00 12

Il diagramma per un tipo così complesso sarà simile al seguente:

Il primo blocco contiene la familiare dichiarazione del tipo complesso “ Messaggio" Se hai notato, in ogni tipo semplice incluso in " Messaggio", sono stati aggiunti nuovi attributi chiarificatori" minSi verifica" E " maxOccurs" Come puoi intuire dal nome, il primo ( minSi verifica) indica che questa sequenza deve contenere almeno un elemento di tipo " telefono», « testo», « data" E " tipo", mentre il successivo ( maxOccurs) ci dichiara che esiste al massimo uno di questi elementi nella nostra sequenza. Di conseguenza, quando scriviamo i nostri schemi per qualsiasi dato, ci viene data la più ampia scelta su come configurarli!

Il secondo blocco del diagramma dichiara l'elemento " messageList" tipo " Elenco messaggi" È chiaro che" Elenco messaggi" è un tipo complesso che contiene almeno un elemento " Messaggio", ma il numero massimo di tali elementi non è limitato!

4 Scrivi il tuo WSDL

Ricordi che WSDL è il nostro servizio web? Spero che ti ricordi! Mentre lo scriviamo, il nostro piccolo servizio web verrà eseguito su di esso. Pertanto, suggerisco di non scherzare.

In generale, affinché tutto funzioni correttamente per noi, dobbiamo trasferire al client un file WSDL con il tipo MIME corretto. Per fare ciò è necessario configurare opportunamente il proprio server web, ovvero impostare il tipo MIME per i file con estensione “*.wsdl” sulla riga seguente:

Applicazione/wsdl+xml

Ma in pratica, di solito invio l'intestazione HTTP tramite PHP " testo/xml»:

Intestazione("Tipo contenuto: text/xml; charset=utf-8");

e tutto ha funzionato alla grande!

Voglio avvisarti subito che il nostro semplice servizio web avrà una descrizione piuttosto impressionante, quindi non allarmarti, perché... La maggior parte del testo è acqua obbligatoria e, dopo averlo scritto una volta, puoi copiarlo costantemente da un servizio web all'altro!

Poiché WSDL è XML, è necessario scriverlo direttamente nella prima riga. L'elemento root del file dovrebbe sempre essere chiamato " definizioni»:

Tipicamente, WSDL è composto da 4-5 blocchi principali. Il primo blocco è la definizione di un servizio web o, in altre parole, il punto di ingresso.

Qui dice che abbiamo un servizio chiamato..." SMSService" In linea di principio, tutti i nomi nel file WSDL possono essere modificati da te in qualsiasi cosa tu voglia, perché non svolgono assolutamente alcun ruolo.

Successivamente lo annunciamo nel nostro servizio web " SMSService" c'è un punto di ingresso ("porto") chiamato " PortaServizioSms" È a questo punto di ingresso che verranno inviate tutte le richieste dai client al server. E indicare nell'elemento “ indirizzo» collegamento al file del gestore che accetterà le richieste.

Una volta definito il servizio web e specificato il relativo punto di ingresso, dobbiamo associare ad esso le procedure supportate:

Per fare ciò, elenca quali operazioni e in quale forma verranno chiamate. Quelli. per il porto" PortaServizioSms" un'associazione è definita sotto il nome " SmsServiceBinding", che ha un tipo di chiamata " rpc"e HTTP viene utilizzato come protocollo di trasmissione. Pertanto, abbiamo indicato qui che effettueremo una chiamata RPC su HTTP. Successivamente descriviamo quali procedure ( operazione) sono supportati nel servizio Web. Sosterremo una sola procedura –” inviare SMS" Attraverso questa procedura i nostri meravigliosi messaggi verranno inviati al server! Dopo aver dichiarato la procedura, è necessario indicare in quale forma verranno trasmessi i dati. In questo caso si indica che verranno utilizzate buste SOAP standard.

Successivamente, dobbiamo associare la procedura ai messaggi:

Per fare ciò specifichiamo che la nostra associazione è di tipo " TipoPortaServizioSms" e nell'elemento " portType"con il nome dello stesso tipo si indica l'associazione delle procedure ai messaggi. E così, il messaggio in arrivo (dal client al server) si chiamerà “ inviaSmsRequest", e in uscita (dal server al client)" sendSmsResponse" Come tutti i nomi in WSDL, i nomi dei messaggi in entrata e in uscita sono arbitrari.

Ora dobbiamo descrivere i messaggi stessi, ad es. in entrata e in uscita:

Per fare questo aggiungiamo gli elementi " Messaggio"con nomi" inviaSmsRequest" E " sendSmsResponse"rispettivamente. In essi indichiamo che l'input dovrebbe essere una busta la cui struttura corrisponde al tipo di dati " Richiesta" Successivamente viene restituita una busta dal server contenente il tipo di dati - “ Risposta».

Ora dobbiamo fare solo una piccola cosa: aggiungere una descrizione di questi tipi al nostro file WSDL! E come pensi che il WSDL descriva i dati in entrata e in uscita? Penso che tu abbia già capito tutto molto tempo fa e ti sia detto che usare gli schemi XML! E avrai assolutamente ragione!

Puoi congratularti con noi! Il nostro primo WSDL è stato scritto! E siamo un passo avanti verso il raggiungimento del nostro obiettivo.
Successivamente, esamineremo ciò che PHP ci offre per sviluppare le nostre applicazioni distribuite.

5 Il nostro primo server SOAP

In precedenza ho scritto che per creare un server SOAP in PHP utilizzeremo la classe SoapServer integrata. Affinché tutte le ulteriori azioni avvengano nello stesso modo in cui ho fatto io, dovrai modificare leggermente il tuo PHP. Per essere ancora più precisi, devi assicurarti di avere installata l’estensione “php-soap”. È meglio leggere come installarlo sul tuo server web sul sito ufficiale di PHP (vedi l'elenco dei riferimenti).

Dopo che tutto è stato installato e configurato, dovremo creare un file nella cartella principale del nostro hosting” smsservice.php» con il seguente contenuto:

setClass("SoapSmsGateWay"); //Avvia il server $server->handle();

Spero che non sia necessario spiegare cosa c'è sopra la linea con la funzione "ini_set". Perché lì viene determinato quali intestazioni HTTP invieremo dal server al client e l'ambiente è configurato. Nella riga "ini_set" disabilitiamo la memorizzazione nella cache del file WSDL in modo che le nostre modifiche abbiano immediatamente effetto sul client.

Ora veniamo al server! Come puoi vedere, l'intero server SOAP occupa solo tre righe! Nella prima riga creiamo una nuova istanza dell'oggetto SoapServer e passiamo l'indirizzo della nostra descrizione WSDL del servizio web al suo costruttore. Ora sappiamo che si troverà nella root dell'hosting in un file dal nome autoesplicativo “ smsservice.wsdl.php" Nella seconda riga diciamo al server SOAP quale classe deve essere estratta per elaborare la busta ricevuta dal client e restituire la busta con la risposta. Come avrai intuito, è in questa classe che verrà descritto il nostro unico metodo inviare SMS. Sulla terza riga avviamo il server! Questo è tutto, il nostro server è pronto! Con il quale mi congratulo con tutti noi!

Ora dobbiamo creare il file WSDL. Per fare ciò, puoi semplicemente copiarne il contenuto dalla sezione precedente oppure prenderti delle libertà e “modellarlo” un po’:

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// schemas.xmlsoap.org/wsdl/http/" name="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservice.php" />

A questo punto dovremmo essere completamente soddisfatti del server risultante, perché Possiamo registrare le buste in arrivo e poi analizzare con calma i dati in arrivo. Per poter ricevere qualsiasi cosa sul server, abbiamo bisogno di un client. Allora veniamo al dunque!

6 Client SOAP in arrivo

Prima di tutto dobbiamo creare un file in cui scriveremo il client. Come al solito, lo creeremo nella root dell'host e lo chiameremo " client.php", e all'interno scriveremo quanto segue:

ListaMessaggi = nuova ListaMessaggi(); $req->messageList->message = nuovo messaggio(); $req->messageList->messaggio->telefono = "79871234567"; $req->messageList->message->text = "Messaggio di prova 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->messaggio->tipo = 15; $client = new SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($client->sendSms($req));

Descriviamo i nostri oggetti. Quando abbiamo scritto il WSDL, descriveva tre entità per la busta in entrata al server: Richiesta, Elenco messaggi E Messaggio. Di conseguenza classi Richiesta, Elenco messaggi E Messaggio sono riflessi di queste entità nel nostro script PHP.

Una volta definiti gli oggetti, dobbiamo creare un oggetto ( $rich), che invieremo al server. Dopodiché arrivano le due linee per noi più care! Il nostro cliente SOAP! Che tu ci creda o no, questo è sufficiente affinché il nostro server inizi a ricevere messaggi dal client, nonché affinché il nostro server li riceva ed elabori con successo! Nel primo creiamo un'istanza della classe SoapClient e passiamo l'indirizzo della posizione del file WSDL al suo costruttore, e nei parametri indichiamo esplicitamente che lavoreremo utilizzando il protocollo SOAP versione 1.2. Nella riga successiva chiamiamo il metodo inviare SMS oggetto $cliente e visualizzare immediatamente il risultato nel browser.
Eseguiamolo e vediamo cosa abbiamo finalmente ottenuto!

Il seguente oggetto mi è stato restituito dal server:

Oggetto (stdClass) public "status" => booleano vero

E questo è fantastico, perché... Ora sappiamo per certo che il nostro server funziona e non solo funziona, ma può anche restituire alcuni valori al client!

Adesso diamo un'occhiata al log che conserviamo prudentemente lato server! Nella sua prima parte vediamo i dati grezzi arrivati ​​sul server:

79871234567 Messaggio di prova 1 21-07-2013 15:00:00.26 15

Questa è la busta. Ora sai che aspetto ha! Ma difficilmente saremo interessati a guardarlo continuamente, quindi deserializziamo l'oggetto dal file di registro e vediamo se va tutto bene:

Oggetto(stdClass) public "messageList" => oggetto(stdClass) public "messaggio" => oggetto(stdClass) public "telefono" => string "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 1 " (lunghezza=37) public "data" => stringa "2013-07-21T15:00:00.26" (lunghezza=22) public "tipo" => stringa "15" (lunghezza=2)

Come puoi vedere, l'oggetto è stato deserializzato correttamente, per questo voglio congratularmi con tutti noi! Qualcosa di più interessante ci aspetta dopo! Vale a dire, invieremo al client al server non solo un messaggio SMS, ma un intero pacchetto (per essere più precisi, tre)!

7 Invio di oggetti complessi

Pensiamo a come trasferire un sacco di messaggi al server in un pacchetto? Probabilmente il modo più semplice sarebbe organizzare un array all'interno dell'elemento messageList! Facciamolo:

// crea un oggetto da inviare al server $req = new Request(); $req->ListaMessaggi = nuova ListaMessaggi(); $msg1 = nuovo messaggio(); $msg1->telefono = "79871234567"; $msg1->text = "Messaggio di prova 1"; $msg1->data = "2013-07-21T15:00:00.26"; $msg1->tipo = 15; $msg2 = nuovo messaggio(); $msg2->telefono = "79871234567"; $msg2->text = "Messaggio di prova 2"; $msg2->data = "2014-08-22T16:01:10"; $msg2->tipo = 16; $msg3 = nuovo messaggio(); $msg3->telefono = "79871234567"; $msg3->text = "Messaggio di prova 3"; $msg3->data = "2014-08-22T16:01:10"; $msg3->tipo = 17; $req->messageList->messaggio = $msg1; $req->messageList->messaggio = $msg2; $req->messageList->messaggio = $msg3;

I nostri registri indicano che il seguente pacchetto è stato ricevuto dal client:

79871234567 Messaggio di prova 1 21-07-2013 15:00:00.26 15 79871234567 Messaggio di prova 2 22/08/2014 16:01:10 16 79871234567 Messaggio di prova 3 22/08/2014 16:01:10 17

Che sciocchezza, dici? E in un certo senso avrai ragione, perché... Non appena abbiamo appreso che l'oggetto ha lasciato il client, è arrivato al nostro server assolutamente nella stessa forma sotto forma di busta. È vero, i messaggi SMS non erano serializzati in XML nel modo di cui avevamo bisogno: dovevano essere racchiusi in elementi Messaggio, Non in Struttura. Ora vediamo in che forma un oggetto del genere arriva al metodo inviare SMS:

Oggetto(stdClass) public "messageList" => oggetto(stdClass) public "messaggio" => oggetto(stdClass) public "Struct" => array (dimensione=3) 0 => oggetto(stdClass) public "telefono" => stringa "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 1" (lunghezza=37) public "data" => stringa "2013-07-21T15:00:00.26" (lunghezza=22) public " type" => string "15" (lunghezza=2) 1 => oggetto(stdClass) public "telefono" => string "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 2" (lunghezza= 37) public "data" => string "2014-08-22T16:01:10" (lunghezza=19) public "tipo" => string "16" (lunghezza=2) 2 => oggetto(stdClass) public "telefono " => string "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 3" (lunghezza=37) public "data" => string "2014-08-22T16:01:10" (lunghezza= 19) public "tipo" => stringa "17" (lunghezza=2)

Cosa ci dà questa conoscenza? Solo che il percorso che abbiamo scelto non è corretto e non abbiamo ricevuto risposta alla domanda: "Come possiamo ottenere la struttura dati corretta sul server?" Ma suggerisco di non disperare e di provare a convertire il nostro array nel tipo un oggetto:

$req->messageList->messaggio = (oggetto)$req->messageList->messaggio;

In questo caso riceveremo un'altra busta:

79871234567 Messaggio di prova 1 21-07-2013 15:00:00.26 15 79871234567 Messaggio di prova 2 22/08/2014 16:01:10 16 79871234567 Messaggio di prova 3 22/08/2014 16:01:10 17

È entrato nel metodo inviare SMS l'oggetto ha la seguente struttura:

Oggetto(stdClass) public "messageList" => oggetto(stdClass) public "messaggio" => oggetto(stdClass) public "BOGUS" => array (dimensione=3) 0 => oggetto(stdClass) public "telefono" => stringa "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 1" (lunghezza=37) public "data" => stringa "2013-07-21T15:00:00.26" (lunghezza=22) public " type" => string "15" (lunghezza=2) 1 => oggetto(stdClass) public "telefono" => string "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 2" (lunghezza= 37) public "data" => string "2014-08-22T16:01:10" (lunghezza=19) public "tipo" => string "16" (lunghezza=2) 2 => oggetto(stdClass) public "telefono " => string "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 3" (lunghezza=37) public "data" => string "2014-08-22T16:01:10" (lunghezza= 19) public "tipo" => stringa "17" (lunghezza=2)

Per quanto mi riguarda, “la somma non cambia cambiando i luoghi dei termini” (c). Che cosa FALSO, Che cosa Struttura– non abbiamo ancora raggiunto il nostro obiettivo! E per raggiungere questo obiettivo, dobbiamo assicurarci che al posto di questi nomi incomprensibili venga visualizzato quello nativo Messaggio. Ma l'autore non sa ancora come raggiungere questo obiettivo. Pertanto, l’unica cosa che possiamo fare è sbarazzarci del contenitore in più. In altre parole, ora ci assicureremo che invece di Messaggio divenne FALSO! Per fare ciò, modificare l'oggetto come segue:

// crea un oggetto da inviare al server $req = new Request(); $msg1 = nuovo messaggio(); $msg1->telefono = "79871234567"; $msg1->text = "Messaggio di prova 1"; $msg1->data = "2013-07-21T15:00:00.26"; $msg1->tipo = 15; $msg2 = nuovo messaggio(); $msg2->telefono = "79871234567"; $msg2->text = "Messaggio di prova 2"; $msg2->data = "2014-08-22T16:01:10"; $msg2->tipo = 16; $msg3 = nuovo messaggio(); $msg3->telefono = "79871234567"; $msg3->text = "Messaggio di prova 3"; $msg3->data = "2014-08-22T16:01:10"; $msg3->tipo = 17; $req->elencomessaggi = $msg1; $req->elencomessaggi = $msg2; $req->messageList = $msg3; $req->elencomessaggi = (oggetto)$req->elencomessaggi;

Cosa succede se siamo fortunati e dal diagramma esce il nome corretto? Per fare ciò, diamo un'occhiata alla busta arrivata:

79871234567 Messaggio di prova 1 21-07-2013 15:00:00.26 15 79871234567 Messaggio di prova 2 22/08/2014 16:01:10 16 79871234567 Messaggio di prova 3 22/08/2014 16:01:10 17

Sì, il miracolo non è avvenuto! FALSO– non vinceremo! Vieni a inviare SMS l'oggetto in questo caso sarà simile a questo:

Oggetto(stdClass) public "messageList" => oggetto(stdClass) public "BOGUS" => array (dimensione=3) 0 => oggetto(stdClass) public "telefono" => stringa "79871234567" (lunghezza=11) public " testo" => string "Messaggio di prova 1" (lunghezza=37) public "data" => string "2013-07-21T15:00:00.26" (lunghezza=22) public "tipo" => string "15" (lunghezza =2) 1 => oggetto(stdClass) public "telefono" => string "79871234567" (lunghezza=11) public "testo" => string "Messaggio di prova 2" (lunghezza=37) public "data" => string " 2014-08-22T16:01:10" (lunghezza=19) public "tipo" => stringa "16" (lunghezza=2) 2 => oggetto(stdClass) public "telefono" => stringa "79871234567" (lunghezza= 11) public "testo" => string "Messaggio di prova 3" (lunghezza=37) public "data" => string "2014-08-22T16:01:10" (lunghezza=19) public "tipo" => string " 17" (lunghezza=2)

Come si suol dire: “Quasi”! Su questa nota (un po’ triste), propongo di concludere lentamente le cose e di trarre alcune conclusioni per noi stessi.

8 Conclusione

Finalmente siamo arrivati ​​qui! Scopriamo cosa puoi fare ora:

  • puoi scrivere il file WSDL necessario per il tuo servizio web;
  • puoi facilmente scrivere il tuo client in grado di comunicare con il server tramite SOAP;
  • puoi scrivere il tuo server che comunica con il mondo esterno tramite SOAP;
  • puoi inviare array dello stesso tipo di oggetti al server dal tuo client (con alcune restrizioni).

Abbiamo anche fatto alcune scoperte durante la nostra piccola ricerca:

  • la classe nativa SoapClient non serializza correttamente strutture dati dello stesso tipo in XML;
  • quando serializza un array in XML crea un elemento aggiuntivo chiamato Struttura;
  • quando si serializza un oggetto in XML crea un elemento aggiuntivo chiamato FALSO;
  • FALSO meno malvagio di Struttura a causa del fatto che la busta è più compatta (gli spazi dei nomi aggiuntivi non vengono aggiunti all'intestazione XML della busta);
  • Sfortunatamente, la classe SoapServer non convalida automaticamente i dati della busta con il nostro schema XML (forse neanche altri server lo fanno).