Quantcast
Channel: Eirik Hoem's Blog » SOAP
Viewing all articles
Browse latest Browse all 6

Setting xsi:type for objects sent over SOAP (inheritance)

$
0
0

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] 


Viewing all articles
Browse latest Browse all 6

Trending Articles