Введение в Zend Framework

 Learning Zend Framework

appendix

 Zend Framework Reference


  • Zend_Gdata
  • Zend_Http
  • Zend_InfoCard
  • Zend_Json
  • Zend_Layout
  • Zend_Ldap
  • Zend_Loader
  • Zend_Locale
  • Zend_Log
  • Zend_Mail
  • Zend_Markup
  • Zend_Measure
  • Zend_Memory
  • Zend_Mime
  • Zend_Navigation
  • Zend_Oauth
  • Zend_OpenId
  • Zend_Paginator
  • Zend_Pdf
  • Zend_ProgressBar
  • Zend_Queue
  • Zend_Reflection
  • Zend_Registry
  • Zend_Rest

  • Zend_Search_Lucene
  • Zend_Serializer
  • Zend_Server
  • Zend_Service
  • Zend_Session
  • Zend_Soap
  • Zend_Tag
  • Zend_Test
  • Zend_Text
  • Zend_TimeSync
  • Zend_Tool
  • Zend_Tool_Framework
  • Zend_Tool_Project
  • Zend_Translate
  • Zend_Uri
  • Zend_Validate
  • Zend_Version
  • Zend_View
  • Zend_Wildfire
  • Zend_XmlRpc
  • ZendX_Console_Process_Unix
  • ZendX_JQuery
  • Ttranslation 27.4% Update 2010-11-28 - Revision 23238 - Version ZF 1.11.x

    79.2. Zend_XmlRpc_Client

    79.2.1. Введение

    Zend Framework поддерживает клиентское использование удаленных XML-RPC сервисов через пакет Zend_XmlRpc_Client. Его основные возможности включают в себя автоматическое преобразование типов между PHP и XML-RPC, прокси-объект сервера и доступ к средствам интроспекции на сервере.

    79.2.2. Вызов методов

    Конструктор Zend_XmlRpc_Client принимает URL удаленного XML-RPC сервера в качестве первого параметра. Новый экземпляр класса может использоваться для вызова любых удаленных методов этого сервера.

    Для вызова удаленного метода через клиентa XML-RPC инстанцируйте его и используйте его метод call(). В примере ниже используется демонстрационный XML-RPC сервер на веб-сайте Zend Framework. Вы можете использовать его для тестирования или изучения компонент Zend_XmlRpc.

    Пример 79.1. Вызов метода XML-RPC

    $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    echo 
    $client->call('test.sayHello');

    // hello

    Значение XML-RPC, возвращаемое при вызове удаленного метода, будет автоматически приведено к эквивалентному типу в PHP. В примере выше возвращается строка (тип String в PHP), и она уже готова к применению.

    Первый параметр метода call() принимает имя удаленного метода, вызов которого требуется. Если удаленный метод требует каких-либо параметров, то они могут быть переданы методу call() через второй необязательный параметр в виде массива значений для последующей передачи удаленному методу:

    Пример 79.2. Вызов метода XML-RPC с параметрами

    $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    $arg1 1.1;
    $arg2 'foo';

    $result $client->call('test.sayHello', array($arg1$arg2));

    // возвращаемый результат имеет "родной" для PHP тип

    Если удаленный метод не требует параметров, то этот необязательный параметр можно опустить или передать пустой массив. Массив параметров для удаленного метода может содержать значения "родного" для PHP типа, объекты Zend_XmlRpc_Value, либо и то и другое вместе.

    Метод call() будет автоматически преобразовывать ответ XML-RPC и возвращать его в эквивалентном "родном" для PHP типе. Кроме этого, можно получить объект Zend_XmlRpc_Response для возвращенного значения, вызвав метод getLastResponse() после вызова call().

    79.2.3. Типы и их преобразование

    Некоторые удаленные методы требуют передачи параметров при вызове. Они передаются методу call() объекта Zend_XmlRpc_Client в виде массива во втором параметре. Любой параметр может быть передан в "родном" для PHP типе, который будет автоматически преобразован в соответствующий тип XML-RPC, или как объект, представляющий определенный тип в XML-RPC (один из объектов Zend_XmlRpc_Value).

    79.2.3.1. Параметры в "родном" для PHP типе

    Параметры могут передаваться методу call() как переменные "родного" для PHP типа, это могут быть типы String, integer, float, Boolean, Array или object. В этом случае каждый из этих типов будет автоматически определен и преобразован в один из типов XML-RPC согласно следующей таблице:

    Таблица 79.1. Преобразование типов PHP и XML-RPC

    Тип в PHP Тип в XML-RPC
    integer int
    double double
    boolean boolean
    string string
    array array
    array (ассоциативный) struct
    object array

    [Замечание] Какому типу будет соответствовать пустой массив?

    Передача пустого массива методу XML-RPC несет в себе потенциальную проблему, т.к. он может быть представлен и массивом, и структурой. Zend_XmlRpc_Client в этом случае делает запрос к методу сервера system.methodSignature для определения требуемого типа аргумента и производит соответствующее преобразование.

    Но такое решение само по себе тоже может быть источником проблем. Во-первых, сервера, которые не поддерживают метод system.methodSignature, будут журналировать это как ошибочные вызовы, в этом случае Zend_XmlRpc_Client будет производить преобразование значения к типу array в XML-RPC. Кроме того, это приводит к дополнительным вызовам к удаленному серверу в случае передачи аргументов в виде массивов.

    Для того, чтобы полностью отключить эти вызовы, вы можете вызвать метод setSkipSystemLookup() до собственно запроса к методу XML-RPC:

    $client->setSkipSystemLookup(true);
    $result $client->call('foo.bar', array(array()));

    79.2.3.2. Параметры в виде объектов Zend_XmlRpc_Value

    Параметры могут также создаваться как экземпляры Zend_XmlRpc_Value для точного указания типа XML-RPC. Основные причины для этого:

    • Вы хотите быть уверенными в том, что процедуре передается корректный тип параметра (т.е. процедура требует целочисленное значение, а вы можете получать его из БД в виде строки)

    • Удаленная процедура требует тип base64 или dateTime.iso8601 (которых нет среди "родных" для PHP типов).

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

    Есть два способа создания объектов Zend_XmlRpc_Value ― непосредственное инстанцирование одного из подклассов Zend_XmlRpc_Value и использование статического фабричного метода Zend_XmlRpc_Value::getXmlRpcValue().

    Таблица 79.2. Объекты Zend_XmlRpc_Value для типов XML-RPC

    Тип XML-RPC Константа Zend_XmlRpc_Value Объект Zend_XmlRpc_Value
    int Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER Zend_XmlRpc_Value_Integer
    double Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE Zend_XmlRpc_Value_Double
    boolean Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN Zend_XmlRpc_Value_Boolean
    string Zend_XmlRpc_Value::XMLRPC_TYPE_STRING Zend_XmlRpc_Value_String
    base64 Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64 Zend_XmlRpc_Value_Base64
    dateTime.iso8601 Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME Zend_XmlRpc_Value_DateTime
    array Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY Zend_XmlRpc_Value_Array
    struct Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT Zend_XmlRpc_Value_Struct

    [Замечание] Автоматическое преобразование

    Когда создается новый объект Zend_XmlRpc_Value, его значение устанавливается в "родном" для PHP типе. Тип в PHP будет преобразован к определенному типу средствами PHP. Например, если в качестве значения для объекта Zend_XmlRpc_Value_Integer была передана строка, то она будет преобразована через (int)$value.

    79.2.4. Прокси-объект сервера

    Другим способом вызова удаленных методов через клиента XML-RPC является использование "заместителя" сервера. Это PHP-объект, который предоставляет интерфейс к удаленному пространству имен XML-RPC, делая работу с ним максимально близкой к работе с обычным объектом в PHP.

    Для того, чтобы инстанцировать "заместителя" сервера, вызовите метод getProxy() объекта Zend_XmlRpc_Client. Он вернет объект класса Zend_XmlRpc_Client_ServerProxy. Любые вызовы методов прокси-объекта сервера будет перенаправлены к удаленному серверу, параметры могут передаваться так же, как и для любых других методов в PHP.

    Пример 79.3. Прокси-объект к пространству имен по умолчанию

    $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    // Создание прокси-объекта к пространству имен по умолчанию
    $server $client->getProxy();

    $hello $server->test->sayHello(12);
    // test.Hello(1, 2) возвращает "hello"

    Метод getProxy() принимает необязательный аргумент, указывающий, к какому пространству имен следует создать прокси-объект. Если этот аргумент не был указан, то то будет использоваться пространство имен по умолчанию. В следующем примере используется пространство имен test:

    Пример 79.4. Прокси-объект к произвольному пространству имен

    $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    // Создание прокси-объекта к пространству имен "test"
    $test  $client->getProxy('test');

    $hello $test->sayHello(12);
    // test.Hello(1,2) возвращает "hello"

    Если удаленный сервер поддерживает сколько угодно вложенные пространства имен, то они также могут использоваться через прокси-объект сервера. Например, если сервер в примере выше имеет метод test.foo.bar(), то он может вызываться следующим образом: $test->foo->bar().

    79.2.5. Обработка ошибок

    При вызове методов XML-RPC могут могут быть ошибки двух типов: HTTP и XML-RPC. Zend_XmlRpc_Client распознает оба типа, позволяя обнаруживать и отлавливать их независимо друг от друга.

    79.2.5.1. Ошибки HTTP

    Если произошла ошибка HTTP - например, удаленный HTTP-сервер вернул код 404 Not Found, - то будет сгенерировано исключение Zend_XmlRpc_Client_HttpException.

    Пример 79.5. Обработка ошибок HTTP

    $client = new Zend_XmlRpc_Client('http://foo/404');

    try {

        
    $client->call('bar', array($arg1$arg2));

    } catch (
    Zend_XmlRpc_HttpException $e) {

        
    // $e->getCode() возвращает 404
        // $e->getMessage() возвращает "Not Found"

    }

    Независимо от того, какой клиент XML-RPC используется, всякий раз, когда происходит ошибка HTTP, генерируется исключение Zend_XmlRpc_Client_HttpException.

    79.2.5.2. Ошибки XML-RPC

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

    Если используется метод call() или прокси-объект сервера, то ошибка XML-RPC приведет к тому, что будет сгенерировано исключение Zend_XmlRpc_Client_FaultException. Код и сообщение исключения будут в точности соответствовать значениям в возвращенном ответе с сообщением об ошибке.

    Пример 79.6. Обработка ошибок XML-RPC

    $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    try {

        
    $client->call('badMethod');

    } catch (
    Zend_XmlRpc_FaultException $e) {

        
    // $e->getCode() возвращает 1
        // $e->getMessage() возвращает "Unknown method"

    }

    Если для выполнения запроса используется метод call(), то в случае ошибки будет сгенерировано исключение Zend_XmlRpc_FaultException. Объект Zend_XmlRpc_Response, содержащий возвращенную ошибку, можно также получить через метод getLastResponse().

    Если для выполнения запроса используется метод doRequest(), то исключение не генерируется. Вместо этого будет возвращен объект Zend_XmlRpc_Response, содержащий возвращенную XML-RPC ошибку. Проверить, содержит ли объект ошибку, можно через метод isFault() объекта Zend_XmlRpc_Response.

    79.2.6. Интроспекция сервера

    Некоторые XML-RPC сервера поддерживают интроспекцию методов под пространством имен system.. Zend_XmlRpc_Client предоставляет специальную поддержку для серверов с этой возможностью.

    Экземпляр Zend_XmlRpc_Client_ServerIntrospection может быть получен через вызов метода getIntrospector() класса Zend_XmlRpcClient. Далее он может использоваться для выполнения операций интроспекции на сервере.

    79.2.7. От запроса к ответу

    Метод call() экземпляра Zend_XmlRpc_Client в процессе выполнения строит объект запроса (Zend_XmlRpc_Request) и передает его другому методу doRequest(), который возвращает объект ответа (Zend_XmlRpc_Response).

    Метод doRequest() также доступен для непосредственного использования:

    Пример 79.7. Выполнение запроса

    $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    $request = new Zend_XmlRpc_Request();
    $request->setMethod('test.sayHello');
    $request->setParams(array('foo''bar'));

    $client->doRequest($request);

    // $server->getLastRequest() возвращает экземпляр Zend_XmlRpc_Request
    // $server->getLastResponse() возвращает экземпляр Zend_XmlRpc_Response

    После того, как через клиента был вызван метод XML-RPC (через методы call(), doRequest() или через прокси-объект сервера), всегда можно получить объекты последнего запроса и ответа на него через методы getLastRequest() и getLastResponse() соответственно.

    79.2.8. HTTP-клиент и тестирование

    Ни в одном из предыдущих примеров не указывался HTTP-клиент. В этом случае создается новый экземпляр Zend_Http_Client с настройками по умолчанию и автоматически используется клиентом Zend_XmlRpc_Client.

    HTTP-клиент может быть получен в любое время через метод getHttpClient(). В большинстве случаев достаточно использование HTTP-клиента по умолчанию. Тем не менее, метод setHttpClient() позволяет установить HTTP-клиент, отличный от принятого по умолчанию.

    setHttpClient() может быть полезен при unit-тестировании. При совместном использовании с Zend_Http_Client_Adapter_Test можно имитировать удаленные сервисы для тестирования. В качестве примера реализации рассмотрите unit-тесты для Zend_XmlRpc_Client, входящие в поставку Zend Framework.

    digg delicious meneame google twitter technorati facebook

    Comments

    Loading...