In PHP you have several ways of sending binary data. It can be primarily categorized in to non-optimized method (send as base64 binary) and optimized method (send as MTOM or SWA). Here I m talking about how to send binaries in above mentioned methods starting from a WSDL.
WSDL
Think you have a WSDL with the following XML Schema.
<!-- Here is my submitPerson method-> <xs:element name="submitPerson"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="age" type="xs:int"/> <xs:element name="photo" type="xs:base64Binary"/> </xs:sequence> </xs:complexType> </xs:element>
The submit Person method submit the name,age and a photo which is a type of base64Binary.
Generated Class
After generating php class for this piece of code using wsdl2php you will have the following class.
class submitPerson { /** * @var string */ public $name; /** * @var int */ public $age; // You need to set only one from the following two vars /** * @var Plain Binary */ public $photo; /** * @var base64Binary */ public $photo_encoded; }
So it is very easy to fill the class with your own data. Note that you only need to fill one of the ‘photo’ or ‘photo_encoded’ fields. If you have binary already converted to base64 then you can use the ‘photo_encoded’ field where as if you only have the row binary just use the ‘photo’ field. Here are my values for this particular example.
$person = new submitPerson(); $person->name = "xxxx yyy"; $person->age = 35; $person->photo = file_get_contents("/photo/xxxyyy");
Sending Binary as MTOM
Here is the code you need to send the above structure as a MTOM message.
$client = new WSClient(array("useMTOM" => TRUE)); // anyway useMTOM is default to TRUE for WSClient $proxy = $client->getProxy(); $response = $proxy->submitPerson($person);
Sending Binary as Base64 Encoded string
You only need to change one option. That is setting “useMTOM” to FALSE will send the binary as Base64.
$client = new WSClient(array("useMTOM" => FALSE)); $proxy = $client->getProxy(); $response = $proxy->submitPerson($person);
SWA (SOAP With Attachments)
You can send the binary data as SWA by setting the “useMTOM” option to “SWA”. SWA is also a binary optimized method of sending attachments, but unlike with MTOM you can’t integrate security or reliability with this approach.
My service is currently returning an array of base64binary images along with other data. However, I also need to put the original filenames of those base64binary attachments in the response so that they can be saved with the same name. I had originally thought I could just add a new public variable $fileName to the base64binary class in the client and server, but since that is a type referenced in the XSD, I don’t think that’s the right way to do it.
I know in the above I could add the filename to the submitPerson object, but I’m not sure how to do it if the object is returning an array of images instead, each of which needs to carry it’s original filename. Please let me know if anyone has any ideas.
Here’s what’s in my wsdl:
and here’s the class definition in the service and client:
class getArticleResponse {
/**
* @var string
*/
public $title;
/**
* @var string
*/
public $subheader;
/**
* @var string
*/
public $bodytext;
/**
* @var (object)base64Binary
*/
public $responseImage;
}
class base64Binary {
/**
* @var string
* NOTE: contentType should follow the following restrictions
* Your length of the value should be
* Greater than 3
*/
public $contentType;
// The “value” represents the element ‘responseImage’ value..
// You need to set only one from the following two vars
/**
* @var Plain Binary
*/
public $value;
/**
* @var base64Binary
*/
public $value_encoded;
}
It seems to have stripped out the wsdl code I copied, so here it is again – this time htmlencoded to see if it helps.
<xsd:complexType><xsd:sequence><xsd:element name="title" type="xsd:string"/><xsd:element name="subheader" type="xsd:string"/><xsd:element name="bodytext" type="xsd:string"/><xsd:element name="responseImage" maxOccurs="unbounded" minOccurs="1" type="xmime:base64Binary"></xsd:element></xsd:sequence></xsd:complexType>
You can’t add a element to the Base64Binary class as it is a simple type extension. What you can do is add an element “filename” to getArticleResponse which is a complex type. This can be done by adding <xsd:element name=”filename” type=”xsd:string”/> to the xsd:sequence you have shown here.
Thanks
Dimuthu