Задача
Необходимо создать SOAP-сервер и отвечать на SOAP-запросы. Если ваш сервер отвечает на SOAP-запросы, то любой, кто имеет соответствующий SOAP-клиент, может посылать запросы на ваш сервер через сеть Интернет.
Решение
Используем PEAR-класс SOAP_Server. Приведем пример сервера, который возвращает текущую дату и время:
require 'SOAP/Server.php';
class pc_SOAP_return_time {
var $method_namespace = 'urn:pc_SOAP_return_time';
function return_time() {
return date('Ymd\THis');
}
}
$rt = new pc_SOAP_return_time();
$server = new SOAP_Server;
$server->addObjectMap($rt);
$server->service($HTTP_RAW_POST_DATA);
Обсуждение
Вот три этапа создания SOAP-сервера с помощью PEAR-класса SOAP_Server:
1. Создаем класс для работы с SOAP-методами и реализуем его.
2. Создаем экземпляр SOAP-сервера и связываем обрабатываемый
объект с сервером.
3. Приказываем серверу обрабатывать запрос и отвечать SOAP-клиенту.
PEAR-класс SOAP_Server использует объекты для обработки SOAP-запросов. Обрабатывающему запрос классу необходимо указать свойство $method_namespace, которое определяет его пространство имен SOAP.
В данном случае это urn:pc_SOAP_return_time. Затем методы объекта назначают имена процедурам SOAP из указанного пространства имен. Действительное имя класса, принятое в PHP, не распространяется посредством SOAP, поэтому тот факт, что имя класса и его $method_namespace идентичны, является вопросом удобства, а не необходимостью:
class pc_SOAP_return_time {
var $method_namespace = 'urn:pc_SOAP_return_time';
function return_time() {
return date('Ymd\THis');
}
}
$rt = new pc_SOAP_return_time();
После того как определен класс, создается экземпляр этого класса, чтобы связать методы с объектом SOAP-сервера. Однако перед сопоставлением процедур и методов класса необходимо создать сам объект SOAP_Server:
$server = new SOAP_Server;
$server->addObjectMap($rt);
$server->service($GLOBALS['HTTP_RAW_POST_DATA']);
После того как это сделано, вызываем функцию SOAP_Server::addObject Map(), передавая объект в качестве параметра для того, чтобы сообщить серверу о методах, предоставляемых этим объектом. Теперь сервер готов отвечать на все SOAP-запросы из пространства имен, для которого вы определили методы.
Чтобы дать указание серверу отвечать на запрос, вызовите функцию SOAP_Server::service() и передайте SOAP-конверт. Поскольку конверт доставляется с помощью метода POST, вы передаете переменную $GLOBALS['HTTP_RAW_POST_DATA']. Таким образом, серверу предоставляется весь запрос целиком, о необходимом анализе запроса позаботится класс.Для вызова этой процедуры с помощью PEAR SOAP-клиента используйте следующий код:
require 'SOAP/Client.php';
$soapclient = new SOAP_Client('http://clock.example.com/time-soap.php');
$result = $soapclient->call('return_time', array(),
array('namespace' => 'urn:pc_SOAP_return_time'));
print "The local time is $result.\n";
Его вывод будет таким:
The local time is 20020821T132615.
Чтобы расширить этот метод для чтения параметров, необходимо изменить прототип метода, включив имена параметров, а затем модифицировать клиентский запрос, добавив данные дополнительных аргументов. Следующий пример модифицирует SOAP-процедуру так, чтобы она принимала временную зону в качестве необязательного аргумента:
class pc_SOAP_return_time {var $method_namespace = 'urn:pc_SOAP_return_time';
function return_time($tz='') {
if ($tz) { putenv("TZ=$tz"); }
$date = date('Ymd\THis');
if ($tz) { putenv('TZ=EST5EDT'); } // меняем EST5EDT на зону вашего
// сервера
return $date
}
}
Второй параметр в клиентском вызове теперь принимает опцию tz:
$result = $soapclient->call('return_time', array('tz' => 'PST8PDT'),
array('namespace' => 'urn:pc_SOAP_return_time'));
С новыми настройками сервер возвращает время, отстающее от предыдущего времени на три часа:
20020821T202615