Comment puis-je récupérer les données du contenu XML d'une requête SOAP dans un serveur SOAPServer php ?

StackOverflow https://stackoverflow.com//questions/12692797

  •  12-12-2019
  •  | 
  •  

Question

J'essaie de mettre en place un service SOAP en php.J'ai déclaré une fonction php du serveur et je peux appeler cette fonction avec une requête http de type SOAP où le contenu est mon enveloppe SOAP.

Le contenu XML du corps SOAP est l'argument de la fonction que je suppose, mais je ne sais pas comment accéder aux informations qu'il contient dans mon code php.

J'ai remarqué que l'argument de la fonction est une instance de stdClass par défaut, et je me demande en fait pourquoi il n'est pas diffusé sur un XML ou DOM object par php - c'est un appel SOAP, n'est-ce pas ?Mais bon, maintenant c'est à moi d'extraire les informations de l'objet, ce qui n'est pas facile car aucune méthode n'est assignée à stdClass, il faudra donc que ce soient des fonctions php standard.Alors j'ai essayé serialize, mais cela m'a donné des bêtises, pas la chaîne XML à laquelle je m'attendais.

Ce qu'il faut faire?

MODIFIER

notez que ci-dessous ne contient aucun exemple de code de ce que je souhaite faire - obtenir des données détaillées du contenu XML de la requête SOAP - car je ne sais pas comment coder pour l'obtenir à partir de l'objet stdClass

A la demande de David, voici quelques détails.

code php :

<?php
    function mi102($arg) {
        $txt = serialize ($arg);
        $result = new SoapVar ($txt, XSD_ANYXML);
        return($result);
    }
    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("test.wsdl");
    $server -> addFunction ("mi102");
    try {
        $server -> handle();
    }
    catch (Exception $e) {
        $server -> fault ('Client', $e -> getMessage());
    }
?php>

La requête http est construite par une application que j'utilise ;l'en-tête http et l'enveloppe + corps du savon sont générés autour du XML que je lui alimente :

Contenu du corps de la requête SOAP :

<mi102 xmlns="http://pse">
  <cdhead cisprik="21"/>
  <instr>
    <insid>
      <bcdt>20120930</bcdt>
    </insid>
  </instr>
</mi102>

Le WSDL utilisé est le suivant :

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://pse/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="PSE" targetNamespace="http://pse/">
    <types>
        <xs:schema>
            <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
        </xs:schema>
    </types>
    <message name="MI102Req">
        <part name="cdhead" type="tns:cdhead_T"/>
        <part name="instr" type="tns:instr_T"/>
    </message>
    <message name="Res">
        <part name="cdhead" type="tns:cdhead_T"/>
    </message>
    <portType name="MIPortType">
        <operation name="mi102">
            <input message="tns:MI102Req"/>
            <output message="tns:Res"/>
        </operation>
    </portType>
    <binding name="MIBinding" type="tns:MIPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="mi102">
            <soap:operation soapAction="http://testServerURL/test_soap.php#mi102"/>
            <input>
                <soap:body use="literal" namespace="http://pse/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://pse/"/>
            </output>
        </operation>
    </binding>
    <service name="PSE">
        <port name="MIPortType" binding="tns:MIBinding">
            <soap:address location="http://testServerURL/test_soap.php"/>
        </port>
    </service>
</definitions>

Et le XML résultant (encore une fois, extrait du corps SOAP par l'application que j'utilise), est

Réponse SOAP :

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mi102Response xmlns:ns1="http://pse/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">O:8:"stdClass":2:{s:7:"cisprik";i:21;s:7:"version";s:2:"13";}</ns1:mi102Response>

Pas gentil.

Était-ce utile?

La solution

J'ai finalement trouvé la réponse dans d'autres discussions sur SO, comme obtenir-reçu-xml-de-php-soap-server

La solution consiste à utiliser ce qui suit :

$inp = file_get_contents ('php://input');

Note:Je n'ai trouvé aucune fonction pouvant agir sur le stdClass argument d'entrée et peut en récupérer le contenu du corps XML SOAP.
La meilleure option est donc d’utiliser la variable d’entrée php standard.Notez que cela a la structure suivante : Envelope/Body/..inputXML.., qui correspond exactement au contenu de la requête http publiée sur le serveur.

Note: http_get_request_body peut fonctionner aussi, mais mon serveur php ne prend pas en charge cette fonction.je pense que file_get_contents est pris en charge sur chaque serveur php à partir d'une version ultérieure.

Autres conseils

Cela ne sera pas au départ une réponse complète, mais je voulais le formatage.Veuillez préciser ce que vous avez configuré.Généralement, vous disposerez d'une méthode PHP avec des arguments réguliers (et non XML) que vous souhaitez exposer en tant que service Web.Un exemple de base sur la façon de procéder est ici :

http://www.phpeveryday.com/articles/Web-Services-WSDL-Creating-SOAP-Server-P484.html

Le contenu XML du corps SOAP est l'argument de la fonction que je suppose

Non, le contenu XML du corps SOAP est le représentation de la méthode avec vos arguments, mais vos arguments sont ce que vous voulez.Vous ne devriez pas avoir à gérer XML manuellement si vous le configurez avec SoapServer et SoapClient de PHP.

MODIFIER:Vous prenez votre argument, qui est une simple représentation sous forme de tableau PHP du corps de votre requête SOAP, le sérialisez et le renvoyez en réponse (ce que vous observez).Est-ce que c'est ce que tu veux faire ?Vous ne voulez pas faire quelque chose avec les données de la demande ?Pouvez-vous également publier le schéma importé du WSDL ?

Vous avez cette représentation "pas agréable" d'un objet parce que vous renvoyez l'objet sérialisé (la sérialisation convertit l'objet et son état en une représentation sous forme de chaîne).Si vous souhaitez avoir une représentation XML de l'objet renvoyé, vous devez modifier le type de paramètre de retour de votre fonction en objet.Parce que maintenant renvoie une chaîne.

Je vous recommande d'utiliser les composants Zend_Soap_Server et Zend_Soap_Autodiscover du framework zend.

Avec Zend_Soap_Autodiscover vous pouvez générer dynamiquement votre définition de service Web (wsdl), simplement en écrivant les docblocks de vos fonctions.Et Zend_Soap_Server est plutôt cool aussi.

Si vous utilisez ces composants et documentez vos types et votre fonction pour renvoyer un type spécifique sans le sérialiser, alors vous allez recevoir la représentation XML selon la définition wsdl.De plus, chaque type que vous créez est automatiquement converti par Zend_Soap_Autodiscover en ComplexType dans le wsdl généré.

Échantillon:

 public class Person{
         public $id;
         public $name;
    }

    public class MyService {
     /**
     *
     * @param integer $UserID
     * @return Person
     */
    function mi102($UserID) {

         $output = new Person();
         $output->id = 2;
         $output->name = 'Peter';        

        return $output;
    }
}


// Generate WSDL relevant to code
if (isset($_GET['wsdl'])){

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

} else {

    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
    $server->setClass('MyService');
    $server->setObject(new MyService());
    $server->handle();

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top