PHP и XML Web services

5
(1)

Введение

Общая идея служб выражается в следующем примере. Представим есть пользователь, он заходит на сайт, который сделали мы. На нашем сайте есть возможность посмотреть расписание рейсов автобусов из городов Украины в Европейские города. Но при этом наш сайт не располагает базой данных, в которой описаны все рейсы. Эти данные есть в гос. службе автовокзала.

Так вот, на сервере автовокзала, программисты пишут веб сервис, а мы на своем сайте пишем сервис клиент. И далее процесс идет таким путем:

  • пользователь делает запрос указывая при этом интересующие данные,
  • мы формируем полученные от пользователя данные и отправляем их запросом на веб сервис автовокзала,
  • там этот запрос обрабатывается сервисом, и нам летят данные из их базы данных,
  • мы отображаем эти данные на нашем сайте пользователю.

Для дополнительной наглядности рисунок 1.

Общая идея работы веб службы

Рисунок №1 — Общая идея работы веб службы

Характерными особенностями веб служб является:

  • использование протокола http для доступа к сервису,
  • если это, например, xml сервис, то данные между клиентом и сервером передаются именно в формате xml,
  • независимость от языка программирования.

История появления веб-служб берет свое начало с появления такого подхода, как Remote Procedure Call (RPC) или вызов удаленных процедур. Этот подход позволяет программе вызывать процедуры из удаленного адресного пространства. 

Важно! 

Remote Procedure Call — это именно подход, идея. Не путать с конкретной реализацией. Например, есть идея игры в мяч. Суть которой, что есть две команды ,которые пытаются забросить друг другу мяч.  И та команда, которая больше забросит, побеждает. Это идея, а вот, например, футбол — это конкретная реализация. 

Идея RPC получила ряд реализаций:

  • XML-RPC,
  • SOAP,
  • JSON-RPC,
  • .NET Remoting,
  • DCOM,
  • JAVA RMI.

Simple Object Access Protocol

SOAP — это простой протокол доступа к объектам. Запросы посылаются по протоколу http и методом POST.  Между клиентом и сервером передается xml строка. Передаваемый xml состоит из трех главных элементов:

  • Envelope,
  • Header,
  • Body.

Пример SOAP запроса

<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
      <getStock xmlns="http://site.ru/ws">
         <num>12345</num>
      </getStock>
    </soap:Body>
</soap:Envelope>

Тут происходит следующее. Запрос вызывает процедуру под именем getStock и передает ей параметр 12345. 

Ответ от сервера может иметь, например, такой вид

<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
   <getStockDetailsResponse xmlns="http://site.ru/ws">
     <getStockDetailsResult>
        <id>12345</id>
        <productName>Стакан граненый</productName>
        <description>Стакан граненый. 250 мл.</description>
        <price>9.95</price>
     </getStockDetailsResult>
   </getStockDetailsResponse>
</soap:Body>
</soap:Envelope>

В php для этих целей есть модуль php_soap.dll. Который предоставляет два класса для работы. Это:

  • SoapServer,
  • SoapClient.

Первый пример из урока (SOAP), представлен тремя файлами — client, service и wsdl.

<!-- client-->
//Создание SOAP-клиента
//Параметром передаем адрес wsdl.
//После чего, все операции, перечисленные в этом документе
//становятся методами объекта
$client = new SoapClient("http://pb.seolab.dp.ua/soap/stock.wsdl");

//Отправка запроса и получение результата
$res = $client->getStock(2);
echo "$res";

<!--  service -->
//Описание функции Web-сервиса
function getStock($id){
    $stock = array(
    "1" => 100,
    "2" => 200,
    "3" => 300,
    "4" => 400,
    "5" => 500,
    );
   if(isset($stock[$id])){
     return $stock[$id];
   }else{
     return 0;
   }
}

//Создаем SOAP-сервер
//И в конструктор передаем адрес, по которому расположен
//файл wsdl с описанием службы
$server = new SoapServer("https://pb.seolab.dp.ua/soap/stock.wsdl");

//Регистрируем функцию, к которой будет обращаться клиент
$server->addFunction("getStock");

//Запускаем сервер
$server->handle();

<!-- WSDL -->

<?xml version="1.0" encoding="UTF-8"?>

<!-- Web Services Description Language (WSDL)
Это xml документ, используемый для описания веб службы.
Описывает:
- Где находится служба
- Какие функции доступны клиенту
- Количество аргументов функций
- Типы аргументов функций
- Типы возвращаемых функциями значений
- Описание пользовательских типов для параметров функций-->

<definitions name='News' 
targetNamespace='http://pb.seolab.dp.ua/soap'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' 
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' 
xmlns='http://schemas.xmlsoap.org/wsdl/'>

<message name='getStockRequest'>
<!-- входящий параметр с типом integer -->
  <part name='id' type='xsd:integer' />
</message>
<message name='getStockResponse'>
<!-- возвращаемый параметр с типом integer -->
  <part name='item' type='xsd:integer' />
</message>

<portType name='StockPortType'>
  <operation name='getStock'><!-- наличие элементов input и output говорит о том, что функция и принимает и возвращает -->
    <input message='tns:getStockRequest' /><!-- в атрибуте message указано имя элемента, где описаны типы данных, которые принимает функция -->
    <output message='tns:getStockResponse' /><!-- в атрибуте message указано имя элемента, где описаны типы данных, которые возвращает функция -->
  </operation>
</portType>

<binding name='StockBinding' type='tns:StockPortType'><!-- Список доступных функций и имя элемента, в котором описан тип доступных функций (т.е. фун-ция только принимает или принимает и возвращает), указано в атрибуте "type"-->
  <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http' />
  <operation name='getStock' /><!-- Имя доступной функции. Количество элементов "operation" = кол-ву доступных для клиента функций -->
</binding>
<service name='StockService'><!-- имя сервиса -->
  <port name='StockPort' binding='StockBinding'><!-- тут указывается имя элемента, в котором описаны доступные функции -->
    <soap:address location='https://pb.seolab.dp.ua/soap/service.php' /><!-- указание адреса службы -->
  </port>
</service>
</definitions>

Нюансы в работе с SOAP

  1. При регистрации доступной для клиента функции ($server->addFunction(«getStock»)), в нашем примере используется лишь одна функция. Если необходимо указать список доступных функций нужно создать массив с именами доступных функций. $func = [«getStock», «setStock»]; и передать уже имя массива $server->addFunction(«$func»).
  2. Для того, чтобы на стороне клиента получить описание доступной нам функции используется метод __getFunctions. В представленном выше примере, это имело бы следующий вид — print_r($client->__getFunctions());//Array ([0] => integer getStock(integer $id))

Автор Виталий Сухомлинов
практикующий веб разработчик
и seo-специалист

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 5 / 5. Количество оценок: 1

Оценок пока нет. Поставьте оценку первым.