Использование SOAP и WSDL в PHP

14 февраля 2014
Короткое описание протокола SOAP и языка WSDL можно посмотреть в статье «Введение в SOAP и WSDL».
Документация по работе с SOAP в PHP: https://www.php.net/manual/ru/book.soap.php

Взаимодействие с SOAP в PHP обеспечивается библиотекой php_soap.dll. Нужно убедиться, что в файле конфигурации php.ini эта библиотека включена — то есть существует и не закомментирована символом ;


Второй момент, по-умолчанию через параметр soap.wsdl_cache_enabled включено кэширование WSDL-файлов. На время отладки рекомендуется отключить кэширование:
/**
* Отключение кэширования WSDL.
* Список настроек SOAP-WSDL https://www.php.net/manual/ru/soap.configuration.php
*/
ini_set('soap.wsdl_cache_enabled', 0);

Серверная часть

Работу серверной части обеспечивает класс SoapServer (см. документацию https://www.php.net/manual/ru/class.soapserver.php)

Далее необходимо создать собственный класс и определить в нём методы, с которыми работает веб-сервис. Класс будет обрабатывать запросы веб-сервиса. Имена методов должны совпадать с названиями операций из WSDL-файла. Для примера, класс будет называться my_calculator_class.

В прошлой статье в блоке <wsdl:operation name="math_action"> была определена операция math_action, которая по задумке должна складывать, вычитать, умножать и делать два числа. Соответственно метод класса должен называться math_action и выполнять указанные действия, возвращая результат.

Далее создаём объект сервера SoapServer и привязываем к нему через метод setClass наш класс my_calculator_class, который будет обрабатывать все запросы:

Полный код скрипта сервера:
<?
/**
* Отключение кэширования WSDL
* Список настроек SOAP-WSDL https://www.php.net/manual/ru/soap.configuration.php
*/
ini_set('soap.wsdl_cache_enabled', 0);

/**
* Класс обрабатывает запросы из SOAP-сервиса "Мой калькулятор"
*/
class my_calculator_class
{
	/**
	* Операция "Математическое действие". Выполняет математические действия
	* (сложение, вычитание, умножение и деление над двумя числами)
	*
	* @param stdClass $in_obj - объект с параметрами запроса
	* @return stdClass
	*/
	public function math_action($in_obj)
	{
		$r = new stdClass();

		$a = (float)$in_obj->a;
		$b = (float)$in_obj->b;
		$action = (string)$in_obj->action;

		switch($action)
		{
			case '+':
			{
            	$r->value = $a + $b;
            	break;
			}
			case '-':
			{
            	$r->value = $a - $b;
            	break;
			}
			case '*':
			{
            	$r->value = $a * $b;
            	break;
			}
			case '/':
			{
             	if($b==0) $r->message_error = 'Делить на ноль нелья';
             	else $r->value = $a / $b;
             	break;
			}
			default:
			{
             	$r->message_error = 'В параметре `action` пропущено или указано недопустимое математическое действие';
             	break;
			}
		}

		return $r;
	}

 	/**
 	* Возвращает приближённое значение числа Пи
	*
	* @param stdClass $in_obj - объект с параметрами запроса
	* @return stdClass
 	*/
	public function get_pi($arg)
	{
		$r = new stdClass();
		$r->value = 3.14;

		return $r;
	}
}

//Путь к WSDL файлу
$wsdl_file = $_SERVER['DOCUMENT_ROOT'].'/my_calculator/scheme.wsdl';

//Создаём объект SOAP-сервера
$soap_server = new SoapServer($wsdl_file, array(
	'soap_version' => SOAP_1_1,	//Версия протокола SOAP
	'encoding' => 'utf-8', 		//Кодировка, к которой должно приводиться содержимое запросов
));

//Устанавливаем на сервере класс, который будет обрабатывать запросы (операции из раздела wsdl:operation в WSDL файле)
$soap_server->setClass('my_calculator_class');

//Запуск обработки запросов
$soap_server->handle();

?>

Клиентская часть

Работу клиентской части обеспечивает класс SoapClient (см. документацию https://www.php.net/manual/ru/class.soapclient.php)

Тут взаимодействие ещё проще — создаётся объект SoapClient и через метод __soapCall (https://www.php.net/manual/ru/soapclient.soapcall.php) посылается запрос к серверу.

Пример кода клиента:
<?
/*
Отключение кэширования WSDL
Список настроек SOAP-WSDL https://www.php.net/manual/ru/soap.configuration.php
*/
ini_set('soap.wsdl_cache_enabled', 0);

//Путь к WSDL файлу
$wsdl_file = 'http://test-site.ru/my_calculator/scheme.wsdl';

//Настройки SOAP
$soap_settings = array(
	'soap_version' => SOAP_1_1,
	'encoding' => 'utf-8',
	'trace' => true, //включение отслеживания конвертов (будут доступны методы __getLastRequest и __getLastResponse)
);

//Клиент
$soap_client = new SoapClient($wsdl_file, $soap_settings);

try
{
	$params = array(
 		'a' => 100,
 		'b' => 5,
 		'action' => '/',
 	);
 	$r = $soap_client->__soapCall('math_action', array($params));

 	echo '<pre>'.print_r($r, true).'</pre>';

	//Вывод последнего запроса
	echo '<b>Содержимое запроса:</b><br><pre>'.trim(htmlspecialchars($soap_client->__getLastRequest())).'</pre><br>';

	//Вывод последнего ответа
	echo '<b>Содержимое ответа:</b><br><pre>'.trim(htmlspecialchars($soap_client->__getLastResponse())).'</pre>';
}
catch(SoapFault $soap_error)
{
	echo '<b>Ошибка:</b> '.$soap_error->getMessage();
}

?>

Результат работы клиента:


Архив с примерами файлов: scheme.wsdl, server.php, client.php
my_calculator.zip (4 Кб)