im trying to make a xml request to a ws using guzzle,(and i try with curl to) in php but always the response its in plain text no in xml
$client = new \GuzzleHttp\Client(['verify' => false]);
$soapRequest = <<<XML
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/" xmlns:san="mywebsservice">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Action>http://tempuri.org/mywebsservice</wsa:Action>
<To soap:mustUnderstand="1" xmlns="http://www.w3.org/2005/08/addressing">mywebsservice </To>
</soap:Header>
<soap:Body>
<tem:GetSecurityToken>
<tem:request>
<san:Connection>mywebsservice</san:Connection>
<san:Passwoord>mywebsservice</san:Passwoord>
<san:System>mywebsservice</san:System>
<san:UserName>mywebsservice</san:UserName>
</tem:request>
</tem:GetSecurityToken>
</soap:Body>
</soap:Envelope>
XML;
$request = $client->request('POST','mywebsservice', [
'headers' => [
'Content-Type' => 'application/soap+xml'
],
'body' => $soapRequest
]);
$response = $request->getBody()->getContents();
var_dump($response);
this is the response
this is the response
string(1870) "
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://tempuri.org/webservices/GetSecurityTokenResponse</a:Action>
<ActivityId CorrelationId="cf1c12da-af1b-4013-ba89-25db2fa67dc1" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">00000000-0000-0000-0000-000000000000</ActivityId>
</s:Header>
<s:Body>
<GetSecurityTokenResponse xmlns="http://tempuri.org/">
<GetSecurityTokenResult xmlns:b="webservices" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:AccessToken>token access</b:AccessToken>
<b:IdToken>the token</b:IdToken>
<b:TokenType>Bearer</b:TokenType>
</GetSecurityTokenResult>
</GetSecurityTokenResponse>
</s:Body>
</s:Envelope>
"
The headers you are sending is what the receiving server uses to decide what content to serve. It will still be text content though, but only with a different Content-Type header.
guzzlehttp/guzzle 6.x
The $response->json() and $response->xml() helpers were removed in 6.x. The following lines can be used to replicate that behaviour:
// Get an associative array from a JSON response.
$data = json_decode($response->getBody(), true);
See https://www.php.net/manual/en/function.json-decode.php
// Get a `SimpleXMLElement` object from an XML response.
$xml = simplexml_load_string($response->getBody());
See https://www.php.net/manual/en/function.simplexml-load-string.php
guzzlehttp/guzzle 5.x
Guzzle 5.x has some shortcuts to help you out:
$client = new Client(['base_uri' => 'https://example.com']);
$response = $client->get('/');
// $response = Psr\Http\Message\ResponseInterface
$body = (string) $response->getBody();
// $body = raw request contents in string format.
// If you dont cast `(string)`, you'll get a Stream object which is another story.
Now whatever you do with $body is up to you. If it is a JSON response, you'd do:
$data = $response->json();
If it is XML, you can call:
$xml = $response->xml();
I never work with XML APIs so i can't give you any more examples on how to traverse the XML you will retrieve.
Related
I am trying to make a SOAP call using POSTMAN that will duplicate a call I'm making with a PHP code for testing purposes, but I am getting a "Bad request" error message, so I assume my conversion is incorrect.
The PHP code is:
//Create xml string
$xml=new DomDocument();
$xml->createCDATASection('![CDATA[]]');
$xml->encoding = 'utf-8';
$xml->xmlVersion = '1.0';
$xml->formatOutput = true;
$xsd=$xml->createElement("xsd:schema");
$xml->appendChild($xsd);
$xsdattr=new DOMAttr("xmlns:xsd","http://www.w3.org/2001/XMLSchema");
$xsd->setAttributeNode($xsdattr);
$ZHT=$xml->createElement("ZHT",str_replace(" ","",$username));
$xsd->appendChild($ZHT);
$PASSWORD=$xml->createElement("PASSWORD",str_replace(" ","",$pwd));
$xsd->appendChild($PASSWORD);
$SNL=$xml->createElement("SNL",$date);
$xsd->appendChild($SNL);
$USERNAME=$xml->createElement("USERNAME","");
$xsd->appendChild($USERNAME);
$RETHASIMA=$xml->createElement("RETHASIMA","1");
$xsd->appendChild($RETHASIMA);
$LANG=$xml->createElement("LANG","");
$xsd->appendChild($LANG);
$ROLE=$xml->createElement("ROLE",$role);
$xsd->appendChild($ROLE);
$xmlstring=$xml->saveXML();
//Set SOAP request
$baseURL=$url;
$arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));
$options = array(
'soap_version' => SOAP_1_1,
'trace' => true,
'exceptions' => true, // disable exceptions
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
'encoding' => 'UTF-8',
'cache_wsdl'=>WSDL_CACHE_NONE,
);
$client = new SoapClient($baseURL."?wsdl", $options);
$p=array(
"P_RequestParams" => array (
"RequestID"=>"48",
"InputData"=>$xmlstring
) ,
"Authenticator" => array (
"Password"=>$authpass,
"UserName"=>$authuser
),
);
//SOAP call and response
$response=$client->ProcessRequestJSON($p);
And This is the body I created in POSTMAN:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProcessRequestJSON xmlns="****">
<P_RequestParams>
<RequestID>48</RequestID>
<InputData>
<?xml version="1.0" encoding="utf-8" ?>
<schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PARAMS>
<ZHT>****</ZHT>
<PASSWORD>****</PASSWORD>
<SNL>***</SNL>
<USERNAME></USERNAME>
<RETHASIMA>1</RETHASIMA>
<LANG></LANG>
<ROLE>1</ROLE>
</PARAMS>
</schema>
</InputData>
</P_RequestParams>
<Authenticator>
<UserName>****</UserName>
<Password>****</Password>
</Authenticator>
</ProcessRequestJSON>
</soap:Body>
</soap:Envelope>
I'm not sure how to set certain things on POSTMAN.
For example, the following line:
$xsdattr=new DOMAttr("xmlns:xsd","http://www.w3.org/2001/XMLSchema");
How do I set a DOMAttr in POSTMAN?
Or the options?
I set up the headers for XML:
Content-Type: text/xml
SOAPAction: "****/ProcessRequestJSON"
Body: Raw (XML)
I tried putting the inner XML (inside the tag) in "" to indicate a string, but that didn't work either.
The PHP code works correctly, the SOAP call is successful and returns a correct response.
The POSTMAN request returns a "Bad Request" error message.
I successfully get response from soap webservice using php curl. I would like to know how can I parse the curl response so that I got each value separately in other to save into database.
my codes:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "http://xxxxxx/WSAutorizaciones/WSAutorizacionLaboratorio.asmx?WSDL",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>
'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthenticationHeader xmlns="https://arssenasa.gob.do/">
<Cedula>001-0946651-5</Cedula>
<Password>xxxxxxx</Password>
<Proveedo>12077</Proveedo>
</AuthenticationHeader>
</soap:Header>
<soap:Body>
<ConsultarAfiliado xmlns="https://arssenasa.gob.do/">
<TipoDocumento>2</TipoDocumento>
<NumDocumento>021827151</NumDocumento>
</ConsultarAfiliado>
</soap:Body>
</soap:Envelope>',
CURLOPT_HTTPHEADER => array("content-type: text/xml"),
))
;
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
The result is displayed like this:
8013-0000655-6021827151MARGARET ADIRASANTANA LORENZO DE CABRAL08CONTRIBUTIVO22/11/197346FEMENINO08
the soap resonse is like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ConsultarAfiliadoResponse xmlns="https://arssenasa.gob.do/">
<ConsultarAfiliadoResult>
<Contrato>8</Contrato>
<Cedula>013-0000655-6</Cedula>
<Nss>021827151</Nss>
<Nombres>MARGARET ADIRA</Nombres>
<Apellidos>SANTANA LORENZO DE CABRAL</Apellidos>
<IdEstado>0</IdEstado>
<CodigoFamiliar>8</CodigoFamiliar>
<IdRegimen xsi:nil="true" />
<Regimen>CONTRIBUTIVO</Regimen>
<FechaNacimiento>22/11/1973</FechaNacimiento>
<Edad>46</Edad>
<Sexo>FEMENINO</Sexo>
<TipoDocumento>0</TipoDocumento>
<CodigoAfiliado>8</CodigoAfiliado>
<MensajeAfiliado />
</ConsultarAfiliadoResult>
</ConsultarAfiliadoResponse>
</soap:Body>
</soap:Envelope>
Here is a possible example of how you could go about getting the XML elements from your SOAP response (below) using SimpleXML which might be included in your PHP installation. Because I'm not sure what order of element data you need for the final output, you might need to rearrange the order of items in the output part below.
Also, in order for this to work, the $soapResponse variable in the code example needs to have no extra space before the start of the <?xml version="1.0" encoding="utf-8"?> line.
If you need to access other elements from the XML data, you should be able to do it with this pattern: $result->ConsultarAfiliadoResult->ElementNameHere.
<?php
$soapResponse = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ConsultarAfiliadoResponse xmlns="https://arssenasa.gob.do/">
<ConsultarAfiliadoResult>
<Contrato>8</Contrato>
<Cedula>013-0000655-6</Cedula>
<Nss>021827151</Nss>
<Nombres>MARGARET ADIRA</Nombres>
<Apellidos>SANTANA LORENZO DE CABRAL</Apellidos>
<IdEstado>0</IdEstado>
<CodigoFamiliar>8</CodigoFamiliar>
<IdRegimen xsi:nil="true" />
<Regimen>CONTRIBUTIVO</Regimen>
<FechaNacimiento>22/11/1973</FechaNacimiento>
<Edad>46</Edad>
<Sexo>FEMENINO</Sexo>
<TipoDocumento>0</TipoDocumento>
<CodigoAfiliado>8</CodigoAfiliado>
<MensajeAfiliado />
</ConsultarAfiliadoResult>
</ConsultarAfiliadoResponse>
</soap:Body>
</soap:Envelope>
XML;
// Remove <soap></soap> related tag information to get plain XML content
$xmlContent = preg_replace('/<soap:.*?>\n/', '', $soapResponse);
$xmlContent = preg_replace('/<\/soap:.*?>\n?/', '', $xmlContent);
// Note: there is an error with the xsi:nil="true" part, but that can be
// suppressed with the following line. If you need to deal with this error,
// more info here: https://www.php.net/manual/en/simplexml.examples-errors.php
libxml_use_internal_errors(true);
$result = new SimpleXMLElement($xmlContent);
// Print out results
printf(
"%s%s%s%s%s%s%s%s%s%s%s%s",
$result->ConsultarAfiliadoResult->Cedula,
$result->ConsultarAfiliadoResult->Nss,
$result->ConsultarAfiliadoResult->Nombres,
$result->ConsultarAfiliadoResult->Apellidos,
$result->ConsultarAfiliadoResult->IdEstado,
$result->ConsultarAfiliadoResult->CodigoFamiliar,
$result->ConsultarAfiliadoResult->Regimen,
$result->ConsultarAfiliadoResult->FechaNacimiento,
$result->ConsultarAfiliadoResult->Edad,
$result->ConsultarAfiliadoResult->Sexo,
$result->ConsultarAfiliadoResult->TipoDocumento,
$result->ConsultarAfiliadoResult->CodigoAfiliado
);
?>
Output:
$ php q22.php
013-0000655-6021827151MARGARET ADIRASANTANA LORENZO DE CABRAL08CONTRIBUTIVO22/11/197346FEMENINO08
After almost a journey of research I finally get the correct way to do it :
//The follow-up of my posting codes
.
.
.
$response = curl_exec($curl);
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//soapBody ')[0];
$array = json_decode(json_encode((array)$body), TRUE);
// in the case I want to grab only one data
//echo $array['ConsultarAfiliadoResponse']['ConsultarAfiliadoResult']['Cedula'];
// to display all data in the array
function dispaly_array_recursive($array_rec){
if($array_rec){
foreach($array_rec as $value){
if(is_array($value)){
dispaly_array_recursive($value);
}else{
echo $value.'<br>';
}
}
}
}
dispaly_array_recursive($array);
No more problem to save into database now
I would like to convert the SOAP XML response into the JSON format. Can anybody please help!
I got below SOAP XML in $response
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:awsse="http://xml.amadeus.com/2010/06/Session_v3" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
<wsa:From>
<wsa:Address>https://nodeD2.test.webservices.amadeus.com/XXXXXXXX</wsa:Address>
</wsa:From>
<wsa:Action>http://webservices.amadeus.com/FMPTBQ_18_1_1A
</wsa:Action>
<wsa:MessageID>urn:uuid:a4844bc6-2e05-e8e4-b589-6f813ecad262</wsa:MessageID>
<wsa:RelatesTo RelationshipType="http://www.w3.org/2005/08/addressing/reply">urn:uuid:ac1c8436-ecaf-4bbb-a9ff-11b466dffe18</wsa:RelatesTo>
<awsse:Session TransactionStatusCode="End"><awsse:SessionId>00896YTRZQPQ</awsse:SessionId><awsse:SequenceNumber>1</awsse:SequenceNumber><awsse:SecurityToken>TRFTGYNBHUYKIOL</awsse:SecurityToken></awsse:Session>
</soapenv:Header>
<soapenv:Body>
<Fare_MasterPricerTravelBoardSearchReply xmlns="http://xml.amadeus.com/FMPTBR_18_1_1A">
<replyStatus><status><advisoryTypeInfo>FQX</advisoryTypeInfo></status></replyStatus>
<conversionRate><conversionRateDetail><currency>USD</currency></conversionRateDetail></conversionRate>
<familyInformation><refNumber>1</refNumber><fareFamilyname>BAGSEAT</fareFamilyname><description>OPTIMA</description><carrier>IB</carrier><services><reference>1</reference><status>CHA</status></services><services><reference>2</reference><status>CHA</status></services><services><reference>3</reference><status>INC</status></services><services><reference>4</reference><status>NOF</status></services><services><reference>5</reference><status>NOF</status></services><services><reference>6</reference><status>NOF</status></services><services><reference>7</reference><status>NOF</status></services></familyInformation>
</Fare_MasterPricerTravelBoardSearchReply>
</soapenv:Body>
</soapenv:Envelope>
I tried this.
$xml = json_decode(json_encode(simplexml_load_string($response)), true);
print '<pre>';
print_r($xml);
print '</pre>';
I got the solution to the problem, working fine
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$response = simplexml_load_string($response);
$dataArray = json_decode(json_encode((array)$response), TRUE);
echo '<pre>';print_r($dataArray);echo '</pre>';die(__FILE__.' On this line '.__LINE__);
My SOAP Request
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.dgpys.deloitte.com" xmlns:ns2="ws.apache.org/namespaces/axis2">
<env:Header>
<ns2:ServiceGroupId>
<BOGUS>urn:uuid:7C2F61BDE7CB9D9C6D1424938568724</BOGUS>
</ns2:ServiceGroupId>
</env:Header>
<env:Body>
<ns1:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ns1:getGunlukParametreRapor>
</env:Body>
</env:Envelope>
Expected SOAP Request
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.dgpys.deloitte.com">
<soap:Header>
<axis2:ServiceGroupId xmlns:axis2="http://ws.apache.org/namespaces/axis2">urn:uuid:479731898147E116AD1424691518968</axis2:ServiceGroupId>
</soap:Header>
<soap:Body>
<ws:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ws:getGunlukParametreRapor>
</soap:Body>
</soap:Envelope>
Tried with following codes:
$options = array(
'trace' => 1,
'exceptions' => 1,
'soap_version' => SOAP_1_2
);
$client = new SoapClient("http://dgpysws.pmum.gov.tr/dgpys/services/EVDServis.wsdl", $options);
$p1 = new stdCLass();
$p1->loginMessage = new stdCLass();
$p1->loginMessage->UserName = new stdCLass();
$p1->loginMessage->UserName->v = "Username";
$p1->loginMessage->Password = new stdCLass();
$p1->loginMessage->Password->v = "Passwor";
$client->login($p1);
$headers[] = new SoapHeader('http//ws.apache.org/namespaces/axis2', 'ServiceGroupId', "UNIQUEID", false);
$client->__setSoapHeaders($headers);
$result = $client->getGunlukParametreRapor(array('date' => '2015-02-22T00:00Z'));
Question is:
These SOAP requests are same?
I'm using SOAP_1_2 and it should be like Expected SOAP Request but my request doesnt looks like to expected format. Missing where?
How can i get the output like as expected?
Note: dgpysws.pmum.gov.tr wsdl address is private area.
They are not the same. To get rid of the BOGUS node you need to use this:
$strHeaderComponent_Session = "<SessionHeader><ServiceGroupId>$theVarWithTheIDGoesHere</ServiceGroupId></SessionHeader>";
$objVar_Session_Inside = new SoapVar($strHeaderComponent_Session, XSD_ANYXML,
null, null, null);
$objHeader_Session_Outside = new SoapHeader('http//ws.apache.org/namespaces/axis2',
'SessionHeader', $objVar_Session_Inside);
// More than one header can be provided in this array.
$client->__setSoapHeaders(array($objHeader_Session_Outside));
try the following
$ns = 'http//ws.apache.org/namespaces/axis2'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('ServiceGroupId' => $UNIQUEID_Token);
//Create Soap Header.
$header = new SOAPHeader($ns, 'axis2', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.dgpys.deloitte.com" xmlns:ns2="ws.apache.org/namespaces/axis2">
<env:Header>
<ns2:ServiceGroupId>
urn:uuid:7C2F61BDE7CB9D9C6D1424938568724
</ns2:ServiceGroupId>
</env:Header>
<env:Body>
<ns1:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ns1:getGunlukParametreRapor>
</env:Body>
</env:Envelope>
And
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.dgpys.deloitte.com">
<soap:Header>
<axis2:ServiceGroupId xmlns:axis2="http://ws.apache.org/namespaces/axis2">urn:uuid:479731898147E116AD1424691518968</axis2:ServiceGroupId>
</soap:Header>
<soap:Body>
<ws:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ws:getGunlukParametreRapor>
</soap:Body>
</soap:Envelope>
Are the same.
env=soap, ns2=ws and ns2=axis2. You can have any prefix to refer to these namespaces as you like. Once you assign the prefix you just refer to it using that in the other places. Only diff was the bogus tag tin first request. Just remove that.
It's my first time with SOAP, I already read all manuals and still stacked with the following example:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<AuthenticationInfo xmlns="https://blabla.com/ws/Quoting">
<strUserName>[username]</strUserName>
<strPassword>[password]</strPassword>
</AuthenticationInfo>
</soap:Header>
<soap:Body>
<GetQuotes xmlns="https://blabla.com/ws/Quoting">
<CallerClientID>0</CallerClientID>
<quoteRequest>
<CapacityCode>2</CapacityCode>
<BabiesCount>0</BabiesCount>
<QuotingOptions>0</QuotingOptions>
</quoteRequest>
<clientIDs>
<int>20295</int>
</clientIDs>
<withUrlParam>false</withUrlParam>
</GetQuotes>
</soap:Body>
</soap:Envelope>
I do not understand how to start the soapclient with authorization, please help.
You need to use SoapHeader. Below is the example.
$ns = 'https://blabla.com/ws/Quoting'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('strUserName' => $someUser,
'strPassword' => $somePass);
//Create Soap Header.
$header = new SOAPHeader($ns, 'AuthenticationInfo', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);