PHP Soap Server Cómo saber el método llamado

En PHP me gustaría saber cuál será el método llamado por SOAP. Aquí hay una muestra para entender...

$soapserver = new SoapServer();
$soapserver->setClass('myClass');
$soapserver->handle();

Lo que me gustaría saber es el nombre del método que se ejecutará en handle()

¡Gracias!

preguntado el 22 de mayo de 12 a las 16:05

¿Por qué no le echas un vistazo? http://php.net/manual/en/soapserver.handle.php -

@jugnu Ya lo he visto, y esperaba que hubiera otra forma de analizar el XML a mano para encontrar la respuesta (entonces el XML se analizará dos veces para la misma solicitud) -

Para las personas que buscan en Google soluciones de depuración para esta encantadora extensión de PHP, alguien compartió una publicación de blog (¿en SO? ¿las páginas de manual?) con una extensión fantástica, pero sencilla, de SoapServer que ofrece una gran cantidad de información de depuración. Echale un vistazo: blog.mayflower.de/… -

4 Respuestas

En mi opinión, la forma más limpia y elegante de acceder al nombre de la operación llamada en esta situación sería usar algún tipo de Envoltura or Sustituto patrón de diseño. Dependiendo de su intención, usaría el Decorador o apoderado.

Como ejemplo, digamos que queremos agregar dinámicamente alguna funcionalidad adicional a nuestro Handler objeto sin tocar la clase misma. Esto permite mantener la Handler más limpia de clase y, por tanto, más centrada en su responsabilidad directa. Dicha funcionalidad podría ser el registro de métodos y sus parámetros o la implementación de algún tipo de mecanismo de almacenamiento en caché. Para ello utilizaremos el Decorador patrón de diseño. En lugar de hacer esto:

class MyHandlerClass
{
    public function operation1($params)
    {
        // does some stuff here
    }

    public function operation2($params)
    {
        // does some other stuff here
    }
}

$soapserver = new SoapServer(null, array('uri' => "http://test-uri/"));
$soapserver->setClass('MyHandlerClass');
$soapserver->handle();

Haremos lo siguiente:

class MyHandlerClassDecorator
{
    private $decorated = null;

    public function __construct(MyHandlerClass $decorated)
    {
        $this->decorated = $decorated;
    }

    public function __call($method, $params)
    {
        // do something with the $method and $params

        // then call the real $method
        if (method_exists($this->decorated, $method)) {
            return call_user_func_array(
                array($this->decorated, $method), $params);
        } else {
            throw new BadMethodCallException();
        }
    }
}

$soapserver = new SoapServer(null, array('uri' => "http://test-uri/"));
$soapserver->setObject(new MyHandlerClassDecorator(new MyHandlerClass()));
$soapserver->handle();

Si desea controlar el acceso a las operaciones del Controlador, por ejemplo, para imponer derechos de acceso, use el apoderado patrón de diseño.

contestado el 23 de mayo de 12 a las 09:05

Sé que esta es una publicación anterior, pero alguien podría hacer uso de esta solución. Debería ser posible extraer datos de datos HTTP POST sin procesar. No se puede usar $_POST, porque está vacío pero puedes usar una variable predefinida $HTTP_RAW_POST_DATA que contiene una cadena con solicitud SOAP en formato XML.

El nombre del método debe estar en el primer nodo de <soapenv:Body> etiqueta como esta:

<!--
    ...
    XML header, SOAP header etc.
    ...
-->
<soapenv:Body>
   <urn:methodName soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <param1 xsi:type="xsd:string" xs:type="type:string" xmlns:xs="http://www.w3.org/2000/XMLSchema-instance">param1 value</param1>
      <param2 xsi:type="xsd:string" xs:type="type:string" xmlns:xs="http://www.w3.org/2000/XMLSchema-instance">param2 value</param2>
   </urn:methodName>
</soapenv:Body>
<!--
    ...
-->

Probablemente podría analizarlo con algo como SimpleXML o tal vez usar alguna expresión regular para obtener methodName pero recuerda que la cadena urn: es un espacio de nombres definido en el encabezado y, por lo tanto, podría ser cualquier cosa.

Respondido 18 Feb 14, 13:02

Aunque no es la mejor manera, puedes usar esto http://danpolant.com/use-the-output-buffer-to-debug-a-soap-server/ de algun modo.

Para el enfoque rápido y muy sucio (utilice esto solo para una depuración única y no en el código de producción): simplemente asigne una variable global con el nombre de cada método SOAP en los cuerpos del método y haga lo que quiera con él después el SoapServer hace su trabajo, como se describe en el enlace anterior. Algo como esto (código no probado):

$method = "";
class test
{
    function call1()
    {
        global $method; $method = "call1";
    }
}
ob_start();
$soapserver = new SoapServer();
$soapserver->setClass('test');
$soapserver->handle();

$mystring = ob_get_contents(); // retrieve all output thus far
ob_end_clean ();               // stop buffering
log($mystring);                // log output
log($method);                  // log method
echo $mystring;                // now send it

contestado el 22 de mayo de 12 a las 17:05

¡Gracias! Sin embargo, estoy buscando una solución más dinámica para la producción. Sin embargo, esa es una buena manera de ser rápido y fácil :-) ¡Gracias! - Astucia

En este caso, creo que tendrá que investigar un poco más porque, hasta donde yo sé, SoapServer no proporciona esta funcionalidad. De todos modos, hay muchos detalles sobre esta clase que no están documentados y hace 3 años, cuando la estaba usando, terminé investigando el código PHP para controlarlos. - Mihai Todor

Por cierto, para evitar la variable global desordenada en la solución que proporcioné, creo que podría usar un miembro público estático en myClass, que sobrescribe cada vez que se llama a un método. Luego, puede usarlo así: myClass::$myStatic. Si realmente desea implementar la depuración avanzada, tal vez debería considerar extender la clase SoapServer, que es probablemente lo mejor que puede hacer: blog.mayflower.de/archives/… - Mihai Todor

Acabo de ver una extensión aún más simple de la clase SoapServer aquí: php.net/manual/en/soapserver.handle.php#94630 (comentario de Artur Graniszewski) que podrías usar. - Mihai Todor

Usualmente (pero no siempre, depende del cliente) $_SERVER['HTTP_SOAPACTION'] está configurado y puede obtener el nombre del método llamado.

Respondido 04 Feb 13, 15:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.