This post is pretty much a revamp of a previous post called “Working with X-Fire soap services and inheritance in PHP“. That title was a bit misleading, and not really that good when it came to providing a sample.
Let’s say we have a SOAP method called createCustomer(Customer c), and we have a base class called Customer, which has to subclasses, Person and Organization. Person has firstname, lastname, while Organization as orgname and orgid. Now, the createCustomer call accepts a object of the class Customer, and any derived classes.
When retrieving a Person / Organization over SOAP, PHP automatically creates instances of the correct classes, but when calling createCustomer, passing a Person / Organization it breaks. Out object is sent as a Customer, but with Person or Organization fields added. The SOAP server expects to find a xsi:type for the object we are sending to tell what kind of Customer it is. It seems like PHP does not set this itself (maybe it should?).
I spent quite some time looking for info on how to specify the xsi:type for the objects, and I finally came across SoapVar.
I created a base class which the SOAP classes extended. A method called pack is responsible for setting xsi:type.
(I’m very aware that my pasted code looks like a mess in this blog. I will fix that ASAP).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class BaseClass{ private $namespace = "http://model.api.domain.com"; // from your WSDL protected function pack($obj){ $class_name = get_class($obj); $namespace = "http://model.api.domain.com"; $pack = new SoapVar($obj, XSD_STRING, "$class_name", $namespace); return $pack; } } class createCustomer extends BaseClass{ public function setCustomer($customer){ $this->customer = $this->pack($customer); } } $customer = new Person(); $customer->setName("John Doe"); $request = new createCustomer(); $request->setAccountID(123); $request->setCustomer($customer); $client->createCustomer($request); |
That fixed the problems for me atleast.
PS: If your SOAP classes are prefixed you’ll need to strip the prefix in class_name when creating the SoapVar.
Related posts:
[tags]PHP, SOAP[/tags]