Вот простой пример, взятый из тестового источника с добавленными в него заметками:
Запрос SOAP
<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:enc=\"http://schemas.xmlsoap.org/soap/encoding/\"
xmlns:ns1=\"http://schemas.nothing.com\"
>
<env:Body>
<ns1:dotest>
<book xsi:type=\"ns1:book\">
<a xsi:type=\"xsd:string\">foo</a>
<b xsi:type=\"xsd:string\">bar</b>
</book>
</ns1:dotest>
</env:Body>
<env:Header/>
</env:Envelope>";
Код
// data object class
class book{
public $a="a";
public $b="c";
}
// XML transform callback function (for converting the "type" into an object)
function book_from_xml($xml) {
$sxe = simplexml_load_string($xml);
$obj = new book;
$obj->a = (string)$sxe->a;
$obj->b = (string)$sxe->b;
return $obj;
}
// SOAP action class (called by soap handle() method)
class test
{
function dotest($book)
{
$classname=get_class($book);
return "Object: ".$classname. "(".$book->a.",".$book->b.")";
}
}
// SOAPServer Instantiation
$options=Array(
'actor' =>'http://schemas.nothing.com',
'typemap' => array(
array(
// type namespaces have to match those declared in the WSDL
'type_ns' => 'http://schemas.nothing.com',
'type_name' => 'book',
'from_xml' => 'book_from_xml',
),
// additional typemap definition arrays go here
)
);
$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options);
$server->setClass("test");
$server->handle($HTTP_RAW_POST_DATA);
Исходный файл справки
Полезные, но важные замечания
- Входные карты типов должны иметь определенный обратный вызов
from_xml
, иначе вы получите ошибку сегментации.
- Выходные карты типов должны иметь определенный обратный вызов
to_xml
, иначе вы получите ошибку сегментации.
- Значение пространства имен
type_ns
должно соответствовать буквенному пространству имен, определенному в WSDL, иначе совпадение типов не произойдет.
- Обратные вызовы могут быть более сложными, чем простой обратный вызов функции, использованный в примере выше. Методы класса / объекта поддерживаются. Смотри ниже.
Сложные обратные вызовы
При использовании методов объекта или класса для обратных вызовов вам необходимо убедиться, что вы используете FQCN вашего класса (если вы используете пространства имен), и либо а) объявите свой метод обратного вызова как public static
если не хотите создавать экземпляр экземпляра или b) сначала создать экземпляр объекта и использовать его метод в качестве обратного вызова.
Вот несколько примеров более сложных обратных вызовов в массиве typemap:
Вызов метода статического класса
...
array(
// type namespaces have to match those declared in the WSDL
'type_ns' => 'http://schemas.nothing.com',
'type_name' => 'book',
// myStaticCallbackMethod must be a public static function of MyClass
'from_xml' => array('\My\Name\Space\MyClass', 'myStaticCallbackMethod'),
),
Или для версий PHP PHP 5.2.3 и выше:
array(
// type namespaces have to match those declared in the WSDL
'type_ns' => 'http://schemas.nothing.com',
'type_name' => 'book',
// myStaticCallbackMethod must be a public static function of MyClass
'from_xml' => array('\My\Name\Space\MyClass::myStaticCallbackMethod'),
),
Определение класса:
namespace My\Name\Space;
class MyClass
{
public static function myStaticCallbackMethod($xml)
{
// do something
}
}
вызов метода объекта
$obj = new \My\Name\Space\MyClass();
...
// static class method call
array(
// type namespaces have to match those declared in the WSDL
'type_ns' => "http://schemas.nothing.com",
'type_name' => 'book',
'from_xml' => array($obj, 'myCallbackMethod'),
),
Определение класса:
namespace My\Name\Space;
class MyClass
{
public function myCallbackMethod($xml)
{
// do something
}
}
Затворы
$myCallback = function($xml) {
// do something
};
...
// static class method call
array(
// type namespaces have to match those declared in the WSDL
'type_ns' => 'http://schemas.nothing.com',
'type_name' => 'book',
'from_xml' => $myCallback,
),