Los componente SCA pueden pasar y devolver los cuatro tipos escalares de PHP boolean, integer, float y string, pero para pasar o devolver estructuras de datos, los componentes SCA usan Objetos de Datos de Servicio (SDOs). Los SDOs están descritos con más detalle en las páginas de SDO de este manual. Los lectores familiarizados con SDOs sabrán que son adecuados para representar el tipo de datos estructurados y semiestructurados que frecuentemente se modelan en XML, y que serializan de forma muy natural para pasarlos entre componentes remotos, o en servicios web. Los SDOs son actualmente la única manera soportada de pasar y devolver estructuras de datos. No es posible pasar o devolver objetos de PHP, o arrays de PHP.
El tiempo de ejecución de SCA siempre se asegura de que los datos sean pasados por valor, incluso para llamadas locales. Para hacer esto, el tiempo de ejecución de SCA copia cualquier SDO de la lista de parámetros antes de pasarlo, al igual que hace con los tipos escalares.
Actualemtne, el único mecanismo para especificar la ubicación de una definición de una estructura de datos, es especificar los tipos en un fichero de esquema XML. Sin embargo, en el futuro podría ser posible definir tipos de otra manera, tal como basadas en clases o interfaces de PHP, o basadas en definiciones expresadas como arrays asociativos.
Para ilustrar el uso de SDOs, se introduce un nuevo componente. El servico PortfolioMangement de abajo devuelve un SDO que representa una cartera de acciones para un cliente dado.
Ejemplo #1 Un componente que usa estructuras de datos
<?php
include "SCA/SCA.php";
/**
* Administrar la cartera para un cliente.
*
* @service
* @binding.soap
*
* @types http://www.example.org/Portfolio PortfolioTypes.xsd
*
*/
class PortfolioManagement {
/**
* Obtener la cartera de acciones para un cliente dado.
*
* @param integer $customer_id El id del cliente
* @return Portfolio http://www.example.org/Portfolio The stock portfolio (symbols and quantities)
*/
function getPortfolio($customer_id) {
// Pretend we just got this from a database
$portfolio = SCA::createDataObject('http://www.example.org/Portfolio', 'Portfolio');
$holding = $portfolio->createDataObject('holding');
$holding->ticker = 'AAPL';
$holding->number = 100.5;
$holding = $portfolio->createDataObject('holding');
$holding->ticker = 'INTL';
$holding->number = 100.5;
$holding = $portfolio->createDataObject('holding');
$holding->ticker = 'IBM';
$holding->number = 100.5;
return $portfolio;
}
}
?>
La anotación @types:
<?php
@types http://www.example.org/Portfolio PortfolioTypes.xsd
?>
indica que los tipos del espacio de nombres http://www.example.org/Portfolio se encontrarán en el fichero de esquema ubicado en la URI URI PortfolioTypes.xsd. El WSDL generado reproducirá esta información con una sentencia importante, como sigue:
<xs:import schemaLocation="PortfolioTypes.xsd" namespace="http://www.example.org/Portfolio"/>
por lo que la URI, absoluta o relativa, debe ser una que pueda ser resuelta al incluirla en el atributo 'schemaLocation'.
Los lectores familiarizados con SDOs sabrán que siempre son creados según una descripción de la estructura permitida (algunas veces llamada como el "esquema" o "modelo") y que, en vez de crearlos usando directamente 'new', es necesaria alguna forma de fábrica de datos. A menudo, se puede usar un objeto de datos existente como la fábrica de datos, pero otras veces, y especialmente para obtener el primer objeto de daots, otra cosa debe actuar como fábrica de datos.
En SCA, tanto la clase en tiempo de ejecución de SCA o los delegados para servicios, ya sean locales o remotos, pueden actuar como las fábricas de datos para SDOs. La elección de cúal usar, y cuando, está descrita en las dos secciones siguientes.
Cambiamos a un nuevo ejemplo para ilustrar la creación de SDOs, para pasarlo a, y ser devuelto por un servicio.
Un llamador de un servicio que requiera que una estructura de datos le sea pasada, utiliza un delegado para el servicio como la fábrica de datos para los correspondientes SDOs. Por ejemplo, suponga que un componente hace uso de un delegada para un servicio proporcionado por un componente AddressBook local.
<?php
/**
* @reference
* @binding.local AddressBook.php
*/
$address_book;
?>
El componente AddressBook que se desea llamar está definido como sigue:
<?php
/**
* @service
* @binding.soap
* @types http://addressbook ../AddressBook/AddressBook.xsd
*/
class AddressBook {
/**
* @param personType $person http://addressbook (un objeto person)
* @return addressType http://addressbook (el objeto address para el objeto person)
*/
function lookupAddress($person) {
...
}
}
?>
El componente AddressBook proporciona un método de servicio llamado lookupAddress() que usa los tipos del espacio de nombres http://addressbook namespace. el método lookupAddress toma una estructura de datos personType y devuelve un addressType. Ambos tipos están definido en el fichero de esquema addressbook.xsd.
Una vez que el componente que desea usar el componente AddressBook haya sido construido, de modo que la instancia variable $address_book contiene un delegado para el servicio, el componente llamador puede usar el delegado en $address_book para crear el SDO 'person', tal como se muestra abajo:
<?php
$william_shakespeare = $address_book->createDataObject('http://addressbook','personType');
$william_shakespeare ->name = "William Shakespeare";
$address = $address_book->lookupAddress($william_shakespeare);
?>
Observe que el uso del delegado como el medio de crear el SDO no está limitado a componentes SCA. Si un servicio está siendo llamado desde un script de PHP general, y el delegado fue obtenido con getService(), entonces se usa el mismo enfoque.
<?php
$address_book = SCA::getService('AddressBook.php');
$william_shakespeare = $address_book->createDataObject('http://addressbook','personType');
?>
Un componente que necesita crear un objeto de datos para devolverlo a un llamador no tendrá un delgado que usar como objeto de datos. En este caso usa el método estático createDataObject() de SCA.php. Por lo tanto, si el componente AddressBook descrito arriba necesita crear un objeto del tipo addressType dentro del espacio de nombres http://addressbook, podría hacerlo como sigue:
<?php
$address = SCA::createDataObject('http://addressbook','addressType');
?>