[PHP] SOAP Arrays

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Communicon
  • Registratie: December 2012
  • Laatst online: 25-12-2024
Op dit moment werk ik aan een koppeling tussen een webshop en een leverancier doormiddels van SOAP WSDL

Ik kan een order plaatsen maar helaas lukt het niet om artikelen mee te geven in de bestelling.

WSDL

code:
1
2
3
4
5
6
7
8
9
<operation name="SaveOrder">
<soap:operation soapAction="SaveOrder" style="rpc"/>
<input>
<soap:body use="encoded" namespace="urn:Webshop" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" namespace="urn:Webshop" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>


code:
1
2
3
4
5
<operation name="SaveOrder">
<documentation>Save an order</documentation>
<input message="tns:SaveOrderRequest"/>
<output message="tns:SaveOrderResponse"/>
</operation>


code:
1
2
3
4
5
6
7
8
9
10
11
<message name="SaveOrderRequest">
<part name="Username" type="xsd:string"/>
<part name="Password" type="xsd:string"/>
<part name="OrderReference" type="xsd:string"/>
<part name="Customer" type="tns:Customer"/>
<part name="OrderItems" type="tns:OrderItems"/>
<part name="OrderDeliver" type="tns:OrderDeliver"/>
<part name="shop_order_id" type="xsd:string"/>
<part name="IsPayed" type="xsd:boolean"/>
<part name="ShipToCustomer" type="xsd:boolean"/>
</message>



Op dit moment lukt het niet om de OrderItems mee te geven, daar het een array is

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<xsd:complexType name="OrderItems">
<xsd:complexContent>
<xsd:restriction base="SOAP-ENC:Array">
<xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:OrderItem[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>

///

<xsd:complexType name="OrderItem">
<xsd:all>
<xsd:element name="VariantArticleID" type="xsd:string"/>
<xsd:element name="Quantity" type="xsd:string"/>
<xsd:element name="Description" type="xsd:string"/>
<xsd:element name="UnitPrice" type="xsd:string"/>
</xsd:all>
</xsd:complexType>


Ik gebruik wsdl2php om lokaal de objecten en classes beschikbaar te krijgen lokaal beschikbaar gemaakt.

code:
1
2
//Execute Order!
echo $connection->SaveOrder('user','password','Order Red',$klant,$orders,$leveradr,'12','TRUE','TRUE');



Ik weet gewoon niet of ik voor dit stukje <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:OrderItem[]"/> een array in array moet stoppen of object in array.

Acties:
  • 0 Henk 'm!

Anoniem: 241683

Omdat het type 'OrderItems' een eigen gemaakt type is kan PHP dit lang niet altijd goed converteren. Dit zul je dus zelf moeten doen. Dit kan je doen doormiddel van soapvar en soapparam. De documentatie op php.net is op dit punt goed te volgen en er staan een paar goede voorbeelden bij.

Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 06-07 10:04

chem

Reist de wereld rond

Kijk in soapui eens wat de structuur is bij de mockup service; dat geeft vaak wel een hint.

Mijn gok:
PHP:
1
2
3
4
5
6
7
8
$orders = new stdClass;
$orders->OrderItem = array();
$orderitem = new stdClass;
$orderitem->VariantArticleID = "1";
$orderitem->Quantity = "1";
$orderitem->Description = "foo";
$orderitem->UnitPrice = "1";
$orders->OrderItem[] = $orderitem;


Tip voor binnenkomende soap-arrays; als php maar 1 item ziet dan maakt php daar geen array voor aan!

[ Voor 12% gewijzigd door chem op 29-12-2012 15:46 ]

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

chem:
Tip voor binnenkomende soap-arrays; als php maar 1 item ziet dan maakt php daar geen array voor aan!
Is inderdaad een belangrijke tip. Gebruik om dit te voorkomen de SOAP_SINGLE_ELEMENT_ARRAYS flag.

De makkelijkste manier om te debuggen hoe je messages geserialized worden is gebruik te maken van de __getLastRequest() en __getLastResponse() calls. Haal ze door DOMDocument::saveXml() om te formatten en je bent er binnen no time achter waar het probleem zit. In een dev-environment is het wel handig om calls sowieso te loggen, en in andere omgeving de kritieke calls, zodat je goed inzicht hebt in wat er precies heen-en-weer gestuurd wordt. (Zorg wel voor goeie log rotation, kan namelijk aardig uit de klauwen lopen ;))

Het is voor de soap library overigens om het even of je echt objecten of arrays gebruikt. Voor het uitproberen / testen van calls in test scriptjes gebruik ik liever arrays omdat die veel makkelijker op te bouwen zijn. I.c.m. bovenstaande logging kom je er dan veel sneller achter wat de service exact verwacht.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Communicon
  • Registratie: December 2012
  • Laatst online: 25-12-2024
Dank alvast,

PHP Catchable fatal error: Argument 5 passed to Webshop::SaveOrder() must be an instance of OrderItems, instance of stdClass given, called in

echter vind ik heel de class OrderItems niet gedefinieerd in de wsdl file

Heb dus

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class OrderItems {
}

// Maak OrderItem
$orders = new OrderItems();
$orders->OrderItem = array();

//Vars
$orderitem = new OrderItem();
$orderitem->VariantArticleID = "5072302914960";
$orderitem->Quantity = "5";
$orderitem->Description = "testartikel";
$orderitem->UnitPrice = "20.00";

$orders->OrderItem[] = $orderitem;


output =

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Arrayobject(OrderItems)#3 (1) {
  ["OrderItem"]=>
  array(1) {
    [0]=>
    object(OrderItem)#4 (4) {
      ["VariantArticleID"]=>
      string(13) "5072302914960"
      ["Quantity"]=>
      string(1) "5"
      ["Description"]=>
      string(32) "testartikel"
      ["UnitPrice"]=>
      string(5) "20.00"
    }
  }
}


Heb ook de optie 'features' => SOAP_SINGLE_ELEMENT_ARRAYS aangezet!

[ Voor 83% gewijzigd door Communicon op 29-12-2012 20:13 . Reden: Meer input ]


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 06-07 10:04

chem

Reist de wereld rond

De functie SaveOrder is blijkbaar door je code-generator (wsdl2php) in elkaar gezet. Die zal dan ook wel de OrderItems class hebben aangemaakt - 'ergens'.

Dit is dus geen soap-melding maar een melding van php dat je functie signature afwijkt van wat je er heenstuurt: http://php.net/manual/en/language.oop5.typehinting.php

Klaar voor een nieuwe uitdaging.


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Ik heb ook wel eens naar die wsdl2php gekeken, maar vond dat het me meer in de weg zat dan dat het me echt iets opleverde. Dat lijkt bij jou ook het geval te zijn ;) Probeer het eens zonder die gegenereerde code voor elkaar te krijgen.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Communicon
  • Registratie: December 2012
  • Laatst online: 25-12-2024
Wellicht dat dit het e.e.a. duidelijk maakt?


[php]
class Webshop extends SoapClient {

private static $classmap = array(
'Customer' => 'Customer',
'OrderDeliver' => 'OrderDeliver',
'OrderItem' => 'OrderItem',
'ArticleItem' => 'ArticleItem',
'ArticleItemStoreStock' => 'ArticleItemStoreStock',
'ArticleItemStock' => 'ArticleItemStock',
);

public function Webshop($wsdl = "https://www.example.com/webservices?wsdl", $options = array('features' => SOAP_SINGLE_ELEMENT_ARRAYS)) {
foreach(self::$classmap as $key => $value) {
if(!isset($options['classmap'][$key])) {
$options['classmap'][$key] = $value;
}
}
parent::__construct($wsdl, $options);
}

[php]

PHP:
1
2
3
4
5
6
7
  public function SaveOrder($Username, $Password, $OrderReference, Customer $Customer, OrderItems $OrderItems, OrderDeliver $OrderDeliver, $shop_order_id, $IsPayed, $ShipToCustomer) {
    return $this->__soapCall('SaveOrder', array($Username, $Password, $OrderReference, $Customer, $OrderItems, $OrderDeliver, $shop_order_id, $IsPayed, $ShipToCustomer),       array(
            'uri' => 'urn:Webshop',
            'soapaction' => ''
           )
      );
  }


PHP:
1
2
3
4
5
6
7
  public function GetStockIndication($Username, $Password, $SupplierCheck, ArticleItems $ArticleItems) {
    return $this->__soapCall('GetStockIndication', array($Username, $Password, $SupplierCheck, $ArticleItems),       array(
            'uri' => 'urn:Webshop',
            'soapaction' => ''
           )
      );
  }

[ Voor 36% gewijzigd door Communicon op 30-12-2012 17:00 ]


Acties:
  • 0 Henk 'm!

  • Down
  • Registratie: Februari 2005
  • Laatst online: 12-07 09:03
offtopic:
Je werkt bij Kega toevallig?

Mother north, how can they sleep while their beds are burning?


Acties:
  • 0 Henk 'm!

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 06-07 10:04

chem

Reist de wereld rond

Communicon schreef op zondag 30 december 2012 @ 16:56:
Wellicht dat dit het e.e.a. duidelijk maakt?
Eerlijk gezegd maakt het vooral duidelijk dat je niet leest wat er geschreven wordt.

De functie verwacht een object van de class 'OrderItems'. Zoek op of wsdl2php die gemaakt heeft; zo niet, definieer hem zelf.

Vervolgens moet je een instantie van die class meegeven als parameter; of je dat goed doet is een kwestie van debuggen. Check welke parameters je stuurt - je doet het blijkbaar verkeerd :)

Klaar voor een nieuwe uitdaging.

Pagina: 1