Статьи

Создайте свой собственный веб-сервис с PHP и XML-RPC

Одной из актуальных тем в Интернете являются веб-сервисы, представленные Кевином Янком в его статье « Демистифицированные веб-сервисы» .

Если вы следите за отраслевыми новостями на эту тему, вы можете подумать, что это технология высокого уровня, которая интересна только крупным компаниям с огромными бюджетами. Но если бы ты сделал, ты был бы неправ.

Концепции, лежащие в основе веб-сервисов, удивительно просты, и в этой статье мы подробнее рассмотрим, что с ними происходит. Затем, с небольшой помощью нашего хорошего друга PHP , мы настроим наш первый веб-сервис.

Мы предполагаем некоторые знания PHP, MySQL и XML, которые – если вы не уверены в них – вы можете быстро выбрать из создания собственного сайта, управляемого базой данных, используя PHP & MySQL и XML – Введение .

Итак, вот что в меню:

Основы веб-сервисов. Для начала мы кратко рассмотрим основные концепции веб-сервисов.

Представляем XML-RPC: Далее мы познакомим вас со стандартом XML для обмена данными между системами и познакомим его со статьей Кевина.

Реализации PHP XML-RPC: Затем мы рассмотрим некоторые реализации XML-RPC с открытым исходным кодом в PHP: код, который можно использовать для быстрого создания собственной веб-службы или доступа к другим веб-службам с вашего сайта.

Ваш первый веб-сервис: если вы хотите перейти прямо к делу, это место для вас. Здесь мы возьмем одну из реализаций, описанных ранее, и создадим для нее Web-сервис на PHP.

Что вы можете сделать с XML-RPC: Хотите знать, что делать дальше? Мы дадим вам несколько идей о том, что вы можете сделать с XML-RPC и веб-службами.

Давайте начнем!

Основы веб-сервисов

Первое, что нужно понять о веб-сервисах, это то, что они не являются чем-то новым. Если вы когда-либо использовали RSS-канал, чтобы получать новости с другого веб-сайта и размещать их самостоятельно, у вас уже есть хорошее представление о том, как работают веб-службы (см. Статью Кевина Янка: PHP и XML: парсинг RSS 1.0 ).

Веб-службы предназначены для обмена данными между сервером и клиентом с использованием стандартного формата XML для «упаковки» запросов и данных, чтобы обе системы могли «понимать» друг друга. Сервер и клиент могут быть как веб-серверами, так и любыми другими электронными устройствами, о которых вы можете подумать.

В сети обмен данными в веб-службе обычно происходит через TCP-порт 80, используя стандартные протоколы POST HTTP. Иными словами, веб-службы работают в основном так же, как ваш браузер, когда он отправляет HTML-форму на сайт и получает веб-страницу в ответ. Единственное реальное отличие состоит в том, что вместо HTML веб-службы используют XML. А это означает, что веб-службы могут быть доступны в любом месте Интернета, проходя через брандмауэры так же, как при просмотре веб-страницы. Обмен данными происходит на уровне упаковки .

Помимо обмена данными, вам также нужна информация, которая описывает интерфейс (или интерфейс прикладных программ – API) к службе. Это делает веб-сервис полезным для остальной части Интернета, позволяя другим разработчикам разрабатывать программы, которые могут получить доступ к вашему веб-сервису. Это называется уровнем описания , и стандарт WSDL (язык описания веб-служб), который сделает это возможным, находится в стадии разработки.

Кроме того, есть информация, которая описывает характер самой службы (в отличие от HTML-дескриптивных тегов META), поэтому ее можно классифицировать и найти на сайтах, предлагающих каталоги веб-служб. Это уровень обнаружения , который в настоящее время рассматривается стандартом UDDI (универсальное описание, обнаружение и интеграция).

Слои описания и обнаружения – это просто XML, управляемый особым форматом, который позволяет найти соответствующую информацию для всех веб-служб в Интернете.

Возможно, то, что сделало веб-сервисы горячей темой в последнее время – помимо маркетинга таких компаний, как Microsoft и IBM, – это разработка этих стандартов. Они позволят массово развернуть веб-службы в Интернете, опираясь на инструменты разработки, которые сделают доступ к ним как предсказуемым, так и простым.

Но следует помнить, что все, что веб-служба делает сейчас с точки зрения обмена данными, также можно было бы сделать 5 или даже 10 лет назад с использованием стандарта HTTP и любого формата XML, который вы решили использовать или изобрести (каналы RSS являются простыми). пример). «Горячие новости» сегодня заключаются в том, что создание и распространение веб-службы теперь намного проще, чем в прошлом.

В любом случае, если вы ищете бесплатный источник новостей для технологических разработок в Web-сервисах, попробуйте XML Hack .

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

Представляем XML-RPC

В статье «Демистифицированные веб-службы» Кевин рассматривает стандарт, называемый SOAP , который используется для «упаковки» данных для обмена между двумя системами. SOAP находится на пути к тому, чтобы стать стандартом W3C для веб-сервисов, и при поддержке Microsoft и IBM, вероятно, очень скоро получат официальную печать.

Но для этой же цели существует другой стандарт: XML-RPC . Он существует с 1998 года, и хотя он не является официальным стандартом W3C, он уже широко используется и имеет впечатляющую поддержку в виде проектов с открытым исходным кодом. Разработанный Useful Inc. совместно с Microsoft, он может рассматриваться во многих отношениях как предвестник SOAP, который еще не прекратил свою работу.

Как будет показано в этой статье, самое важное, что есть у XML-RPC, – это простота, которая становится понятной с самого начала, когда вы сравниваете спецификацию на 1500 слов с библией (и растущей) из 11 000 слов в SOAP. Другая хорошая новость заключается в том, что XML-RPC хорошо поддерживается в PHP, наряду с реализациями практически на любом другом языке, который вы можете пожелать.

Для подробного сравнения XML-RPC и SOAP я бы рекомендовал прочитать XML-RPC и SOAP . Вкратце, SOAP призван заполнить пробелы в XML-RPC, предлагая по-настоящему корпоративный механизм для обмена данными между системами. Например, должно быть проще доставлять многомерные массивы через SOAP, чем через XML-RPC. Но в использовании XML-RPC нет ничего плохого, особенно если учесть, что это стабильный стандарт, а в будущем SOAP может подвергнуться дальнейшему пересмотру.

Вы можете задаться вопросом, стоит ли прилагать усилия для изучения XML-RPC, если он собирается быть заменен другим стандартом. Не беспокойтесь больше: вы можете легко преобразовать запрос SOAP в запрос XML-RPC с помощью XSLT , что позволит вашему XML-RPC выжить в грязном Интернете, где все ищут SOAP (извинения, но нужно было сделать один удар) ,

Так как же работает XML-RPC? Как вы увидите позже в этой статье, вам не нужно знать слишком много об этом, чтобы иметь возможность использовать его. Но есть много информации , которая описывает это, и стоит прочитать XML-RPC для новичков . Мы кратко рассмотрим, как сейчас работает XML-RPC, а затем перейдем к тому, как мы можем его использовать.

Двумя основными компонентами «сообщения» XML-RPC являются методы и параметры . Методы слабо соответствуют функциям, которые вы определяете в PHP, а параметры соответствуют переменным, которые вы передаете этим функциям. Параметры могут быть одного из множества различных типов, таких как строки, целые числа и массивы – очень похожие на типы переменных, к которым вы уже привыкли в PHP. Кроме того, XML-RPC определяет другие теги для таких вещей, как обработка ошибок, но мы оставим это объяснение спецификации, так как по большей части нам никогда не придется беспокоиться о них.

«Разговор» XML-RPC между двумя системами начинается с запроса от клиента XML-RPC, на который сервер отвечает ответом . Запрос содержит метод и, возможно, некоторые параметры, необходимые для метода. Ответ отвечает параметрами, которые содержат запрошенные данные. Этот процесс очень похож на использование функции, которую вы определили в скрипте PHP; Вы вызываете функцию и передаете ей некоторые переменные. Затем функция отвечает, возвращая некоторые переменные.

Вот как может выглядеть запрос клиента с точки зрения целевого сервера XML-RPC:

Запрос (от вашего клиента XML-RPC):

POST /xmlrpcInterface HTTP/1.0  User-Agent: Sitepoint XML-RPC Client 1.0  Host: xmlrpc.sitepoint.com  Content-type: text/xml  Content-length: 195  <?xml version="1.0"?>  <methodCall>    <methodName>forums.getNumTodaysThreads</methodName>  <params>  <param><value><string>PHP Development</string></value></param>  </params>  </methodCall> 

А вот и ответ от сервера, который видит клиент XML-RPC.

Ответ (с сервера XML-RPC):

   HTTP/1.1 200 OK  Connection: close  Content-Length: 148  content-Type: text/xml  Date: Wed, Jul 28 1999 15:59:04 GMT  Server: Sitepoint XML-RPC Server 1.0  <?xml version="1.0"?>  <methodResponse>    <params>      <param>        <value><int>42</int></value>      </param>    </params>  </methodResponse> 
Пример запроса может быть, чтобы узнать, сколько потоков было опубликовано на форуме по разработке PHP сегодня. Ответ сообщает клиенту номер, который он запросил. Это простой пример, отправка одного параметра в метод и получение одного параметра обратно. XML-RPC предоставляет гораздо больше, позволяя передавать на сервер более сложные наборы данных (например, массивы) и получать взамен подробный ответ, содержащий все виды данных.

Если вам интересно, «RPC» в XML-RPC означает «Удаленный вызов процедур». Клиентская система «вызывает» «процедуру» (или метод) на удаленном сервере. Концепция удаленного вызова процедур является общей для разработки программного обеспечения, и ее можно встретить во многих местах. XML-RPC - это стандарт XML для обмена данными, который используется в удаленном вызове процедур.

XML-RPC сам по себе находится на уровне упаковки технологического стека, описанного в «Демистификации веб-служб» Кевина (и, как уже упоминалось выше, это альтернатива SOAP, которую Кевин использует в качестве примера уровня упаковки). Что происходит в слоях описания и обнаружения, зависит от вас. Некоторые реализации XML-RPC предлагают расширения, которые обеспечивают самоанализ, что равносильно уровню описания, предоставляющему подробные сведения о методах и параметрах, с помощью которых можно вызывать сервер XML-RPC. Уровень обнаружения отсутствует в XML-RPC: отсутствует центральный реестр серверов XML-RPC, но, несомненно, появятся расширения, соответствующие стандарту UDDI , когда возникнет такая необходимость.

Достаточно подробно XML-RPC! Используя реализации, которые уже существуют для PHP, вам не нужно слишком увлекаться самим стандартом. Итак, давайте посмотрим, что вы можете получить бесплатно для XML-RPC и PHP ...

Реализации PHP XML-RPC

Как только ваши руки начали потеть, пришло время рассмотреть ряд проектов с открытым исходным кодом, которые могут избавить вас от необходимости писать собственный код для генерации запросов и ответов XML-RPC. Все рассмотренные здесь взяты со страницы реализации на xmlrpc.com . Два основных «стресс-теста» при их рассмотрении были:

  1. сколько времени они занимают, чтобы установить и использовать?

  2. Будут ли они широко поддерживаться типом конфигурации PHP, который вы найдете на среднем веб-хосте?

XMLRPC-EPI

http://xmlrpc-epi.sourceforge.net/

XMLRPC-EPI изначально разрабатывался для внутреннего использования в первых рядах и был настолько успешным, что теперь предоставляет PHP свои экспериментальные функции XML-RPC . XMLRPC-EPI сам по себе является базовым классом, написанным на C ++ (остальные написаны на PHP), который вы не сможете легко установить на своем веб-сервере, если у вас нет доступа с правами root - вам нужно -компилировать PHP.

Кроме того, этот класс имеет дело только с интерпретацией запросов и ответов XML-RPC и фактически не отправляет и не получает сами запросы. Вы найдете раннее руководство по его использованию здесь .

eZ xmlrpc

http://developer.ez.no/article/static/53/

Разработанный Bård Farstad (должен любить это имя), этот класс XML-RPC используется в ezPublish для получения запросов от клиентского компьютера . Дизайн класса хорош тем, что работать с ним довольно интуитивно, и он хорошо представлен в этом уроке , плюс он предлагает самоанализ.

Но он не работает в одном важном моменте - он требует, чтобы анализатор xml (--with-qtdom) был доступен и настроен для использования с PHP. Это будет нестандартным для большинства установок PHP, которые обычно принимают парсер XML-экспата (--with-xml). Так что, к сожалению, нам придется искать в другом месте ...

Fase 4 XML-RPC

http://www.fase4.com/xmlrpc/

Глядя на сайт, документация хороша, но при установке и попытке демонстрационного скрипта «server.php» выдается ошибка «класс не найден». С таким количеством на выбор, что исключает этот класс из гонки.

phpRPC

http://sourceforge.net/projects/phprpc/

У этого класса есть потенциал. Он выходит за рамки интерпретации и обработки запросов / ответов, обеспечивая функциональность, такую ​​как подключение к «абстрактной» базе данных. Текущая версия альфа 0.9, так что пока мы собираемся перейти на нее, но за ней стоит следить. Если у вас запланированы большие проекты, этот класс может сэкономить вам много времени на разработку.

phpxmlrpc

http://phpxmlrpc.sourceforge.net/

Разработанный Useful Inc, создателем стандарта XML-RPC, этот класс, очевидно, много чего делает. По сути, он полностью поддерживает стандарт XML-RPC и также предлагает отладку, что, как мы увидим позже, может стать одной из ваших больших проблем при создании веб-службы.

Документация хороша, и есть много примеров, а также это руководство о том, как создать клиент с ее помощью. Но, как отправная точка для создания вашего первого веб-сервиса, этот класс не идеален - его можно рекомендовать только более опытным разработчикам PHP, поэтому мы будем искать в другом месте ...

Keith Devens 'XML-RPC клиент / сервер

http://www.keithdevens.com/software/xmlrpc/

Посетив домашнюю страницу проекта, вы быстро поймете, что вам легче начать. Код - это просто набор пользовательских функций PHP для включения в ваши сценарии, а не полный класс.

Он отнимает у ваших серверов и клиентов XML-RPC требование, чтобы они выяснили, с какими типами параметров XML-RPC они имеют дело. Это означает, что вашему XML-RPC-клиенту нужно быть более внимательным при изучении данных, которые он получает, но вас будут беспокоить только переменные PHP (к которым вы уже привыкли), а не параметры XML-RPC. Также документация хорошая. Так что именно здесь мы начнем создавать ваш первый веб-сервис ...

Ваш первый веб-сервис

Вот так! Давайте создадим веб-сервис для публикации новостей с вашего веб-сайта в соответствии с RSS-каналом. Но вместо предоставления списка заголовков и ссылок, которые в конечном итоге приведут пользователя к исходному источнику новостей, наш веб-сервис будет выглядеть так, как будто новости живут на сайте, где установлен клиент XML-RPC.

Мы определим два метода XML-RPC для нашего использования: " news.getNewsList ", который предоставит список элементов новостей, и " news.viewNewsItem ", который будет отображать один элемент новостей полностью. В случае возникновения проблем также будет использоваться метод method_not_found по умолчанию. Каждый метод соответствует функции, которую мы определим в PHP, такой как запрос, который SELECT новости из вашей базы данных.

Предположим, у вас есть PHP 4.1.0 или более поздней версии и доступ к базе данных MySQL (версия 3.23+). Стоит прочитать код и изучить комментарии, а также проверить документацию для функций, связанных с XML-RPC Кейта .

Ok. Закатайте рукава, и мы поедем ...

Препараты

1. Загрузите архив кода для этой статьи - это избавит вас от кропотливого вырезания и вставки кода со страниц этого руководства.

2. Загрузите исходный код с http://www.keithdevens.com/software/xmlrpc/source.php и сохраните его как «kd_xmlrpc.php».

3. Теперь создайте каталог на вашем веб-сервере с именем kd_xmlrpc, ниже вашего веб-корня (где находится ваша «домашняя страница») и поместите туда файл kd_xmlrpc.php. Мы будем помещать все остальные файлы, которые мы создаем ниже, в тот же каталог.

4. Создайте таблицу в базе данных MySQL, используя этот запрос:

 CREATE TABLE kd_xmlrpc_news (  news_id mediumint(9) NOT NULL auto_increment,  title varchar(255) default NULL,  short_desc text,  full_desc text,  author varchar(100) default NULL,  date datetime NOT NULL default '0000-00-00 00:00:00',  PRIMARY KEY  (news_id)  ) TYPE=MyISAM COMMENT='XML RPC News'; 

4. Теперь INSERT в таблицу несколько фиктивных новостей - или, если вам не хватает вдохновения, запустите запрос "kd_xmlrpc_news.sql", который вы найдете в архиве кода (загружен на шаге 1).

Сервер XML-RPC

База данных теперь готова к действию. Далее, давайте создадим сервер XML-RPC и назовем его «server.php»:

 <?php  /* server.php */   /* Variables for accessing MySQL */  $dbserver= "localhost";     // Hostname of your MySQL server  $db = "database_name";      // Name of your MySQL database  $dbuser = "username";       // MySQL user with access to $db  $dbpassword = "password";   // Password for MySQL user   /* Connect to the MySQL server */  $link = @mysql_connect ($dbserver, $dbuser, $dbpassword);  if (! $link){    echo ( "Unable to connect to db" );  exit();  }   /* Select the database */  if (!mysql_select_db ($db, $link) ){  exit ();  }   /* Include Keith's xml-rpc library */  include("kd_xmlrpc.php");   /* Include a file that defines all the xml-rpc "methods" */  include("web_service_api.php");   /* Now use the XMLRPC_parse function to take POST   data from what xml-rpc client connects and turn   it into normal PHP variables */  $xmlrpc_request = XMLRPC_parse($GLOBALS['HTTP_RAW_POST_DATA']);   /* From the PHP variables generated, let's get the   method name ie. server asks "What would you like   me to do for you?" */  $methodName = XMLRPC_getMethodName($xmlrpc_request);   /* Get the parameters associated with that method   eg "So you want to view a news item. Tell me   which one you want. What's the id#?" */  $params = XMLRPC_getParams($xmlrpc_request);   /* Error check - if a method was used that doesn't   exist, return the error response to the client */  if(!isset($xmlrpc_methods[$methodName])){    $xmlrpc_methods['method_not_found']($methodName);   /* Otherwise, let's run the PHP function corresponding   to that method - note the functions themselves   return the correct formatted xml-rpc response   to the client */  }else{     /* Call the method - notice $params[0] not just $params as the    documentation states. */    $xmlrpc_methods[$methodName]($params[0]);  }  ?> 

Вот краткий обзор того, что происходит внутри server.php:

  1. Подключитесь к MySQL, чтобы предоставить скрипту доступ к базе данных.
  2. Включите код kd_xmlrpc.php, чтобы мы могли использовать функции Кейта.
  3. Включите web_service_api.php, который определяет методы XML-RPC (см. Ниже).
  4. Используйте XMLRPC_parse() чтобы взять содержимое $GLOBALS['HTTP_RAW_POST_DATA'] , которое содержит запрос от клиента XML-RPC, и преобразовать XML в переменные PHP.
  5. Теперь определите, какой метод XML-RPC был вызван, используя XMLRPC_getMethodName() . Мы хотим, чтобы один и тот же XML-RPC-сервер мог выполнять более одной задачи (метод / функцию), и здесь мы определяем, какую из них мы будем выполнять для текущего запроса (например, « news.getNewsList » или « news.viewNewsItem «).
  6. Теперь проверьте все параметры, отправленные в запросе клиента, такие как « id » (идентификационный номер) новости.
  7. Наконец, мы проверяем, что метод существует, как определено в web_service_api.php, и, если все выглядит хорошо, мы запускаем th-метод (т.е. функцию PHP). Если мы не можем найти метод, мы запускаем метод по умолчанию " method_not_found ".

Мы использовали специальные функции XML-RPC:

  • XMLRPC_parse() : эта функция берет некоторый XML и превращает его в переменные PHP – поэтому XML из запроса клиента преобразуется в форму, с которой может работать PHP. На данный момент это не относится к стандарту XML-RPC – любой отправленный XML будет преобразован в переменные PHP.
  • XMLRPC_getMethodName() определяет, какой метод используется, чтобы мы могли решить, какую функцию PHP использовать.
  • XMLRPC_getParams() принимает любые параметры XML-RPC и преобразует их в переменные PHP.

На этом сервер XML-RPC закончен. В общем, это то, что вы делаете для каждого построенного вами XML-RPC-сервера. Не сложно, не так ли? Теперь все, что нам нужно, это те функции PHP, которые будут использоваться с методами …

Методы

Далее мы определяем некоторые функции PHP, которые соответствуют методам XML-RPC, и сохраняем их в web_service_api.php:

 <?php  /* web_service_api.php */   /* Define an array to name the xmlrpc methods and   their corresponding PHP functions */  $xmlrpc_methods = array();  $xmlrpc_methods['news.getNewsList'] = news_getNewsList;  $xmlrpc_methods['news.viewNewsItem'] = news_viewNewsItem;  $xmlrpc_methods['method_not_found'] = XMLRPC_method_not_found;   /* Now a useful function for converting MySQL datetime   to a UNIX timestamp which can then be used with   the XMLRPC_convert_timestamp_to_iso8601($timestamp) function.   This is not a method!   It comes from: http://www.zend.com/codex.php?id=176&single=1 */  function mysql_datetime_to_timestamp($dt) {    $yr=strval(substr($dt,0,4));    $mo=strval(substr($dt,5,2));    $da=strval(substr($dt,8,2));    $hr=strval(substr($dt,11,2));    $mi=strval(substr($dt,14,2));    $se=strval(substr($dt,17,2));    return mktime($hr,$mi,$se,$mo,$da,$yr);  }   /* Function for listing news items, corresponding   to the news.getNewsList method Allows ordering by   column name and a result limit of up to 20 rows */  function news_getNewsList ( $query_info=0 ) {     /* Define an array of column names we'll accept   to ORDER BY in our query */    $order_fields = array ( "author", "title" );     /* Now check to see if $query_info['order'] has    an acceptable value and assign the correct value    to the $order variable */    if ( ISSET ( $query_info['order'] ) &&            in_array ( $query_info['order'], $order_fields ) ) {        $order = "ORDER BY " . $query_info['order'] . ", date DESC ";    } else {        $order = "ORDER BY date DESC ";    }     /* Now check for $query_info['limit'] to specify    the number of news items we want returned,    and assign the correct value to $limit */    if ( ISSET ( $query_info['limit'] ) && $query_info['limit'] < 20 ) {        $limit = "LIMIT 0, " . $query_info['limit'] . " ";    } else {        $limit = "LIMIT 0, 5 ";    }     /* Now build the query */    $query = "SELECT * FROM kd_xmlrpc_news " . $order . $limit;    $sql = mysql_query ( $query );    if ( $sql ) {        $news_items = array();        while ( $result = mysql_fetch_array ( $sql ) ) {             /* Extract the variables we want from the row */            $news_item['news_id'] = $result['news_id'];            $news_item['date'] = XMLRPC_convert_timestamp_to_iso8601(                mysql_datetime_to_timestamp( $result['date'] )                );            $news_item['title'] = $result['title'];            $news_item['short_desc'] = $result['short_desc'];            $news_item['author'] = $result['author'];             /* Add to the $news_items array */            $news_items[] = $news_item;        }         /* Convert the $news_items array to a set        of XML-RPC parameters then respond with the XML. */        XMLRPC_response(XMLRPC_prepare($news_items),        KD_XMLRPC_USERAGENT);    } else {         /* If there was an error, respond with an        error message */        XMLRPC_error("1", "news_getNewsList() error: Unable        to read news:"            . mysql_error() . "nQuery was: " . $query,  KD_XMLRPC_USERAGENT);    }  }   /* Function for viewing a full news item corresponding   to the news.viewNewsItem method */  function news_viewNewsItem ( $news_id ) {     /* Define the query to fetch the news item */    $query = "SELECT * FROM kd_xmlrpc_news WHERE news_id = '"    . $news_id . "'";    $sql = mysql_query ( $query );    if ( $result = mysql_fetch_array ( $sql ) ) {         /* Extract the variables for sending in        our server response */        $news_item['news_id'] = $result['news_id'];        $news_item['date'] = XMLRPC_convert_timestamp_to_iso8601(            mysql_datetime_to_timestamp( $result['date'] ) );        $news_item['title'] = $result['title'];        $news_item['full_desc'] = $result['full_desc'];        $news_item['author'] = $result['author'];         /* Respond to the client with the news item */        XMLRPC_response(XMLRPC_prepare($news_item),        KD_XMLRPC_USERAGENT);    } else {         /* If there was an error, respond with a        fault code instead */        XMLRPC_error("1", "news_viewNewsItem() error: Unable  to read news:"            . mysql_error(), KD_XMLRPC_USERAGENT);    }  }   /* Function for when the request method name  doesn't exist */  function XMLRPC_method_not_found($methodName){    XMLRPC_error("2", "The method you requested, " . $methodName        . ", was not found.", KD_XMLRPC_USERAGENT);  }  ?> 

Что здесь случилось?

  1. Сначала мы определили массив PHP $xmlrpc_methods , который представляет собой список всех доступных методов XML-RPC и функций PHP, которые нужно запустить для этого метода.
  2. Функция mysql_datetime_to_timestamp() – это не сам метод XML-RPC, а скорее полезная функция для преобразования полей даты и времени MySQL в формат, с которым может работать PHP.
  3. Затем мы определяем news_getNewsList() , который мы будем использовать для запроса таблицы « kd_xmlrpc_news ». Эта функция может принимать массив с именем $query_info , который будет соответствовать необязательным параметрам, которые может отправить клиент XML-RPC. Как видите, это изменяет запрос, который мы запускаем к mysql, изменяя параметры « ORDER BY » и « LIMIT ».
  4. Функция news_viewNewsItem() используется для извлечения отдельного элемента новостей из базы данных и принимает только одну переменную / параметр: $news_id, который соответствует идентификатору строки статьи в базе данных.
  5. Последняя функция, XMLRPC_method_not_found() , является нашей функцией по умолчанию, которая генерирует ответ, когда клиентский запрос относится к методу XML-RPC, который не существует.

Мы использовали специальные функции XML-RPC:

  • XMLRPC_convert_timestamp_to_iso8601() : XML-RPC имеет определенный формат для отправки даты и времени. Эта функция берет временную метку PHP и преобразует ее в правильный формат для XML-RPC.
  • XMLRPC_prepare() : он принимает набор переменных PHP и превращает его в параметры XML-RPC. Он определяет тип используемой переменной и создает правильный вывод XML-RPC из нее. Это одна из вещей, которые делают код Кейта Девенса дружественным к использованию – другие реализации обычно требуют, чтобы вы использовали отдельную функцию для массивов, целых чисел, строк и т. Д. При построении XML-RPC-запроса ответа.
  • XMLRPC_response() : это функция, которую вы используете для предоставления результатов клиенту по запросу. Он принимает два значения – первое – это данные XML-RPC (созданные XMLRPC_prepare()) , а второе – необязательное имя для сервера или агента пользователя, например, KD_XMLRPC_USERAGENT – это может быть любым, что вам нравится.
  • XMLRPC_error() : генерирует ответ XML-RPC с использованием тегов сообщения об ошибках, определенных в спецификации. При желании вы можете создать здесь свой собственный набор кодов ошибок для вашего сервера, что может помочь, когда дело доходит до отладки сервера.

Уф! Итак, теперь мы определили наши функции PHP и имеем массив для перевода их в методы XML-RPC: наш сервер XML-RPC готов к работе! Теперь, чтобы закончить, давайте составим простой клиент для доступа к нашим новостям.

Клиент XML-RPC

Для примера, мы будем хранить клиентский скрипт в том же месте, что и сервер, но если у вас есть другой веб-сервер, вы можете разместить скрипт там, убедившись, что у него есть доступ к функциям “kd_xmlrpc.php”, функциям библиотека.

 <?php  /* Include the library */  include ( "kd_xmlrpc.php" );   /* Define variables to find the rpc server script */  $site = "www.yourdomain.com";  $location = "/kd_xmlrpc/server.php";   /* Function to give us back a nice date */  function convert_date ( $date ) {    $date = date ( "DM y H:i:s",                  XMLRPC_convert_iso8601_to_timestamp ( $date ) );    return ( $date );  }  ?>  <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">  <html>  <head>  <title> KD XML RPC News Client </title>  <meta name="Generator" content="EditPlus">  <meta name="Author" content="HarryF">  <meta name="Keywords" content="XML RPC">  <meta name="Description" content="Gets news form server.php">  </head>  <body>  <?php   /* client.php */  /* If user is viewing a single news item, do this */  if ( ISSET ( $_GET['news_id'] ) ) {     /* $success is 0 (fail) / 1 ( succeeded ).       XMLPRC_request preforms the XML POST to       the server script, calling the method and       sending the correct parameters using       XMLRPC_prepare */    list($success, $response) = XMLRPC_request(        $site,        $location,        'news.viewNewsItem',        array(XMLRPC_prepare($_GET['news_id']),        'HarryFsXMLRPCClient')    );     /* If all went well, show the article */    if ($success) {  ?>  <table align="center" width="600">  <tr valign="top">  <th colspan="2"><b><?php echo ( $response['title'] );?></b></th>  </tr>  <tr valign="top">  <th><?php echo ( $response['author'] );?></th>  <th><?php echo ( convert_date ( $response['date'] ) );?></th>  </tr>  <tr valign="top">  <td colspan="2">  <?php echo ( nl2br ( $response['full_desc'] ) );?>  </th>  </tr>  </table>  <?php     /* Else display the error */    } else {        echo ( "<p>Error: " . nl2br ( $response['faultString'] ) );    }  } else {     /* Define the parameters to pass to the XML-RPC    method as a PHP array */    $query_info['limit'] = 10;    $query_info['order'] = "author";     /* XMLRPC_prepare works on an array and    converts it to XML-RPC parameters */    list($success, $response) = XMLRPC_request(        $site,        $location,        'news.getNewsList',        array(XMLRPC_prepare($query_info),        'HarryFsXMLRPCClient')    );     /* On success, display the list as HTML table */    if ($success) {        echo ( "<table align="center" width="600">n" );        $count = 0;        while ( list ( $key, $val ) = each ( $response ) ) {  ?>  <tr valign="top">  <td colspan="2">  <a href="<?php echo ( $_SERVER['PHP_SELF'] );?>?news_id=<?php  echo ( $response[$count]['news_id'] );  ?>">  <?php echo ( $response[$count]['title'] ); ?>  </a>  </td>  </tr>  <tr valign="top">  <td colspan="2">  <?php echo ( $response[$count]['short_desc'] ); ?>  </td>  </tr>  <tr valign="top">  <td>  <?php echo ( $response[$count]['author'] ); ?>  </td>  <td>  <?php echo ( convert_date ( $response[$count]['date'] ) ); ?>  </td>  </tr>  <?php            $count++;        }        echo ( "</table>n" );     /* Or error */    } else {        echo ( "<p>Error: " . nl2br ( $response['faultString'] ) );    }  }  ;?>  </body>  </html> 

Что здесь случилось? Сам код PHP – это просто структура if / else, поэтому, если мы решим просмотреть один элемент новостей с помощью переменной $_GET['news_id'] , мы отобразим этот элемент. В противном случае мы отображаем список новостей.

Для списка новостей мы используем метод news.getNewsList . Обратите внимание, что мы установили для $query_info['limit'] значение 10 (т. $query_info['limit'] Нам нужно максимум 10 новостей), а для $query_info['order'] установлено значение “author” (сортировка новостей по имени автора). Они станут параметрами, которые будут отправлены в запросе клиента XML-RPC.

Когда мы просматриваем один элемент новостей, мы превращаем $_GET['news_id'] в параметр, по которому сервер сможет идентифицировать нужный элемент новостей.

Здесь использовались специальные функции XML-RPC:

  • XMLRPC_prepare() : мы использовали это раньше на сервере, снова, чтобы превратить переменные PHP в параметры XML-RPC. Здесь мы предоставляем серверу данные, необходимые для конкретного метода, который мы используем.
  • MLRPC_request() : эта функция принимает пять переменных и возвращает массив. Это в основном то, что делает ваш клиент клиентом. Принимаются:
    • $site – доменное имя сервера
    • $location – путь на сервере от корневого веб-сервера до сценария сервера
    • $methodName – имя метода XML-RPC, который мы вызываем
    • $params – любая переменная, необходимая для метода
    • $user_agent – необязательный и может быть любым, что вам нравится (например, HarryFsXMLRPCClient).

    Возвращенный массив содержит две переменные. Первый – либо 0 для сбоя, либо 1 для успешного ответа на запрос, который мы используем для проверки ошибок. Второй – это многомерный массив, который содержит все данные из ответа.

  • -XMLRPC_convert_iso8601_to_timestamp : с нашей convert_date() вверху мы используем эту специальную функцию, чтобы изменить формат даты XML-RPC во что-то, что выглядит красиво, с помощью промежуточной временной метки PHP.

Один совет: для написания XML-RPC-клиентов может быть полезно думать о сервере так же, как о базе данных – это просто источник данных. С точки зрения ваших сценариев, код будет аналогичен структуре, которую вы будете использовать при запросе MySQL.

Итак, это все! Направьте свой браузер на http://www.yourdomain.com/kd_xmlrpc/client.php, откиньтесь на спинку кресла и читайте новости.

Загрузите код: все скрипты, используемые в этом руководстве, и таблица MySQL находятся в этом zip-файле .

Заворачивать

Как вы уже видели, используя код XML-RPC Кейта Девенса, довольно легко создать свой собственный веб-сервис. Это отличная отправная точка для знакомства с веб-сервисами. Возможно, как «домашнее задание», вы можете попробовать обновить клиента, чтобы посетители могли выбирать, каким образом они хотят заказывать новости (например, по автору, названию или дате). И если вы чувствуете себя честолюбивым, возможно, вы даже подумаете о добавлении интерфейса к клиенту для INSERT или UPDATE новостей.

Если у вас большие планы на веб-службы, вы можете обратиться к некоторым другим реализациям, таким как класс phpxmlrpc от phpxmlrpc , для оптимизации вашего кода. Но вы определенно можете обойтись без реализации Кейта Девенса, достигнув тех же конечных результатов, что и с любым другим решением.

В коде Кейта есть один или два небольших недостатка, о которых вы должны знать.

Во-первых, XMLRPC_request() используемая клиентом, удаляет «знания», хранящиеся в ответе XML-RPC, о типе каждой переменной, что может привести к дополнительному кодированию для клиента. Например, вы можете ожидать массив, но получите только скалярную (однозначную) переменную – клиенту необходимо иметь дело с обоими обстоятельствами.

Также нет расширения для самоанализа, позволяющего другим разработчикам видеть ваш API (то есть какие методы и параметры принимает ваш сервер). Не должно быть слишком сложно добавить свой собственный самоанализ – просто используйте массив, который мы определили в web_service_api.php.

Наконец, есть только ограниченное положение для отладки. Если ваш единственный интерфейс – клиент, вы можете столкнуться с множеством головных болей, когда речь заходит о том, что делает ваш XML-RPC-сервер. Возможно, вам захочется подумать о создании какого-либо файла журнала для сервера, используя пользовательскую обработку ошибок PHP – посмотрите эту статью, чтобы начать работу с пользовательскими обработчиками ошибок.

Но спасибо Кита Девенсу за отличный код и за то, что он дал нам отличное начало!

Есть пара вопросов, которые мы здесь не рассматривали: безопасность и обработка транзакций.

Если вы хотите немного страха и отвращения, попробуйте эту статью . В отношении безопасности следует учитывать три основных вопроса:

  1. Как вы аутентифицируете клиентов XML-RPC. Если вы добавили методы для INSERT и UPDATE новостей выше, вам также нужно будет найти способ аутентификации удаленного сайта и / или пользователей этого сайта. На данный момент, как вы это делаете, зависит от вас. Вы можете проверить удаленный сайт, используя IP-адрес или имя хоста. Для удаленных пользователей один из подходов заключается в том, чтобы думать о вашем сервере XML-RPC так же, как при проверке пользователей по базе данных, и требовать комбинации имени пользователя и пароля перед тем, как разрешить доступ к чувствительным методам, используя метод исключительно для аутентификации. В идеале, если вы делаете это, вы будете шифровать соединение между клиентом и сервером, используя SSL, но для этого потребуется использовать функции PHP Curl для отправки и получения данных (вам может потребоваться переписать части реализации, которую вы ‘ используется для этого).
  2. Как вы будете контролировать атаки типа «отказ в обслуживании»? Более общий вопрос: что происходит, когда клиент наводняет ваш сервер запросами и мешает ему отвечать другим клиентам?
  3. Какие элементы управления вы размещаете над публикацией вашего API (introspection / WSDL) на уровне описания? Является ли хорошей идеей опубликовать все методы для вашего сервера XML-RPC, чтобы каждый мог “попробовать”? Как вы контролируете, кто что видит? Если ваши методы обеспечивают доступ к конфиденциальным данным, которые обычно хранятся за брандмауэром, вам следует тщательно обдумать.

Что касается обработки транзакций, что произойдет, если вы потеряете соединение между клиентом и сервером во время разговора XML-RPC? Какие механизмы вы предоставляете для обработки повторных попыток (повторная отправка запроса или ответа)? Может случиться так, что вы не можете позволить себе потерять данные для веб-службы, которую вы используете, и в этом случае вам нужно рассмотреть какой-то механизм для очереди запросов и ответов. Для ознакомления с принципами обработки транзакций попробуйте эту статью .

Не беспокойтесь, вы создали свой первый веб-сервис и, надеюсь, получили хорошее представление о том, как работает эта технология. Вопрос сейчас в том, что с этим делать? Публикация новостей – это хорошо, но это было сделано раньше. Что еще там? Мы рассмотрим это в следующем разделе …

Что вы можете сделать с XML-RPC?

Этот вопрос немного похож на вопрос “что я могу сделать с веб-страницей?” Единственным ограничением является ваше воображение. Что вы можете сделать с XML-RPC и PHP в целом, так это расширить свой веб-сайт за пределы простого обслуживания веб-страниц. Ваш сайт сможет передавать данные в любую понравившуюся вам систему, и, приняв и приняв стандарт, вы предоставите интерфейс, с которым другие разработчики будут рады работать.

Веб-сервисы в самом широком смысле будут зарабатывать деньги для тех, кто владеет «ценными данными». Например, если у вас есть прямой доступ к курсам обмена валют, вы можете использовать PHP и XML-RPC для доставки конвертера валют на другие веб-сайты. Но вот некоторые другие идеи и примеры:

  • Предоставьте альтернативного клиента для обновления вашего сайта. Вы когда-нибудь кричали от разочарования, когда вы набирали длинное сообщение в текстовой области HTML, нажимали «Отправить» – и теряли все это из-за истечения времени сеанса или потери соединения с веб-сайтом? XML-RPC может:
    • предоставить вам интерфейс для обновления вашего сайта,
    • позволяют запускать стандартный клиент Windows, чтобы вы могли сохранить свои данные локально на жестком диске, и
    • обновите веб-сайт, когда придет время.
  • ez Systems сделала именно это, предоставив Desktop Edition для своей системы управления контентом ezPublish .
  • Исправьте орфографию на своем веб-сайте с помощью программы проверки правописания в формате Stuffed Dog XML-RPC.
  • Распределите нагрузку и использование полосы пропускания, запустив базу данных на одном веб-сервере, а затем используйте несколько серверов, обеспечивающих пользовательский интерфейс, которые обращаются к базе данных через XML-RPC. Для массовых многопользовательских игр, таких как Planetarion , возможности безграничны.
  • Получите ваш PHP-сайт, говорящий с CGI / Perl или ASP-сайтом, используя одну из многих реализаций XML-RPC, которые позволяют вам сохранить старый код при обновлении до PHP.
  • Воспользуйтесь поисковым шлюзом Google , чтобы результаты поиска появлялись прямо на вашем сайте.
  • POP свою электронную почту повсюду, а затем прочитать все из одного источника XML-RPC с CGI-сервером xr2pop (ОК – Perl, а не PHP – но это хороший пример).
  • Получайте все новости от News is Free, используя свой XML-RPC-сервер .

Возможности безграничны…