PHP SoapClient fails to include function-params in XML properly - php

I try to make a request to a .NET WSDL function called GetPeriodicValues. The function requires some params and the problem is that SoapClient creates an incorrect XML.
This PHP-code...
$client = new SoapClient(self::URL , array('trace' => 1, 'encoding' => 'UTF-8', 'soap_version' => SOAP_1_1));
$params = array('name' => 'myname', 'address' => 'myaddress');
$result = $client->__soapCall('GetPeriodicValues', array('parameters' => $params), array());
...genereates the following request-XML (I have excluded some irrelevant content):
<SOAP-ENV:Body>
<ns1:RequestOf_GetPeriodicValuesParameters/>
</SOAP-ENV:Body>
But I would expect it to create this
<SOAP-ENV:Body>
<ns1:RequestOf_GetPeriodicValuesParameters>
<ns1:name>myname</ns1:name>
<ns1:address>myaddress</ns1:address>
</ns1:RequestOf_GetPeriodicValuesParameters>
</SOAP-ENV:Body>
How should i include the params in the function-call?

Problem solved. What I learned was that the XML-output is dependent on the WSDL and in my case it wanted me to put params in an array with the key "Params". However, looking at the XML return by the WSDL I found no such information, instead it looked like the key "parameters" should be used. I'm not sure, but perhaps something was wrong with the service.

Related

Multidimensional Array with PHP Soap Client

I'm trying to create a SOAP Client, but I need to send a multi-dimensional array (I think) as requested in the documentation, example below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.senior.com.br">
<soapenv:Body>
<ser:ColaboradoresAdmitidos>
<user>String</user>
<password>String</password>
<encryption>Integer</encryption>
<parameters>
<NumEmp>Integer</NumEmp>
<AbrTipCol>String</AbrTipCol>
<IniPer>DateTime</IniPer>
<FimPer>DateTime</FimPer>
</parameters>
</ser:ColaboradoresAdmitidos>
</soapenv:Body>
</soapenv:Envelope>
I create a array like this:
$arguments = [
'user' => 'xxxxx',
'password' => 'xxxxxxxxxx',
'encryption' => 0,
'parameters' => array(
'NumEmp' => 1,
'AbrTipCol' => '1',
'IniPer' => '01/01/2019',
'FimPer' => null
),
];
$client = new SoapClient($url, array('trace' => 1));
dd($arguments, $client->__soapCall("colaboradoresAdmitidos", $arguments), $client->__getLastRequest());
However in the request, it seems that it does not accept the array, in fact I did some tests, and in addition to the first 3 parameters, but none enter the generated XML.
I already made the array in different ways, and changed the parameter value, but it always returns as below:
<?xml version="1.0" encoding="UTF-8"?>\n
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.senior.com.br">
<SOAP-ENV:Body>
<ns1:ColaboradoresAdmitidos>
<user>xxxxxxx</user>
<password>xxxxxxxxx</password>
<encryption>0</encryption>
<parameters/>
</ns1:ColaboradoresAdmitidos>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Someone could help me, because the server understands that the parameter is missing, so I can't execute the query.
Searching the internet, I discovered a lot of people with this problem and who couldn't solve it. I discovered the error.
This happens when the parameters do not match those registered in the WSDL. in my case: the documentation mentions the parameters with a capital letter, however, I had to use it with a small letter.
It seems that the parameter key has to be the same value as the one registered in wsdl.
ex:
$arguments = [
'user' => 'xxxxx',
'password' => 'xxxxxxxxxx',
'encryption' => 0,
'parameters' => array(
'numEmp' => 1,
'abrTipCol' => '1',
'iniPer' => '01/01/2019',
'fimPer' => null
)];

How to remove attribute from envelope in SoapClient

Trying to use PHP-s own SoapClient, but I have come across an obstacle.
I'm using __soapCall for making requests, but the query fails, because encodingStyle attribute is set:
$client = new SoapClient(NULL, array(
'location' => 'http://myUri.com',
'uri' => 'http://namespace.com/producer'
));
$result = $client->__soapCall('GET_ALL');
Now doing $client->__getLastRequest(); shows Envolope node like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
How to remove SOAP-ENV:encodingStyle attribute and still use __soapCall(); ?
Apperantly I was missing "use" parameter in SoapClient construct. Solution:
$client = new SoapClient(NULL, array(
'location' => 'http://myUri.com',
'uri' => 'http://namespace.com/producer',
'use' => SOAP_LITERAL,
));

Soap PHP WSDL XML formatting

So I am using Soap client in PHP and I'm trying to make a request on some WSDL. I try to have a specific output but it seems a bit far from what I try to do. Maybe I don't do this right. I'm a bit new to WSDL.
Here is the result I want:
<SOAP-ENV:Body>
<loc:sendSms>
<loc:addresses>9000000000</loc:addresses>
<loc:senderName>9000000</loc:senderName>
<loc:message>test SMS</loc:message>
</loc:sendSms>
</SOAP-ENV:Body>
This is what I try to fit my requirement, but it ends with a server error:
$MCIResp = (array) $_soapClient->__soapCall('sendSms',
'sendMessage' => array(
'addresses' => '9000000000',
'senderName' => '9000000',
'message' => 'test SMS '
)
);
And this is the error I get from this request:
"SoapFault exception: [Client] SOAP-ERROR: Encoding: object has no
'sendmessage' property";
EDIT: Made some improvements on that by getting inspiration on some posts
Here is my code now:
$_soapClient = new SoapClient(
null,
array(
'location' => 'http://someIP/parlayxsmsgw/services/SendSmsService?wsdl',
'uri' => 'http://someIP/parlayxsmsgw/services/SendSmsService?wsdl',
'trace' => 1,
'cache_wsdl' => WSDL_CACHE_NONE,
'use' => SOAP_LITERAL,
'style' => SOAP_DOCUMENT,
'stream_context' => stream_context_create(array(
'http' => array(
'header' => 'servicekey: someservicekey'
),
)),
)
);
$params = new \SoapVar("<sendSms><addresses>90000000000</addresses><senderName>90000000</senderName><message>test SMS</message></sendSms>",XSD_ANYXML);
And then I do a
$_soapClient->whatEverNameHereWillBeIgnored($params);
This is now the XML I generate:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<sendSms>
<addresses>989127184955</addresses>
<senderName>98307066</senderName>
<message>test SMS</message>
</sendSms>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But I receive this as a response:
Unexpected subelement sendSms
do the "loc:" are mandatory to solve this ? Because when I add it in the raw xml it says that
Undeclared namespace prefix "loc"
Thanks,
I strongly advise you to use a WSDL to PHP generator such as PackageGenerator, it will ease you the request construction so you won't have to wonder how to construct the request, it will be cristal clear.

PHP - SoapClient and typemap to prevent element dissapearing

I am trying to see what is going on when SoapClient is parsing Soap response. When I call $client->__getLastResponse() I get this:
<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
<ns0:Body>
<ns1:ListPositionBranchResponse xmlns:ns1="http://atollon.com/enterprise/wsdl">
<result>OK</result>
<time>0.00505090</time>
<ROWS>
<ROW>
<idPos>1409000</idPos>
<idBranch>122482000</idBranch>
<positionName>ekonom</positionName>
</ROW>
<ROW>
<idPos>1412000</idPos>
<idBranch>122488000</idBranch>
<positionName>IT specialista</positionName>
</ROW>
</ROWS>
</ns1:ListPositionBranchResponse>
</ns0:Body>
</ns0:Envelope>
I create SoapClient this way:
$client = new SoapClient("https://mblue.atollon.com/recruitment.wsdl", array('trace' => 1, 'exceptions'=>true, 'location' => "https://mblue.atollon.com/soap"));
$requestParams = array(
'server' => "SERVER",
'session' => "SESSION"
);
$response = $client->ListPositionBranch($requestParams);
but when I do var_dump of response, there is no idPos element. I have tried it on 64bit Linux machine, but it doesn't work also, so it's not INT limitation. So I wanted to see what is going on, and tried this:
$client = new SoapClient("https://mblue.atollon.com/recruitment.wsdl", array('trace' => 1, 'exceptions'=>true, 'location' => "https://mblue.atollon.com/soap", 'typemap' => array(
array(
'type_ns' => 'http://atollon.com/enterprise/wsdl',
'type_name' => 'idPos',
'to_xml' => 'to_long_xml',
'from_xml' => 'from_long_xml',
)
)));
And the functions themselves:
function to_long_xml($longVal) {
return '<long>' . $longVal . '</long>';
}
function from_long_xml($xmlFragmentString) {
return (string)strip_tags($xmlFragmentString);
}
But the from_long_xml function is not even fired.. I tried to change type_name to I guess all elements in that response, but it never fires it. I am out of ideas - what can be wrong - I am guessing it might be the namespace, but I have tried both listed in xml with no luck. How to get that typemap (or the idPos) working?
Thanks.
type_name in typemap element should be name of type defined in WSDL of service. I had weird experience, that typemap should be defined before classmap element.

Unwanted <param0> node from PHP SoapClient non-wsdl mode

I'm trying to make a request with the PHP SoapClient in non-WSDL mode. I'm passing parameters as a multi-dimensional object as shown in the below code snippet:
$params = new stdClass;
$params->Characteristic = new stdClass;
$params->Characteristic->Name = 'PRODUCT_TYPE';
$params->Characteristic->CharacteristicValue = new stdClass;
$params->Characteristic->CharacteristicValue->Value = $type;
$params->Characteristic->CharacteristicValue->Type = 'STRING';
$client = new SoapClient(NULL, array( 'trace' => true, 'exceptions' => true, 'uri' => $uri, 'location' => $location,
'connection_timeout'=>9999,
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
'soap_version' => SOAP_1_1, 'encoding' => 'ISO-8859-1',
'use' => SOAP_LITERAL
));
$response = $client->thisIsTheFunction($params);
The generated XML is almost right apart from being wrapped in a tag:
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://[removed]">
<soap-env:body>
<ns1:thisisthefunction>
<param0>
<characteristic>
<name>PRODUCT_TYPE</name>
<characteristicvalue>
<value>Adhoc</value>
<type>STRING</type>
</characteristicvalue>
</characteristic>
</param0>
</ns1:thisisthefunction>
</soap-env:body>
</soap-env:envelope>
The problem is this is being detected as malformed by the service. Is there any way we can remove this extra tag?
I think if you want remove param0 and put characteristicValue in this place, you need to use a SoapParam (http://www.php.net/manual/en/class.soapparam.php).
In fact, your call must proceed like that :
$response = $client->thisIsTheFunction(new SoapParam($params->Characteristic, 'ns1:Characteristic'));
Now, your generated XML looks like that :
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://[removed]">
<soap-env:body>
<ns1:thisisthefunction>
<ns1:characteristic>
<name>PRODUCT_TYPE</name>
<characteristicvalue>
<value>Adhoc</value>
<type>STRING</type>
</characteristicvalue>
</ns1:characteristic>
</ns1:thisisthefunction>
</soap-env:body>
Good luck !

Categories