How to create PHP SoapParam from SoapParams?

I use SoapClient to interact with http://weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php?wsdl and calling NDFDgenByDay () works fine, no problem, but when I want to call NDFDgen (), I have to use curl instead of this, because I can’t understand how to pass WeatherParameters to NDFDgen () when using SoapClient. Here is what I tried:

... $this->client = new SoapClient( 'http://weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php?wsdl', array('cache_wsdl'=>WSDL_CACHE_NONE) ); ... $this->xml = $this->client->NDFDgen( new SoapParam($this->latitude, 'latitude'), new SoapParam($this->longitude,'longitude'), new SoapParam('time-series', 'product'), new SoapParam($startTime, 'startTime'), new SoapParam($endTime, 'startTime'), new SoapParam('e', 'Unit'), new SoapParam( array( new SoapParam(false,'maxt'), new SoapParam(false,'mint'), new SoapParam(true, 'temp'), new SoapParam(true, 'dew'), new SoapParam(true, 'pop12'), new SoapParam(true, 'qpf'), new SoapParam(true, 'sky'), new SoapParam(true, 'snow'), new SoapParam(true, 'wspd'), new SoapParam(true, 'wdir'), //10 new SoapParam(false,'wx'), new SoapParam(false,'waveh'), new SoapParam(true, 'icons'), new SoapParam(true, 'rh'), new SoapParam(true, 'appt'), new SoapParam(false,'incw34'), new SoapParam(false,'incw50'), new SoapParam(false,'incw64'), new SoapParam(false,'cumw34'), new SoapParam(false,'cumw50'), //20 new SoapParam(false,'cumw64'), new SoapParam(false,'critfireo'), new SoapParam(false,'dryfireo'), new SoapParam(false,'conhazo'), new SoapParam(false,'ptornado'), new SoapParam(false,'phail'), new SoapParam(false,'ptstmwinds'), new SoapParam(false,'pxtornado'), new SoapParam(false,'pxhail'), new SoapParam(false,'pxtstmwinds'), //30 new SoapParam(false,'ptotsvrtstm'), new SoapParam(false,'pxtotsvrtstm'), new SoapParam(false,'tmpabv14d'), new SoapParam(false,'tmpblw14d'), new SoapParam(false,'tmpabv30d'), new SoapParam(false,'tmpblw30d'), new SoapParam(false,'tmpabv90d'), new SoapParam(false,'tmpblw90d'), new SoapParam(false,'prcpabv14d'), new SoapParam(false,'prcpblw14d'), //40 new SoapParam(false,'prcpabv30d'), new SoapParam(false,'prcpblw30d'), new SoapParam(false,'prcpabv90d'), new SoapParam(false,'prcpblw90d'), new SoapParam(true, 'precipa_r'), new SoapParam(true, 'sky_r'), new SoapParam(true, 'temp_r'), new SoapParam(true, 'td_r'), new SoapParam(true, 'wdir_r'), new SoapParam(true, 'wspd_r'), //50 new SoapParam(true, 'wwa'), new SoapParam(true, 'wgust') ), 'weatherParameters' ) ); 

The error I am getting is:

 Fatal error: Uncaught SoapFault exception: [Client] SOAP-ERROR: Encoding: object has no 'maxt' property in [Redacted]\data\WeatherService.php:199 

Here is the xml that works through curl:

 <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ndf="http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl"> <soapenv:Header/> <soapenv:Body> <ndf:NDFDgen soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <latitude xsi:type="xsd:decimal">{$this->latitude}</latitude> <longitude xsi:type="xsd:decimal">{$this->longitude}</longitude> <product xsi:type="xsd:string">time-series</product> <startTime xsi:type="xsd:dateTime">{$this->startTime}</startTime> <endTime xsi:type="xsd:dateTime">{$this->endTime}</endTime> <Unit xsi:type="xsd:string">e</Unit> <weatherParameters xsi:type="ndf:weatherParametersType"> <!--You may enter the following 52 items in any order--> <maxt xsi:type="xsd:boolean">false</maxt> <mint xsi:type="xsd:boolean">false</mint> <temp xsi:type="xsd:boolean">true</temp> <dew xsi:type="xsd:boolean">true</dew> <pop12 xsi:type="xsd:boolean">true</pop12> <qpf xsi:type="xsd:boolean">true</qpf> <sky xsi:type="xsd:boolean">true</sky> <snow xsi:type="xsd:boolean">true</snow> <wspd xsi:type="xsd:boolean">true</wspd> <wdir xsi:type="xsd:boolean">true</wdir> <wx xsi:type="xsd:boolean">false</wx> <waveh xsi:type="xsd:boolean">false</waveh> <icons xsi:type="xsd:boolean">true</icons> <rh xsi:type="xsd:boolean">true</rh> <appt xsi:type="xsd:boolean">true</appt> <incw34 xsi:type="xsd:boolean">false</incw34> <incw50 xsi:type="xsd:boolean">false</incw50> <incw64 xsi:type="xsd:boolean">false</incw64> <cumw34 xsi:type="xsd:boolean">false</cumw34> <cumw50 xsi:type="xsd:boolean">false</cumw50> <cumw64 xsi:type="xsd:boolean">false</cumw64> <critfireo xsi:type="xsd:boolean">false</critfireo> <dryfireo xsi:type="xsd:boolean">false</dryfireo> <conhazo xsi:type="xsd:boolean">false</conhazo> <ptornado xsi:type="xsd:boolean">false</ptornado> <phail xsi:type="xsd:boolean">false</phail> <ptstmwinds xsi:type="xsd:boolean">false</ptstmwinds> <pxtornado xsi:type="xsd:boolean">false</pxtornado> <pxhail xsi:type="xsd:boolean">false</pxhail> <pxtstmwinds xsi:type="xsd:boolean">false</pxtstmwinds> <ptotsvrtstm xsi:type="xsd:boolean">false</ptotsvrtstm> <pxtotsvrtstm xsi:type="xsd:boolean">false</pxtotsvrtstm> <tmpabv14d xsi:type="xsd:boolean">false</tmpabv14d> <tmpblw14d xsi:type="xsd:boolean">false</tmpblw14d> <tmpabv30d xsi:type="xsd:boolean">false</tmpabv30d> <tmpblw30d xsi:type="xsd:boolean">false</tmpblw30d> <tmpabv90d xsi:type="xsd:boolean">false</tmpabv90d> <tmpblw90d xsi:type="xsd:boolean">false</tmpblw90d> <prcpabv14d xsi:type="xsd:boolean">false</prcpabv14d> <prcpblw14d xsi:type="xsd:boolean">false</prcpblw14d> <prcpabv30d xsi:type="xsd:boolean">false</prcpabv30d> <prcpblw30d xsi:type="xsd:boolean">false</prcpblw30d> <prcpabv90d xsi:type="xsd:boolean">false</prcpabv90d> <prcpblw90d xsi:type="xsd:boolean">false</prcpblw90d> <precipa_r xsi:type="xsd:boolean">true</precipa_r> <sky_r xsi:type="xsd:boolean">true</sky_r> <temp_r xsi:type="xsd:boolean">true</temp_r> <td_r xsi:type="xsd:boolean">true</td_r> <wdir_r xsi:type="xsd:boolean">true</wdir_r> <wspd_r xsi:type="xsd:boolean">true</wspd_r> <wwa xsi:type="xsd:boolean">true</wwa> <wgust xsi:type="xsd:boolean">true</wgust> </weatherParameters> </ndf:NDFDgen> </soapenv:Body> </soapenv:Envelope> 

Basically, I would like to use SoapClient for all Soap interactions, but I don’t know how to perform complex parameters, such as the weatherParameters parameter above, if weatherParameters can be specified when using SoapClient, please show me how, because the alternative using curl , literally adds over 100 extra lines of code to my php, between creating a soap wrapper and initializing and using curl, and then parsing the xml response from the response wrapper.

+4
source share
1 answer

OK, I found a solution.

This part of the request:

 ... <weatherParameters xsi:type="ndf:weatherParametersType"> <!--You may enter the following 52 items in any order--> <maxt xsi:type="xsd:boolean">false</maxt> <mint xsi:type="xsd:boolean">false</mint> <temp xsi:type="xsd:boolean">true</temp> <dew xsi:type="xsd:boolean">true</dew> <pop12 xsi:type="xsd:boolean">true</pop12> <qpf xsi:type="xsd:boolean">true</qpf> <sky xsi:type="xsd:boolean">true</sky> <snow xsi:type="xsd:boolean">true</snow> <wspd xsi:type="xsd:boolean">true</wspd> <wdir xsi:type="xsd:boolean">true</wdir> <wx xsi:type="xsd:boolean">false</wx> <waveh xsi:type="xsd:boolean">false</waveh> <icons xsi:type="xsd:boolean">true</icons> <rh xsi:type="xsd:boolean">true</rh> <appt xsi:type="xsd:boolean">true</appt> <incw34 xsi:type="xsd:boolean">false</incw34> <incw50 xsi:type="xsd:boolean">false</incw50> <incw64 xsi:type="xsd:boolean">false</incw64> <cumw34 xsi:type="xsd:boolean">false</cumw34> <cumw50 xsi:type="xsd:boolean">false</cumw50> <cumw64 xsi:type="xsd:boolean">false</cumw64> <critfireo xsi:type="xsd:boolean">false</critfireo> <dryfireo xsi:type="xsd:boolean">false</dryfireo> <conhazo xsi:type="xsd:boolean">false</conhazo> <ptornado xsi:type="xsd:boolean">false</ptornado> <phail xsi:type="xsd:boolean">false</phail> <ptstmwinds xsi:type="xsd:boolean">false</ptstmwinds> <pxtornado xsi:type="xsd:boolean">false</pxtornado> <pxhail xsi:type="xsd:boolean">false</pxhail> <pxtstmwinds xsi:type="xsd:boolean">false</pxtstmwinds> <ptotsvrtstm xsi:type="xsd:boolean">false</ptotsvrtstm> <pxtotsvrtstm xsi:type="xsd:boolean">false</pxtotsvrtstm> <tmpabv14d xsi:type="xsd:boolean">false</tmpabv14d> <tmpblw14d xsi:type="xsd:boolean">false</tmpblw14d> <tmpabv30d xsi:type="xsd:boolean">false</tmpabv30d> <tmpblw30d xsi:type="xsd:boolean">false</tmpblw30d> <tmpabv90d xsi:type="xsd:boolean">false</tmpabv90d> <tmpblw90d xsi:type="xsd:boolean">false</tmpblw90d> <prcpabv14d xsi:type="xsd:boolean">false</prcpabv14d> <prcpblw14d xsi:type="xsd:boolean">false</prcpblw14d> <prcpabv30d xsi:type="xsd:boolean">false</prcpabv30d> <prcpblw30d xsi:type="xsd:boolean">false</prcpblw30d> <prcpabv90d xsi:type="xsd:boolean">false</prcpabv90d> <prcpblw90d xsi:type="xsd:boolean">false</prcpblw90d> <precipa_r xsi:type="xsd:boolean">true</precipa_r> <sky_r xsi:type="xsd:boolean">true</sky_r> <temp_r xsi:type="xsd:boolean">true</temp_r> <td_r xsi:type="xsd:boolean">true</td_r> <wdir_r xsi:type="xsd:boolean">true</wdir_r> <wspd_r xsi:type="xsd:boolean">true</wspd_r> <wwa xsi:type="xsd:boolean">true</wwa> <wgust xsi:type="xsd:boolean">true</wgust> </weatherParameters> ... 

Must be converted to an object (Struct):

 class weatherParameters { function weatherParameters() { $this->maxt = false; $this->mint = false; $this->temp = true; $this->dew = true; $this->pop12 = true; $this->qpf = true; $this->sky = true; $this->snow = true; $this->wspd = true; $this->wdir = true; $this->wx = false; $this->waveh = false; $this->icons = true; $this->rh = true; $this->appt = true; $this->incw34 = false; $this->incw50 = false; $this->incw64 = false; $this->cumw34 = false; $this->cumw50 = false; $this->cumw64 = false; $this->critfireo = false; $this->dryfireo = false; $this->conhazo = false; $this->ptornado = false; $this->phail = false; $this->ptstmwinds = false; $this->pxtornado = false; $this->pxhail = false; $this->pxtstmwinds = false; $this->ptotsvrtstm = false; $this->pxtotsvrtstm= false; $this->tmpabv14d = false; $this->tmpblw14d = false; $this->tmpabv30d = false; $this->tmpblw30d = false; $this->tmpabv90d = false; $this->tmpblw90d = false; $this->prcpabv14d = false; $this->prcpblw14d = false; $this->prcpabv30d = false; $this->prcpblw30d = false; $this->prcpabv90d = false; $this->prcpblw90d = false; $this->precipa_r = true; $this->sky_r = true; $this->temp_r = true; $this->td_r = true; $this->wdir_r = true; $this->wspd_r = true; $this->wwa = true; $this->wgust = true; } } 

I hard coded the values, but you can make the values ​​dynamic if necessary. Then I instantiate the structure:

 $wParameters = new weatherParameters(); 

Then I tell SoapClient how to convert this object to an XML fragment:

 $weatherParameters = new SoapVar( // object to convert,encoding,name to give the object, name space definition $wParameters, SOAP_ENC_OBJECT, 'weatherParameters', 'http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl' ); 

Then you pass SoapVar to the function call as SoapParam:

 $this->xml = $this->client->NDFDgen( new SoapParam($this->latitude, 'latitude'), new SoapParam($this->longitude,'longitude'), new SoapParam('time-series', 'product'), new SoapParam($startTime, 'startTime'), new SoapParam($endTime, 'startTime'), new SoapParam('e', 'Unit'), new SoapParam($weatherParameters,'weatherParameters') ); 

So, to understand this, I had to read all the PHP Soap documentation ... and then when I got into the documentation on SoapVar http://php.net/manual/en/class.soapvar.php , an example in SoapVar showed how it is used with SoapParam, in my opinion, the examples in SoapParam http://php.net/manual/en/soapparam.soapparam.php should also better show the connection between SoapVar and SoapParam, otherwise you may not understand what you need SoapVar to create sophisticated SoapParam. There are 7 references / references to SoapVar in the SoapParam doc, but none of them indicate that argument 1 of SoapParam will be an instance of SoapVar when you need SoapParam to represent a complex object.

+6
source

Source: https://habr.com/ru/post/1437809/


All Articles