RE: [SOAP] Type translation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At 16:24 28/08/2003, LIMBOURG Arnaud wrote:
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


[Index of Archives]     [PHP Home]     [PHP Users]     [Kernel Newbies]     [PHP Database]     [Yosemite]

  Powered by Linux