Chris coe will probably be able to say more about this.
Arnaud.
Chris Coe is on vacation :P But, I'll do my best :-)
> > can somebody please explain in few words how XML - PHP type > translation > > feature works (or is supposed to work)? I mean, the > $_auto_translation, > > $_type_translation and __set_type_translation() stuff in SOAP_Base.
I looked at this code recently, and though Shane or Dietrich might know better, it looks to me like it is a partially incomplete feature. I think, the basic idea is that as a server or client, you call:
$SrvOrCli->__set_type_translation($type, [$classname]);
where $type is a type used in your SOAP messages, in the form: 'nsprefix:mytypename' or '{fullnamespace}mytypename', or unqualified as 'mytypename', and $class is a PHP class to which to map the type. If you don't supply $classname, then 'mytypename' (unqualified) will be used as the target class name instead.
Call the above function before you start exchanging SOAP messages to set up how you want your SOAP types to map to classes. Obviously, you will need to call it once per type that you are interested in mapping.
The type translation works on decode (ie. when receiving a SOAP message) only. On receiving a value of type foo in namespace bar, ONE the following will happen in descending order of priority:
- if you set a class name for foo:bar, then that class will be created and populated with value data - if you set a class name for bar, then that class will be created and populated with value data - if auto_translation is on ($SrvOrCli->_auto_translation = true), then if a class has been defined with name bar, then an instance will be created and populated with value data - if auto_translation is on, and WSDL is in use (and/or __dispatch_map and __typedefs have been defined in server objects in 0.8RC1), then the qualified element name will be checked to see if it is the accessor name for a complexType, and if so, and if a class has been defined with the same name as the unqualified part of the type name, then an instance of that class will be created and populated with value data. - if none of the above happens, then an instance of 'stdclass' will be created and populated with value data.
When I say "populated with value data", I mean that the properties in the class instance created (the member variables) will be set to the values determined by accessor elements of the same name that are children of the type element, ie.
<myns:someValue> <a xsd:type="int">4</a> <baz>hello world</baz> </myns:someValue>
with no type translations set and auto translation on, and with a class 'someValue' defined in the code, will cause these actions:
$val =& new someValue; $val->a = 4; $val->baz = 'hello world';
In other words, make sure your classes have all the right 'var' definitions in them. IIRC, a piece of code that attempts to set a non-existent property will cause $val->__set() to be called if the PHP overload extension is enabled, so you can leverage this if you want to give your class properties different names.
When setting the value data, if your SOAP element has attributes in it (other than xmlns:*, xsi:type etc. and the other attributes handled in Parser.php), and you define a function called __set_attribute() in your class, then this will be called for each attribute, to allow you to process them. The signature is:
function __set_attribute(string $key, string $value)
The type_translation feature is not implemented for encoding (sending) messages, ie. you cannot pass one of your classes and have PEAR::SOAP automatically know how to serialise it into a SOAP element; this sort of functionality (or similar) will probably come with the PHP 5 iteration of the library.
In summary:
- for most of us, in most cases, 'stdclass' will be used. - if we define classes with the same names as our type elements, we can just turn _auto_translation on and instances of those classes will be made for us when types of the same name are encountered in incoming SOAP messages. - if we want to use different class names, or we want to turn auto_translation off and specify the class mapping manually, call __set_type_translation. Even with auto_translation on, our __set_type_translation settings take priority, so if we receive an element of type foo, and we have defined classes foo and bar, auto_translation is on and we have used _set_type_translation to map type foo to class bar, then it will be bar which is instantiated and not foo (and bar will be filled with value data for type foo). - define the method __set_attribute in your type classes to enable element attributes to be handled, if you use them.
What's the benefit of all of this? Well, I have never used this feature :-) But one can imagine that it is useful for pre-processing complex data as it is deserialised, for example if you need to change the format of it, or fill in gaps in the supplied data, or cross-reference it etc. Of course, it also lets you provide encapsulated methods for getting data in and out of the type, or performing more complicated queries and edits on it. Ultimately though, if you plan to send it back down the wire, you will still have to provide it to PEAR::SOAP in a suitable structure - you can pass objects to be serialised directly, but PEAR::SOAP expects a straightforward set of properties of which it will serialise all of them, with the exact data they contain (as opposed to doing any conversion processing first).
Remember also, if you are passing objects to PEAR::SOAP for serialisation, that doing this:
$args =& $myObjectInstance; $client->call($method, $args);
will make your object and its contents subject to the 'best guess' type serialisation logic that can cause problems with interop. For best results, always include the type information when you pass your object, like this:
$args =& new SOAP_Value('myValue', '{fullnamespaceuri}mytype', $myObjectInstance);
$client->call($method, $args);
This will make PEAR::SOAP refer to your WSDL or __typedef definitions to help serialise the data correctly.
I hope all that made sense.
Best regards,
Chris.
-- PHP Soap Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php