Компоненты SCA могут оперировать четырьмя скалярными типами PHP: boolean, integer, float и string. Но для передачи и приема структур данных компоненты SCA используют SDO. Более подробно об SDO можно почитать на этой странице документации. Читатели, знакомые с SDO, знают, что оно подходят для представления структурированных и полуструктурированных данных, которые часто моделируются в XML, и что они очень просто сериализуются для передачи между удаленными компонентами или в веб-сервисами. В настоящее время SDO - единственный поддерживаемый способ передачи и возврата структур данных. Нельзя передавать или возвращать объекты или массивы PHP.
SCA всегда гарантирует, что данные передаются по значению, даже для локальных вызовов. Для этого SCA копирует все SDO в список параметров перед их передачей, как и для скалярных типов.
В настоящее время единственным механизмом указания местоположения определения структуры данных является указание типов в файле схемы XML. Однако в будущем, возможно, появятся другие способы, например на основе классов или интерфейсов PHP или на основе определений, выраженных как ассоциативные массивы.
Чтобы проиллюстрировать использование SDO, мы вводим новый компонент. Сервис PortfolioMangement возвращает SDO, представляющий портфель акций для данного клиента.
Пример #1 Компонент использующий структуры данных
<?php
include "SCA/SCA.php";
/**
* Управление портфелем для клиента.
*
* @service
* @binding.soap
*
* @types http://www.example.org/Portfolio PortfolioTypes.xsd
*
*/
class PortfolioManagement {
/**
* Получение портфеля акций для данного клиента.
*
* @param integer $customer_id Идентификатор клиента
* @return Portfolio http://www.example.org/Portfolio The stock portfolio (акции и количества)
*/
function getPortfolio($customer_id) {
// Представьте, что мы только что получили это из базы данных
$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;
}
}
?>
Аннотация @types:
<?php
@types http://www.example.org/Portfolio PortfolioTypes.xsd
?>
Указывает, что типы в пространстве имен http://www.example.org/Portfolio будут найдены в файле схемы, расположенной по URI PortfolioTypes.xsd. Сгенерированный WSDL будет описывать эту информацию с помощью оператора импорта следующим образом:
<xs:import schemaLocation="PortfolioTypes.xsd" namespace="http://www.example.org/Portfolio"/>
Таким образом URI, абсолютный или относительный, должен быть разрешаем при включении в аттрибут schemaLocation.
Читатели, знакомые с SDO, знают, что они всегда создаются в соответствии с описанием допустимой структуры (иногда называемой "схемой" или "моделью"), и что, вместо того, чтобы создавать их напрямую, используя 'new', требуется использовать фабрику данных. Часто существующий объект данных может использоваться как фабрика данных, но иногда, и особенно для того, чтобы получить первый объект данных, необходима отдельная фабрика данных.
В SCA, либо классы времени исполнения SCA, либо прокси сервисов, локальные или удаленные могут служить фабриками данных SDO. Что именно выбрать в качестве фабрики и почему мы расскажем ниже.
Чтобы проиллюстрировать создание SDO мы переходим к новому примеру
Вызывающий сервис, которому требуется передать структуру данных, использует в качестве фабрики данных для соответствующих SDO прокси . Например, предположим, что компонент использует прокси для сервиса, предоставляемого локальным компонентом AddressBook.
<?php
/**
* @reference
* @binding.local AddressBook.php
*/
$address_book;
?>
Компонент AddressBook, который он хочет вызвать, определяется следующим образом:
<?php
/**
* @service
* @binding.soap
* @types http://addressbook ../AddressBook/AddressBook.xsd
*/
class AddressBook {
/**
* @param personType $person http://addressbook (объект person)
* @return addressType http://addressbook (объект address для объекта person)
*/
function lookupAddress($person) {
...
}
}
?>
Компонент AddressBook предоставляет метод сервиса lookupAddress(), который использует типы из пространства имен http://addressbook. Метод lookupAddress принимает структуру данных personType и возвращает addressType. Оба типа определены в файле схемы addressbook.xsd.
После того, как компонент, который хочет использовать компонент AddressBook, был сконструирован, и переменная $address_book содержит прокси для сервиса, вызывающий компонент может использовать прокси в $address_book для создания SDO, как показано ниже:
<?php
$william_shakespeare = $address_book->createDataObject('http://addressbook','personType');
$william_shakespeare ->name = "William Shakespeare";
$address = $address_book->lookupAddress($william_shakespeare);
?>
Обратите внимание: использование прокси в качестве средства для создания SDO не ограничивается компонентами SCA. Если служба вызывается из обычного PHP-скрипта, а прокси был получен с помощью getService(), то используется тот же подход.
<?php
$address_book = SCA::getService('AddressBook.php');
$william_shakespeare = $address_book->createDataObject('http://addressbook','personType');
?>
Компонент, который должен создать объект данных для возврата, не будет иметь прокси для использования в качестве объекта данных. В этом случае он использует статический метод createDataObject() из SCA.php. Следовательно, если описанный выше компонент AddressBook необходим для создания объекта типа addressType в пространстве имен http://address, то можно сделать следующее:
<?php
$address = SCA::createDataObject('http://addressbook','addressType');
?>