[ Milos911 @ 06.08.2016. 16:40 ] @
Totalno sam nov kad je SOAP u pitanju, pa ne zamerite ako kazem nesto totalno pogresno.
Treba da komuniciram sa nekim serverom, i ovo mi je dato kao promer zahteva koji bih trebao da posaljem:
Code:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" 
xmlns:rad="http://schemas.datacontract.or...07/Radixx.ConnectPoint.Request" 
xmlns:rad1="http://schemas.datacontract.or....ConnectPoint.Security.Request">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:RetrieveSecurityToken>
         <!--Optional:-->
         <tem:RetrieveSecurityTokenRequest>
            <rad:CarrierCodes>
               <!--Zero or more repetitions:-->
               <rad:CarrierCode>
                  <rad:AccessibleCarrierCode>FZ</rad:AccessibleCarrierCode>
               </rad:CarrierCode>
            </rad:CarrierCodes>
            <rad1:LogonID>xxx</rad1:LogonID>
            <rad1:Password>xxxx</rad1:Password>
         </tem:RetrieveSecurityTokenRequest>
      </tem:RetrieveSecurityToken>
   </soapenv:Body>
</soapenv:Envelope>


Php koji sam ja pisao izgleda ovako:
Code:
$url = "http://xxxx?wsdl";
$data =  array(  "LogonID"=>"xxxxx",  "Password"=>"xxxxx");
$client = new SoapClient($url);
$client->__soapCall("RetrieveSecurityToken", $data);


Puca mi kod ove linije gde pozivam funkciju RetrieveSecurityToken sa greskom:
Code:
The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message
 for operation 'RetrieveSecurityToken'. End element 'Body' from namespace 'http://schemas.xmlsoap.org/soap/envelope/' expected. 
Found element 'param1' from namespace ''. Line 2, position 162. in J:\WORK\web\xxx\index.php:25 Stack trace: #0 J:\WORK\web\xxx\index.php(25):
 SoapClient->__soapCall('RetrieveSecurit...', Array) 
#1 {main} thrown in J:\WORK\web\xxxi\index.php on line 25`


Tamo na serveru na koji se kacim ($url), kad otvorim stranicu bez "?wsdl", imam sledeci opis:
Citat:
To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:
svcutil.exe http://xxx.svc?wsdl
You can also access the service description as a single file:

http://.svc?singleWsdl



Totalno sam pogubljen kako i sta, cenim da nisam dobro napisao ovaj $data array.

Pa ako moze neko da me uputi u pravom smeru i kaze mi gde gresim, bilo bi super
[ dusans @ 06.08.2016. 17:20 ] @
Instaliraj fiddler ili tako nešto pa vidi šta dobijaš kao response i šta tu ne valja.
[ Goran Rakić @ 06.08.2016. 18:17 ] @
Ovo bi trebalo da radi:

Code (php):

$url = "http://xxxx?wsdl";
$data = array("LogonID"=>"xxxxx",  "Password"=>"xxxxx");

$client = new SoapClient($url);
$client->RetrieveSecurityToken(array("RetrieveSecurityTokenRequest" => $data));
 


Dodatno za debug možeš da aktiviraš "tracing" u SoapClientu kako bi video XML koji se šalje i stiže:

Code (php):

$client = new SoapClient($url, array('trace' => true));

var_dump($client->__getLastRequest());
var_dump($client->__getLastResponse());
 


Za testiranje i debagovanje, zgodan je soapUI, tamo možeš da napraviš novi projekat, učitaš WSDL i napraviš test primere sa različitim XML zahtevima.
[ Milos911 @ 06.08.2016. 18:46 ] @
Kad probam taj kod izbaci mi:
Code:
Fatal error: Uncaught SoapFault exception: [a:InternalServiceFault] Object reference not set to an instance of an object. in 
J:\work\web\xxxx\index.php:10 Stack trace: #0 J:\work\web\xxxx\index.php(10): SoapClient->__call('RetrieveSecurit...', Array) #1 
J:\work\web\xxxx\index.php(10): SoapClient->RetrieveSecurityToken(Array) #2 {main} thrown in J:\work\web\xxxx\index.php on line 10


a __getLastRequest i getLastResponse iznad poziva za RetrieveSecurityToken izbacuju NULL, ispod ne izbacuju nista..

Sad cu da probam soapUI, mozda mi tamo bude malo jasnije sta se desava :)
[ Goran Rakić @ 06.08.2016. 20:22 ] @
getLast* idu ispod poziva, uz postavljen parametar trace u konstruktoru.

Ne mogu da ne izbace nista, ali ako gledas HTML stranicu moguce da ne vidis ispisani XML kod. Pogledaj View Source stranice.
[ Milos911 @ 06.08.2016. 23:41 ] @
Nema nista, PHP baci fatal error i kraj.
Code:
<br />
<b>Fatal error</b>:  Uncaught SoapFault exception: [a:InternalServiceFault] Object reference not set to an instance of an object.
 in J:\work\web\xxxx\index.php:8
Stack trace:
#0 J:\work\web\xxxx\index.php(8): SoapClient-&gt;__call('RetrieveSecurit...', Array)
#1 J:\work\web\xxxx\index.php(8): SoapClient-&gt;RetrieveSecurityToken(Array)
#2 {main}
  thrown in <b>J:\work\web\xxxx\index.php</b> on line <b>8</b><br />


Sad cu da probam onaj program gore sto si pomenuo pa javljam sta se desava


EDIT:
Probao, preko programa radi kako treba. E sad fazon kako ovo prebaciti u php? Gledam gore url na koji se salje request, nema uopste ?wsdl na kraju. Da nije mozda u tome fazon, da se preuzme wsdl da bi se uzeli podaci pa se nekako konektuje na url bez wsdl i sa njega uzimaju podaci onda?


[Ovu poruku je menjao Milos911 dana 07.08.2016. u 00:57 GMT+1]
[ Goran Rakić @ 07.08.2016. 02:04 ] @
SoapClient učitava WSDL, a u WSDL-u je naveden service endpoint (što je u ovom slučaju ista ta putanja, samo bez ?wsdl na kraju) na koji se SoapClient povezuje.

Problem je što u SoapUI šalješ i CarrierCodes->AccessibleCarrierCode, dok iz PHP-a šalješ samo LogonID i Password.

Code (php):

$data = array("CarrierCodes" => array(0 => array("AccessibleCarrierCode" => "FZ")), "LogonID"=>"xxxxx",  "Password"=>"xxxxx");

$client = new SoapClient($url, array('trace' => true));
$client->RetrieveSecurityToken(array("RetrieveSecurityTokenRequest" => $data));
 
var_dump($client->__getLastRequest());
var_dump($client->__getLastResponse());
 



Lično meni se ne sviđa čitljivost ovakvog zadavanja parametara i više volim da to raspišem ovako:

Code (php):

$code = new StdClass;
$code->AccessibleCarrierCode = "FZ";

$data = new StdClass;
$data->CarrierCodes = array($code);

$data->LogonID = "xxxx";
$data->Password = "xxxx";
 


[Ovu poruku je menjao Goran Rakić dana 07.08.2016. u 03:24 GMT+1]
[ Mister Big Time @ 11.08.2016. 00:31 ] @
Pitaj ih jel imaju kojim slucajem i REST web servis. SOAP je deprecated zlo. Dakle koristis ako bas moras i nemas nikakvog izbora.

Iz mog iskustva sa Oracle-ovom implementacijom, sve se svodi na zaobilazenje SoapClient-a kroz PHP. Mora na ruke jer jedino tako znas sta radis. Dakle formiras XML kakav njihov endpoint ocekuje, i zveknes ga direktno POST-om kao RAW uz obavezno setovanje Content-Type HTTP hader-a na application/xml.

Posto si kroz SoapUI 'produvao kanal' i znas sta ti treba, onda lepo to rokni kao string XML na njihov endpoint bez SoapClient biblioteke.

Inace, SoapUI je dosta zgodan kod ovih stvari, premda Postman isto zavrsava posao kada imas primer SOAP envelope koju treba da saljes.

Vrhunac ludila je rad sa XML-DSIG koji se kaci na SOAP envelope. Ko je taj posao radio ni pakao mu nece tesko pasti :)