Как разработчики приложений, способность разрабатывать программное обеспечение и сервисы для широкого спектра платформ является необходимым навыком, но не все используют один и тот же язык или платформу, и написание кода для их поддержки неосуществимо. Если бы существовал стандарт, который позволял нам писать код один раз и позволять другим легко взаимодействовать с ним из собственного программного обеспечения. Ну, к счастью, есть … и это имя SOAP. (Раньше SOAP был аббревиатурой, обозначающей Simple Object Access Protocol, но с версии 1.2 протокол называется просто SOAP.)
SOAP позволяет создавать совместимое программное обеспечение и позволяет другим использовать ваше программное обеспечение в сети. Он определяет правила для отправки и получения удаленных вызовов процедур (RPC), такие как структура запроса и ответов. Поэтому SOAP не привязан к какой-либо конкретной операционной системе или языку программирования. Поскольку это важно, кто-то может сформулировать и проанализировать SOAP-сообщение на выбранном им языке.
В этой первой серии из двух частей, посвященной веб-сервисам, я расскажу о спецификации SOAP и о том, что происходит при создании сообщений SOAP. Я также продемонстрирую, как создать SOAP-сервер и клиент, используя отличную библиотеку NuSOAP, чтобы проиллюстрировать поток SOAP. Во второй части я расскажу о важности файлов WSDL, о том, как вы можете легко сгенерировать их с помощью NuSOAP, и о том, как клиент может использовать файл WSDL, чтобы лучше понять ваш веб-сервис.
Структура SOAP-сообщения
SOAP основан на XML, поэтому считается, что он предназначен для чтения человеком, но существует особая схема, которую необходимо соблюдать. Давайте сначала разберем сообщение SOAP, удалив все его данные, и просто посмотрим на конкретные элементы, составляющие сообщение SOAP.
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> ... </soap:Header> <soap:Body> ... <soap:Fault> ... </soap:Fault> </soap:Body> </soap:Envelope>
Это может выглядеть как обычный XML-файл, но что делает его SOAP-сообщением, так это корневой элемент Envelope с soap
пространства имен, например http://www.w3.org/2001/12/soap-envelope
. Атрибут soap:encodingStyle
определяет типы данных, используемые в файле, но сама SOAP не имеет кодировки по умолчанию.
soap:Envelope
является обязательным, но следующий элемент, soap:Header
, является необязательным и обычно содержит информацию, относящуюся к аутентификации и обработке сеанса. Протокол SOAP не предлагает никакой встроенной аутентификации, но позволяет разработчикам включать ее в этот тег заголовка.
Далее есть обязательный элемент soap:Body
который содержит реальное сообщение RPC, включая имена методов и, в случае ответа, возвращаемые значения метода. Элемент soap:Fault
является необязательным; если он присутствует, он содержит любые сообщения об ошибках или информацию о состоянии для сообщения SOAP и должен быть дочерним элементом soap:Body
.
Теперь, когда вы понимаете основы того, что составляет сообщение SOAP, давайте посмотрим, как могут выглядеть сообщения запросов и ответов SOAP. Начнем с запроса.
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.yourwebroot.com/stock"> <m:GetStockPrice> <m:StockName>IBM</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope>
Выше приведен пример сообщения SOAP-запроса для получения цены акций конкретной компании. Внутри soap:Body
вы заметите элемент GetStockPrice
который специфичен для приложения. Это не элемент SOAP, и он берет свое имя от функции на сервере, которая будет вызываться для этого запроса. StockName
также специфичен для приложения и является аргументом для функции.
Ответное сообщение похоже на запрос:
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.yourwebroot.com/stock"> <m:GetStockPriceResponse> <m:Price>183.08</m:Price> </m:GetStockPriceResponse> </soap:Body> </soap:Envelope>
Внутри элемента soap: Body есть элемент GetStockPriceResponse
с GetStockPriceResponse
элементом Price
который содержит возвращаемые данные. Как вы могли догадаться, оба GetStockPriceResponse
и Price
являются специфическими для этого приложения.
Теперь, когда вы увидели пример запроса и ответа и поняли структуру сообщения SOAP, давайте установим NuSOAP и создадим клиент и сервер SOAP, чтобы продемонстрировать создание таких сообщений.
Создание SOAP-сервера
Не может быть проще запустить NuSOAP и запустить его на вашем сервере; просто посетите sourceforge.net/projects/nusoap , загрузите и разархивируйте пакет в своей корневой веб-директории, и все готово. Чтобы использовать библиотеку, просто nusoap.php
файл nusoap.php
в свой код.
Для сервера, скажем, нам дали задачу создать сервис для предоставления списка продуктов с учетом категории продукта. Сервер должен прочитать в категории из запроса, найти все продукты, которые соответствуют категории, и вернуть список пользователю в формате CSV.
Создайте файл в вашем корне сети с именем productlist.php
со следующим кодом:
<?php require_once "nusoap.php"; function getProd($category) { if ($category == "books") { return join(",", array( "The WordPress Anthology", "PHP Master: Write Cutting Edge Code", "Build Your Own Website the Right Way")); } else { return "No products listed under that category"; } } $server = new soap_server(); $server->register("getProd"); $server->service($HTTP_RAW_POST_DATA);
Во-первых, файл nusoap.php включен для использования библиотеки NuSOAP. Затем getProd()
функция getProd()
. После этого создается новый экземпляр класса getProd()
функция getProd()
регистрируется с помощью метода register()
.
Это действительно все, что нужно для создания собственного SOAP-сервера — просто, не правда ли? В реальном сценарии вы, вероятно, искали бы список книг из базы данных, но, поскольку я хочу сосредоточиться на SOAP, я издевался над getProd()
чтобы получить жестко закодированный список названий.
Если вы хотите включить больше функций в сервер, вам нужно только определить дополнительные функции (или даже методы в классах) и зарегистрировать каждую из них, как вы делали выше.
Теперь, когда у нас есть работающий сервер, давайте создадим клиента, чтобы воспользоваться им.
Создание SOAP-клиента
Создайте файл с именем productlistclient.php
и используйте код ниже:
<?php require_once "nusoap.php"; $client = new nusoap_client("http://localhost/nusoap/productlist.php"); $error = $client->getError(); if ($error) { echo "<h2>Constructor error</h2><pre>" . $error . "</pre>"; } $result = $client->call("getProd", array("category" => "books")); if ($client->fault) { echo "<h2>Fault</h2><pre>"; print_r($result); echo "</pre>"; } else { $error = $client->getError(); if ($error) { echo "<h2>Error</h2><pre>" . $error . "</pre>"; } else { echo "<h2>Books</h2><pre>"; echo $result; echo "</pre>"; } }
Мы снова включаем nusoap.php
require_once
а затем создаем новый экземпляр nusoap_client
. Конструктор берет местоположение вновь созданного сервера SOAP для подключения. Метод getError()
проверяет, был ли клиент создан правильно, и код отображает сообщение об ошибке, если это не так.
Метод call()
генерирует и отправляет запрос SOAP для вызова метода или функции, определенной первым аргументом. Второй аргумент для call()
является ассоциированным массивом аргументов для RPC. Свойство fault и getError()
используются для проверки и отображения любых ошибок. Если нет, ошибок нет, выводится результат функции.
Теперь, когда оба файла находятся в корневом веб-каталоге, запустите клиентский скрипт (в моем случае http://localhost/nusoap/productlistclient.php
) в браузере. Вы должны увидеть следующее:
Если вы хотите проверять сообщения запросов и ответов SOAP в целях отладки или просто разбирать их на части для развлечения, добавьте эти строки в productlistclient.php
:
echo "<h2>Request</h2>"; echo "<pre>" . htmlspecialchars($client->request, ENT_QUOTES) . "</pre>"; echo "<h2>Response</h2>"; echo "<pre>" . htmlspecialchars($client->response, ENT_QUOTES) . "</pre>";
Заголовки HTTP и содержимое XML теперь будут добавлены к выводу.
Резюме
В этой первой части серии вы узнали, что SOAP предоставляет возможность создавать совместимое программное обеспечение, поддерживающее широкий спектр платформ и языков программирования. Вы также узнали о различных частях сообщения SOAP и создали свой собственный сервер и клиент SOAP, чтобы продемонстрировать, как работает SOAP.
В следующей части я подробно расскажу о кроличьей норе SOAP и объясню, что такое файл WSDL и как он может помочь вам с документацией и структурой вашего веб-сервиса.
Комментарии к этой статье закрыты. Есть вопрос по PHP? Почему бы не спросить об этом на наших форумах ?
Изображение через Лилиану Виноградову / Shutterstock