Help with nusoap and array

Hello, I am trying to consume a web service using nusoap. I am having trouble getting it to work… Here is my code…

<?php

	require_once('lib/nusoap.php');
	$time = strtotime( $date );
	$myDate = date( 'y-m-d', $time );

	
			
	$request = array('request' => array(
						'CustomerId' => '967636',
						'QuoteType' => 'B2B',
						'ServiceType' => 'LTL',
						'QuoteShipment' => array(
										'ShipmentLabel' => 'test b2b',
										'IsBlind' => 'False',
										'HazardousMaterialContactName' => 'Tyler h',
										'HazardousMaterialContactPhone' => '9139999999',
										'PickupDate' => '2010-11-28T16:00:00.000Z',
										'ShipmentLocations' => array(
											'Location' => array(
												'LocationType' => 'Origin',
												'LocationType' => 'Origin',
													'LocationAddress' => array (
														'PostalCode' => '66209',
														'CountryCode' => 'US')
														),
											'Location' => array(
												'LocationType' => 'Destination',
												'LocationType' => 'Destination',
													'LocationAddress' => array (
														'PostalCode' => '66209',
														'CountryCode' => 'US')
											)),
										'ShipmentProducts' => array(
											'Product' => array(
												'PackageType' => 'Pallets_48x40',
												'Weight' => '200',
												'Length' => '20',
												'Width' => '20',
												'Height' => '20',
												'CommodityType' => 'GeneralMerchandise',
												'ContentType'  => 'NewCommercialGoods',
												'IsHazardousMaterial'  => 'False',
												'PieceCount'  => '1')
												))),
										'user' => array(
										'Name' => 'xmltest@freightquote.com',
										'Password' => 'xml'));
				print_r($request);								
	$soapClient = new nusoap_client("http://b2b.freightquote.com/WebService/QuoteService.asmx?WSDL", $request);
	$result = $soapClient->call("GetRatingEngineQuote", $request);
	print_r($result);
 
?>

and here is what it returns…

Array
(
    [request] => Array
        (
            [CustomerId] => 967636
            [QuoteType] => B2B
            [ServiceType] => LTL
            [QuoteShipment] => Array
                (
                    [ShipmentLabel] => test b2b
                    [IsBlind] => False
                    [HazardousMaterialContactName] => Tyler h
                    [HazardousMaterialContactPhone] => 9139999999
                    [PickupDate] => 2010-11-28T16:00:00.000Z
                    [ShipmentLocations] => Array
                        (
                            [Location] => Array
                                (
                                    [LocationType] => Destination
                                    [LocationAddress] => Array
                                        (
                                            [PostalCode] => 66209
                                            [CountryCode] => US
                                        )

                                )

                        )

                    [ShipmentProducts] => Array
                        (
                            [Product] => Array
                                (
                                    [PackageType] => Pallets_48x40
                                    [Weight] => 200
                                    [Length] => 20
                                    [Width] => 20
                                    [Height] => 20
                                    [CommodityType] => GeneralMerchandise
                                    [ContentType] => NewCommercialGoods
                                    [IsHazardousMaterial] => False
                                    [PieceCount] => 1
                                )

                        )

                )

        )

    [user] => Array
        (
            [Name] => xmltest@freightquote.com
            [Password] => xml
        )

)
Array
(
    [GetRatingEngineQuoteResult] => Array
        (
            [QuoteId] => 0
            [QuoteDateTime] => 2010-01-19T10:15:51.4305286-06:00
            [QuoteExpiration] => 2010-02-18T10:15:51.4305286-06:00
            [QuoteDurationMilliseconds] => 0
            [UnitOfMeasureType] => English
            [QuoteCarrierOptions] => 
            [ValidationErrors] => Array
                (
                    [B2BError] => Array
                        (
                            [ErrorType] => Validation
                            [ErrorMessage] => First Location in list must be origin.
                        )

                )

        )

)

Don’t use nusoap. PHP has a native soap client now: http://www.php.net/manual/en/class.soapclient.php

it still does not work. Its total removing the first node of ‘Location’ - If the node names are duplicates soap skips them… anyway around this?

you’re using the same array key twice in the same array(Location), which you cannot do. This is a limitation of php arrays, not soap.


                                        'ShipmentLocations' => array(
                                            'Location' => array(...),
                                            'Location' => array(... )
                                        ),

Ok, so how can i change the key? or get it to work?

here is the wsdl

http://b2b.freightquote.com/WebService/QuoteService.asmx?WSDL

Sorry, I’ve never used soap.

If I were to guess


'Location' => array(
    array(...),
    array(...)
)

I don’t remember the details, but I think you have to create a SoapVar object to wrap the data, and then wrap this with a SoapParam. The manual is pretty sparse with information, and I don’t really remember the details (Haven’t used php’s soapclient much anyway), but try googling for php+SoapParam

thanks, will try…

ok, i cannot figure this out and I REALLY need to. Does anyone know an ideas???

Yes, try contacting the NuSOAP support forum where the people there live and breathe that technology.

You can create php classes that SoapClient will then map to the soap request data. You can alternatively use SoapParam, but I don’t remember the syntax. Your example is incomplete, which will lead to validation errors. Try this:


class Location {
  function __construct($properties = array()) {
    foreach ($properties as $key => $value) {
      $this->$key = $value;
    }
  }
}

class LocationAddress {
  function __construct($properties = array()) {
    foreach ($properties as $key => $value) {
      $this->$key = $value;
    }
  }
}

class Product {
  function __construct($properties = array()) {
    foreach ($properties as $key => $value) {
      $this->$key = $value;
    }
  }
}

$request = array(
  'request' => array(
    'CustomerId' => '967636',
    'QuoteType' => 'B2B',
    'ServiceType' => 'LTL',
    'QuoteShipment' => array(
      'ShipmentLabel' => 'test b2b',
      'IsBlind' => 'False',
      'HazardousMaterialContactName' => 'Tyler h',
      'HazardousMaterialContactPhone' => '9139999999',
      'PickupDate' => '2010-11-28T16:00:00.000Z',
      'ShipmentLocations' => array(
        new Location(
          array(
            'LocationName' => 'Origin',
            'LocationType' => 'Origin',
            'RequiresArrivalNotification' => false,
            'HasLoadingDock' => false,
            'IsConstructionSite' => false,
            'RequiresInsideDelivery' => false,
            'IsTradeShow' => false,
            'IsResidential' => false,
            'RequiresLiftgate' => false,
            'NotificationMethod' => 'None',
            'LocationAddress' => new LocationAddress(
              array(
                'PostalCode' => '66209',
                'CountryCode' => 'US')))
        ),
        new Location(
          array(
            'LocationName' => 'Destination',
            'LocationType' => 'Destination',
            'RequiresArrivalNotification' => false,
            'HasLoadingDock' => false,
            'IsConstructionSite' => false,
            'RequiresInsideDelivery' => false,
            'IsTradeShow' => false,
            'IsResidential' => false,
            'RequiresLiftgate' => false,
            'NotificationMethod' => 'None',
            'LocationAddress' => new LocationAddress(
              array(
                'PostalCode' => '66209',
                'CountryCode' => 'US')))
        ),
      ),
      'ShipmentProducts' => array(
        new Product(
          array(
            'PackageType' => 'Pallets_48x40',
            'Weight' => '200',
            'Length' => '20',
            'Width' => '20',
            'Height' => '20',
            'DimWeight' => '200',
            'EstimatedWeight' => '200',
            'ItemNumber' => '1',
            'CommodityType' => 'GeneralMerchandise',
            'ContentType'  => 'NewCommercialGoods',
            'IsStackable'  => false,
            'DeclaredValue'  => '1',
            'IsHazardousMaterial'  => false,
            'PieceCount'  => '1')
        )
      ))),
  'user' => array(
    'Name' => 'xmltest@freightquote.com',
    'Password' => 'xml'));

$wsdl_url = 'http://b2b.freightquote.com/WebService/QuoteService.asmx?WSDL';
$client = new SoapClient($wsdl_url, array('trace' => 1));
$response = $client->GetRatingEngineQuote($request);
echo "REQUEST:\
" . $client->__getLastRequest() . "\
";
var_dump($response);

I can recommend that you use soapUI (A free application) on the side, when trying to use SOAP. It can interpret a WSDL and generate sample xml requests. You can then compare this to your own request xml and see what’s missing. You may still have to read the WSDL manually (I had to look for NotificationMethodList to find the allowed values).

All considered, SOAP is a hideous protocol, but if that’s what you must use, good luck.