TigerZF
🌐Español

66.4. AutoDiscovery

66.4.1. Introducción a AutoDiscovery

La funcionalidad de SOAP implementada dentro de Zend Framework tiene como objetivo simplificar todos los pasos necesarios para las comunicaciones SOAP.

SOAP es un protocolo independiente del lenguaje. Por lo tanto, puede utilizarse no solo para comunicaciones PHP-a-PHP.

Existen tres configuraciones para aplicaciones SOAP en las que Zend Framework puede utilizarse:

  1. Aplicación servidor SOAP en PHP <---> aplicación cliente SOAP en PHP
  2. Aplicación servidor SOAP en un lenguaje distinto de PHP <---> aplicación cliente SOAP en PHP
  3. Aplicación servidor SOAP en PHP <---> aplicación cliente SOAP en un lenguaje distinto de PHP

Siempre necesitamos saber qué funcionalidad proporciona el servidor SOAP para poder operar con él. WSDL se utiliza para describir en detalle la API del servicio de red.

El lenguaje WSDL es lo suficientemente complejo (consulte http://www.w3.org/TR/wsdl para más detalles). Por eso resulta difícil preparar una descripción WSDL correcta.

Otro problema es sincronizar los cambios en la API del servicio de red con un WSDL ya existente.

Ambos problemas pueden resolverse mediante la autogeneración de WSDL. Un requisito previo para esto es un servidor de autodetección SOAP. Este construye un objeto similar al objeto utilizado en la aplicación servidor SOAP, extrae la información necesaria y genera el WSDL correcto utilizando esa información.

Hay dos formas de utilizar Zend Framework para una aplicación servidor SOAP:

  • Usar una clase separada.

  • Usar un conjunto de funciones

Ambos métodos son compatibles con la funcionalidad de Autodiscovery de Zend Framework.

La clase Zend_Soap_AutoDiscover también admite el mapeo de tipos de datos de PHP a tipos XSD.

A continuación se muestra un ejemplo de uso común de la funcionalidad de autodetección. La función handle() genera el archivo WSDL y lo envía al navegador.

class My_SoapServer_Class {
...
}

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('My_SoapServer_Class');
$autodiscover->handle();

Si necesita acceder al archivo WSDL generado, ya sea para guardarlo en un archivo o como una cadena XML, puede utilizar las funciones dump($filename) o toXml() que proporciona la clase AutoDiscover.

[Note] Zend_Soap_Autodiscover no es un servidor SOAP

Es muy importante señalar que la clase Zend_Soap_AutoDiscover no actúa como un servidor SOAP por sí misma. Solo genera el WSDL y lo sirve a quien acceda a la url en la que está escuchando.

Como URI del punto de conexión SOAP se utiliza por defecto 'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], pero esto puede cambiarse con la función setUri() o con el parámetro del constructor de la clase Zend_Soap_AutoDiscover. El punto de conexión debe proporcionar un Zend_Soap_Server que escuche las solicitudes.

if(isset($_GET['wsdl'])) {
    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('HelloWorldService');
    $autodiscover->handle();
} else {
    // pointing to the current file here
    $soap = new Zend_Soap_Server("http://example.com/soap.php?wsdl");
    $soap->setClass('HelloWorldService');
    $soap->handle();
}

66.4.2. Autodetección de clases

Si se utiliza una clase para proporcionar la funcionalidad del servidor SOAP, entonces la misma clase debe proporcionarse a Zend_Soap_AutoDiscover para la generación del WSDL:

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->setClass('My_SoapServer_Class');
$autodiscover->handle();

Se utilizan las siguientes reglas durante la generación del WSDL:

  • El WSDL generado describe un servicio web de estilo RPC.

  • El nombre de la clase se utiliza como nombre del servicio web descrito.

  • 'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] se utiliza por defecto como URI donde está disponible el WSDL, pero puede sobrescribirse mediante el método setUri().

    También se utiliza como espacio de nombres de destino para todos los nombres relacionados con el servicio (incluyendo los tipos complejos descritos).

  • Los métodos de la clase se agrupan en un único Port Type.

    $className . 'Port' se utiliza como nombre del Port Type.

  • Cada método de la clase se registra como la operación de puerto correspondiente.

  • Cada prototipo de método genera los mensajes de solicitud/respuesta correspondientes.

    Un método puede tener varios prototipos si algunos de sus parámetros son opcionales.

[Note] ¡Importante!

La autodetección de WSDL utiliza los bloques de documentación (docblocks) de PHP proporcionados por el desarrollador para determinar los tipos de parámetros y de retorno. De hecho, para los tipos escalares, esta es la única forma de determinar los tipos de parámetros, y para los tipos de retorno, esta es la única forma de determinarlos.

Esto significa que proporcionar docblocks correctos y completamente detallados no solo es una buena práctica, sino que es obligatorio para que la clase pueda ser autodetectada.

66.4.3. Autodetección de funciones

Si se utiliza un conjunto de funciones para proporcionar la funcionalidad del servidor SOAP, entonces el mismo conjunto debe proporcionarse a Zend_Soap_AutoDiscovery para la generación del WSDL:

$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->addFunction('function1');
$autodiscover->addFunction('function2');
$autodiscover->addFunction('function3');
...
$autodiscover->handle();

Se utilizan las siguientes reglas durante la generación del WSDL:

  • El WSDL generado describe un servicio web de estilo RPC.

  • El nombre del script actual se utiliza como nombre del servicio web descrito.

  • 'http://' .$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] se utiliza como URI donde está disponible el WSDL.

    También se utiliza como espacio de nombres de destino para todos los nombres relacionados con el servicio (incluyendo los tipos complejos descritos).

  • Las funciones se agrupan en un único Port Type.

    $functionName . 'Port' se utiliza como nombre del Port Type.

  • Cada función se registra como la operación de puerto correspondiente.

  • Cada prototipo de función genera los mensajes de solicitud/respuesta correspondientes.

    Una función puede tener varios prototipos si algunos de sus parámetros de método son opcionales.

[Note] ¡Importante!

La autodetección de WSDL utiliza los bloques de documentación (docblocks) de PHP proporcionados por el desarrollador para determinar los tipos de parámetros y de retorno. De hecho, para los tipos escalares, esta es la única forma de determinar los tipos de parámetros, y para los tipos de retorno, esta es la única forma de determinarlos.

Esto significa que proporcionar docblocks correctos y completamente detallados no solo es una buena práctica, sino que es obligatorio para que la clase pueda ser autodetectada.

66.4.4. Autodetección de tipos de datos

Los tipos de datos de entrada/salida se convierten en tipos del servicio de red utilizando el siguiente mapeo:

  • Cadenas de PHP <-> xsd:string.

  • Enteros de PHP <-> xsd:int.

  • Flotantes y dobles de PHP <-> xsd:float.

  • Booleanos de PHP <-> xsd:boolean.

  • Arrays de PHP <-> soap-enc:Array.

  • Objetos de PHP <-> xsd:struct.

  • Clases de PHP <-> basado en la estrategia de tipo complejo (consulte: esta sección) [29].

  • tipo[] u objeto[] (por ejemplo, int[]) <-> basado en la estrategia de tipo complejo

  • Void de PHP <-> tipo vacío.

  • Si un tipo no coincide con ninguno de estos tipos por algún motivo, entonces se utiliza xsd:anyType.

Donde xsd: es el espacio de nombres "http://www.w3.org/2001/XMLSchema", soap-enc: es el espacio de nombres "http://schemas.xmlsoap.org/soap/encoding/", tns: es el "espacio de nombres de destino" de un servicio.

66.4.5. Estilos de enlace WSDL

WSDL ofrece diferentes mecanismos de transporte y estilos. Esto afecta a las etiquetas soap:binding y soap:body dentro de la sección Binding del WSDL. Diferentes clientes tienen diferentes requisitos en cuanto a qué opciones realmente funcionan. Por lo tanto, puede establecer los estilos antes de llamar a cualquier método setClass o addFunction de la clase AutoDiscover.

$autodiscover = new Zend_Soap_AutoDiscover();
// Default is 'use' => 'encoded' and
// 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'
$autodiscover->setOperationBodyStyle(
                    array('use' => 'literal',
                          'namespace' => 'http://framework.zend.com')
                );

// Default is 'style' => 'rpc' and
// 'transport' => 'http://schemas.xmlsoap.org/soap/http'
$autodiscover->setBindingStyle(
                    array('style' => 'document',
                          'transport' => 'http://framework.zend.com')
                );
...
$autodiscover->addFunction('myfunc1');
$autodiscover->handle();


[29] Zend_Soap_AutoDiscover se creará con la clase Zend_Soap_Wsdl_Strategy_DefaultComplexType como algoritmo de detección para los tipos complejos. El primer parámetro del constructor de AutoDiscover acepta cualquier estrategia de tipo complejo que implemente Zend_Soap_Wsdl_Strategy_Interface o una cadena con el nombre de la clase. Por compatibilidad con versiones anteriores, las variables booleanas $extractComplexType se procesan exactamente igual que en Zend_Soap_Wsdl. Consulte el manual de Zend_Soap_Wsdl sobre cómo agregar tipos complejos para más información.