tobeit: POST-Request, xml als Rückgabe

Hallo zusammen,

im Moment beiß ich mir mal wieder die Zähne aus und zwar an folgendem Problem, ich möchte ein xml abrufen, dass mir ein Webservice generiert, den ich mittels der POST-Methode aufrufe, dazu habe ich folgende Spezifikation ...

POST <Pfad> HTTP/1.1
Host: <Host>
Content-Type: application/x-www-form-urlencoded
Content-Length: <Länge>

<POST-Werte>

---

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: <Länge>

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/"><Rückgabe></string>

Nach einigen Recherchen und ersten Testen hatte ich mir folgendes vorgestellt ...

  
// erzeuge einen neuen cURL-Handle  
$ch = curl_init();  
  
// setze die URL und andere Optionen  
curl_setopt($ch, CURLOPT_URL, $pfad);  
curl_setopt($ch, CURLOPT_HEADER, 0);  
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);  
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);  
  
// führe die Aktion aus und gebe die Daten an den Browser weiter  
$result = curl_exec($ch);  
  
curl_close($ch);  
  
print "<?xml version=\"1.0\" encoding=\"utf-8\"?>";  
print "<string xmlns=\"http://tempuri.org/\">";  
print $result;  
print "</string>";  

... doch die Seite bleibt weiß :( versuche ich den Dienst mittels HTML-Form und/oder direkt über die URL anzusprechen (GET wird gleichermassen unterstützt), funktioniert alles wunderbar!!

Also stellt sich mir die Frage, was mache ich beim Request falsch ...

Scho mal Danke im Voraus

Grüße

tobeit

  1. Hallo,

    <?xml version="1.0" encoding="utf-8"?>
    <string xmlns="http://tempuri.org/"><Rückgabe></string>

    Das ist unvollständig und der tag "<Rückgabe>"ist nicht geschlossen. Du brauchst ein Root-Element like this:

    <?xml version="1.0" encoding="utf-8"?>
    <rootelement>
    <string xmlns="http://tempuri.org/">
    <Rückgabe></Rückgabe>
    </string>
    </rootelement>

    Anstatt
    <tag attr="value"> </tag>
    geht auch: <tag attr="value"/>

    Viele Grüße,
    Hotte

    1. Hi Ihr zwei,

      Du schickst dem Browser das nackte XML als text/html. ENtsprechend interpretiert der es auch: Unbekannte Tags werden ignoriert, unbekannte Attribute ebenfalls - und wenn dann kein darstellbarer Text übrigbleibt, ist die Seite eben weiß.

      Deshalb die prints die das ganze nett verpacken sollen ...

      print "<?xml version="1.0" encoding="utf-8"?>";
      print "<string xmlns="http://tempuri.org/">";
      // hier die Rückgabe ausspucken
      print "</string>";

      ... oder hab ich mir das zu einfach gedacht??

      Das ist unvollständig und der tag "<Rückgabe>"ist nicht geschlossen. Du brauchst ein Root-Element like this:

      Eigentlich steht <Rückgabe> lediglich für den String samt entsprechender Tags stehen, die mir der Request dann liefern sollte ...

      Grüße

      tobeit

      1. Hallo,

        Du schickst dem Browser das nackte XML als text/html. ENtsprechend interpretiert der es auch: Unbekannte Tags werden ignoriert, unbekannte Attribute ebenfalls - und wenn dann kein darstellbarer Text übrigbleibt, ist die Seite eben weiß.

        Deshalb die prints die das ganze nett verpacken sollen ...

        print "<?xml version="1.0" encoding="utf-8"?>";
        print "<string xmlns="http://tempuri.org/">";
        // hier die Rückgabe ausspucken
        print "</string>";

        ... oder hab ich mir das zu einfach gedacht??

        Jo, zu einfach. Du musst _alles_ in Tags packen.
        <?xml version="1.0" encoding="utf-8"?>
        <rootelement>
         <spezi>
          <name>Haselhuhn</name>
          <vname>Horst</name>
          <alias>Hotte</alias>
         </spezi>
        </rootelement>

        Oder so:
        <?xml version="1.0" encoding="utf-8"?>
        <rootelement>
         <spezi name="Haselhuhn" vname="Horst" alias="Hotte"/>
        </rootelement>

        Die Namen der Tags sind frei wählbar aber Case-sensitive! Attribute sind zu quoten.

        Viele Grüße,
        Horst Haselhuhn

        1. *hmpf* ich fühl mich irgendwie unverstanden, also ...

          Wenn mein Request klappt sollte eigentlich in result mein kompletter "Baum" stehen, sowas ungefähr ...

          $result = "<spezi>\n<name>Haselhuhn</name>\n<vname>Horst</name>\n<alias>Hotte</alias>\n</spezi>\n<spezi>\n<name>Beetz</name>\n<vname>Torsten</name>\n<alias>tobeit</alias>\n</spezi>"

          und das will ich dann eigentlich in eine Datei schreiben, aber es scheitert meiner Meinung nach schon am Request :(

          Grüße

          1. Moin!

            *hmpf* ich fühl mich irgendwie unverstanden, also ...

            Du reagierst ja auch nur auf Horst...

            Wenn mein Request klappt sollte eigentlich in result mein kompletter "Baum" stehen, sowas ungefähr ...

            $result = "<spezi>\n<name>Haselhuhn</name>\n<vname>Horst</name>\n<alias>Hotte</alias>\n</spezi>\n<spezi>\n<name>Beetz</name>\n<vname>Torsten</name>\n<alias>tobeit</alias>\n</spezi>"

            und das will ich dann eigentlich in eine Datei schreiben, aber es scheitert meiner Meinung nach schon am Request :(

            Du schreibst es ja aber nicht in eine Datei, sondern schickst es - merkwürdigerweise wieder genauso verpackt, wie deine Datenquelle es sowieso schon liefert - als HTML an den Browser. Das geht wohl schief - oder hast du schon mal den Seitenquelltext der "leeren" Seite im Browser geprüft?

            Wenn dein Request mit CURL schiefgehen würde, würdest du das ja durch die Fehlersignale von CURL merken. Lies mal die Doku dazu!

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hi zusammen,

              wo ist bei der DAS Wurzelelement

              Dies <string xmlns="http://tempuri.org/">...</string> sollte doch als Wurzelelement genügen oder?! Und mein direkter Output wenn ich den Webservice mittels HTML-Formular verwende, sieht auch nich anders aus ...

              1. teste den Reques mit einem bekannten Format (text, html)

              Mit einer php-Datei die ein einfaches "Hello World" ausspuckt, klappt es wunderbar, auch POST-Werte können übermittelt werden ...

              hast du schon mal den Seitenquelltext der "leeren" Seite im Browser geprüft?

              Jepp, der ist auch leer ... also ich hätte zu mindest da etwas zerhacktes erwartet auch wenn ich angeblich nicht die richtigen Header oder XML-Wurzeln verwende ...

              Wenn dein Request mit CURL schiefgehen würde, würdest du das ja durch die Fehlersignale von CURL merken. Lies mal die Doku dazu!

              Seltsamerweise gibt es mir auch keine Fehlermeldungen aus ...

              Grüße

              tobeit

              1. Hellihello tobeit,

                Hi zusammen,

                wo ist bei der DAS Wurzelelement

                Dies <string xmlns="http://tempuri.org/">...</string> sollte doch als Wurzelelement genügen oder?! Und mein direkter Output wenn ich den Webservice mittels HTML-Formular verwende, sieht auch nich anders aus ...

                1. teste den Reques mit einem bekannten Format (text, html)

                Mit einer php-Datei die ein einfaches "Hello World" ausspuckt, klappt es wunderbar, auch POST-Werte können übermittelt werden ...

                mh, wo bitte ist der unterschied von xml zu <html><h1>Textknoten</h1></html> - abgesehen von der Deklaration? Was ist diese PHP-Datei. Ich dachte, Du schreibst mal einfach anderen Text an Stelle des xml-Textes. Xml ist doch auch nur ein String. Was sagt Dein Browser denn sonst so zu xml.

                hast du schon mal den Seitenquelltext der "leeren" Seite im Browser geprüft?

                Jepp, der ist auch leer ... also ich hätte zu mindest da etwas zerhacktes erwartet auch wenn ich angeblich nicht die richtigen Header oder XML-Wurzeln verwende ...

                Wenn dein Request mit CURL schiefgehen würde, würdest du das ja durch die Fehlersignale von CURL merken. Lies mal die Doku dazu!

                Seltsamerweise gibt es mir auch keine Fehlermeldungen aus ...

                Dank und Gruß,

                frankx

                1. Hi,

                  mh, wo bitte ist der unterschied von xml zu <html><h1>Textknoten</h1></html> - abgesehen von der Deklaration? Was ist diese PHP-Datei. Ich dachte, Du schreibst mal einfach anderen Text an Stelle des xml-Textes. Xml ist doch auch nur ein String. Was sagt Dein Browser denn sonst so zu xml.

                  Also nur damit ich jetzt nich auf dem falschen Dampfer bleib, mit cURL kann ich schon rein prinzipiell das erreichen was ich möchte, eine Seite/Skript/Webservice aufrufen und dessen Output zurück erhalten, ohne ihn direkt im Browser auszugeben?!

                  Deshalb mein Testskript zum Rumspielen mit cURL ...

                  Skript/Seite 1:

                    
                  <?php  
                    
                  // erzeuge einen neuen cURL-Handle  
                  $ch = curl_init();  
                    
                  // setze die URL und andere Optionen  
                  curl_setopt($ch, CURLOPT_URL, "http://myserver/blubber.php");  
                  curl_setopt($ch, CURLOPT_HEADER, 0);  
                  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);  
                  curl_setopt($ch, CURLOPT_POSTFIELDS, "mypost=Hello");  
                    
                  // führe die Aktion aus und gebe die Daten an den Browser weiter  
                  $result = curl_exec($ch);  
                  print $result; // zum Testen ausgeben  
                    
                  // schließe den cURL-Handle und gebe die Systemresourcen frei  
                  curl_close($ch);  
                    
                  ?>  
                  
                  

                  Skript blubber.php:

                    
                  <?php  
                    
                  print $_POST["mypost"];  
                    
                  ?>  
                  
                  

                  Was ich eigentlich statt dem print machen möchte, is dann ...

                  $datei_handle = fopen("myxml.xml","w");
                  fwrite( $datei_handle, $result );
                  fclose($datei_handle);

                  Grüße und Danke

                  1. Moin!

                    Also nur damit ich jetzt nich auf dem falschen Dampfer bleib, mit cURL kann ich schon rein prinzipiell das erreichen was ich möchte, eine Seite/Skript/Webservice aufrufen und dessen Output zurück erhalten, ohne ihn direkt im Browser auszugeben?!

                    Es gibt viele Möglichkeiten, das zu tun, cURL ist eine davon.

                    Was ich eigentlich statt dem print machen möchte, is dann ...

                    $datei_handle = fopen("myxml.xml","w");
                    fwrite( $datei_handle, $result );
                    fclose($datei_handle);

                    Warum machst du es dann nicht? Dann könntest du die Datei öffnen und gucken, was drinsteht - anstelle die Rückgabe unsachgemäß in irgendein weiteres XML-Konstrukt zu stecken und dich über eine leere Seite zu wundern.

                    Wenn der Browser einen Server steuert, der einen Server steuert, dann ist das halt eine Ebene mehr, als gewöhnlich. Das sollte berücksichtigt werden. :)

                    - Sven Rautenberg

                    --
                    "Love your nation - respect the others."
                    1. Moin, moin

                      Warum machst du es dann nicht? Dann könntest du die Datei öffnen und gucken, was drinsteht - anstelle die Rückgabe unsachgemäß in irgendein weiteres XML-Konstrukt zu stecken und dich über eine leere Seite zu wundern.

                      gesagt, getan und auch die Datei bleibt, is ja eigentlich auch wurst oder?? Ob ich jetzt den Krempel unformatiert ausspuck, dann hab ich immerhin was zerhacktes oder in ne Datei schreib, es bleib bei dem selben Inhalt, wenn ich nur einen hätte ;) kennt jemand eine gute Doku für cURL, vllt verwend ich das Ding im Zusammenhang mit meinem Webservice nich richtig!!

                      Grüße

                      tobeit

          2. Hello,

            *hmpf* ich fühl mich irgendwie unverstanden, also ...

            einige hier sich wahrscheinlich auch

            Dein Dokument mal etwas eingerückt:
            <spezi>
               <name>
                  Haselhuhn
               </name>
               <vname>
                  Horst
               </name>
               <alias>
                  Hotte
               </alias>
            </spezi>
            <spezi>
               <name>
                  Beetz
               </name>
               <vname>
                  Torsten
               </name>
               <alias>
                  tobeit
               </alias>
            </spezi>
            Auch wenn cih mal von dem Tippfehler </name> = </vname> absehe, wo ist bei der DAS Wurzelelement, dein Dokument besteht aus zwei Elementen, das ist verboten.

            MfG
            Rouven

            --
            -------------------
            sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
            Ambition is the last refuge of failure.  --  Oscar Wilde (Irish Poet, Novelist, Dramatist and Critic, 1854-1900)
          3. Hellihello tobeit,

            *hmpf* ich fühl mich irgendwie unverstanden, also ...

            Wenn mein Request klappt sollte eigentlich in result mein kompletter "Baum" stehen, sowas ungefähr ...

            $result = "<spezi>\n<name>Haselhuhn</name>\n<vname>Horst</name>\n<alias>Hotte</alias>\n</spezi>\n<spezi>\n<name>Beetz</name>\n<vname>Torsten</name>\n<alias>tobeit</alias>\n</spezi>"

            und das will ich dann eigentlich in eine Datei schreiben, aber es scheitert meiner Meinung nach schon am Request :(

            Warum trennst Du die Probleme nicht?

            1. teste den Reques mit einem bekannten Format (text, html)
            2. Kreiere valiedes xml (was mit stylesheet übrigens sehr schön vom Browser angezeigt wird)
            3. Pack beides zusammen.
            Dank und Gruß,

            frankx

  2. Moin!

    ... doch die Seite bleibt weiß :( versuche ich den Dienst mittels HTML-Form und/oder direkt über die URL anzusprechen (GET wird gleichermassen unterstützt), funktioniert alles wunderbar!!

    Du schickst dem Browser das nackte XML als text/html. ENtsprechend interpretiert der es auch: Unbekannte Tags werden ignoriert, unbekannte Attribute ebenfalls - und wenn dann kein darstellbarer Text übrigbleibt, ist die Seite eben weiß.

    Ich halte es allerdings für absolut keine gute Idee, dem Browser nacktes XML zu schicken, du mußt es nett in eine darstellbare HTML-Seite verpacken.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. Moin!

      Ich halte es allerdings für absolut keine gute Idee, dem Browser nacktes XML zu schicken, du mußt es nett in eine darstellbare HTML-Seite verpacken.

      Ich sags mal so: Es ist ein riesen Geficke, aus XML wieder HTML zu machen (mit JavaScript), bei meiner letzten Ajax-Geschichte habe ich dazu einen ganzen Samstag verbraten. Gottseidank hats geregnet und bis zum Glühwein abends auf dem W.Markt war ich aus dem Gröbsten raus ;-)

      Viele Grüße,
      Hotte

      1. Moin Moin!

        Schonmal JSON/JSONRPC probiert? Wesentlich weniger Widerstand ...

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
        1. Moin Moin!

          Schonmal JSON/JSONRPC probiert? Wesentlich weniger Widerstand ...

          gehört schon, aber (noch) nicht probiert.

          Der Winter ist noch lang ;-)

          Viele Grüße,
          Hotte

  3. Eigentlich möcht ich hier ungern als Themenpusher geahntet werden, jedoch hab ich mich noch an eine andere Lösung gewagt und dabei kamen mir eventuelle Fehlerquellen in den Sinn ...

    Hier erstmal der alternative Code:

      
    $handle = fsockopen($host, 80);  
      
    $out = "POST $pfad HTTP/1.1\r\n";  
    $out .= "Host: $host:80\r\n";  
    $out .= "Content-Type: application/x-www-form-urlencoded\r\n";  
    $out .= "Content-Length: ".strlen($request)."\r\n";  
    $out .= "Connection: close\r\n\r\n";  
    $out .= $postdata;  
    fwrite($handle, $out);  
      
    while (!feof($handle))  
            echo fgets($handle,128);  
    fclose($handle);  
    
    

    Lokal getestet, funktioniert der Zugriff einwandfrei, jedoch auf den eigentlichen Webservice angewendet, gibts natürlich wieder Problemchen mit folgenden Meldungen ...

    "Warning: fwrite(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 16

    Warning: feof(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 18

    Warning: fgets(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 19"

    Für mich liegt entsprechend die Vermutung nahe, dass überhaupt keine Connection zu dem Server aufgebaut werden kann, ich bin derzeit dabei zu klären ob ich einen anderen Port und/oder Proxy verwenden muss, wobei mich interessiert, wie gebe ich dabei einen Proxy an oder kümmert sich darum der Browser??

    Grüße

    Ein ratloser tobeit

    1. echo $begrüßung;

      "Warning: fwrite(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 16
      Warning: feof(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 18
      Warning: fgets(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 19"

      Das sind alles Folgefehler, weil du diesen Funktionen ein falsches Argument übergibst. Dieses falsche Argument kommt vom Aufruf von fsockopen(). Diese Funktion liefert im Gutfall eine Ressource, im Fehlerfall ein false zurück. Außerdem kennt sie zwei Parameter um den genauen Wortlaut des Fehlers zu ermitteln.

      Für mich liegt entsprechend die Vermutung nahe, dass überhaupt keine Connection zu dem Server aufgebaut werden kann, ich bin derzeit dabei zu klären ob ich einen anderen Port und/oder Proxy verwenden muss, wobei mich interessiert, wie gebe ich dabei einen Proxy an oder kümmert sich darum der Browser??

      Wild rumstochern kann zum Ergebnis führen. Die Ursache des Fehlverhaltens zu ermitteln kann Irrwege sparen.

      Welcher Browser soll sich um den Proxy kümmern? PHP läuft auf dem Server ab, der steht mitunter am anderen Ende der Welt in einer ganz anderen Netzwerkumgebung. In deinem Fall musst dich selbst darum kümmern, den Proxy anzusprechen. Beispiele dazu gibt es in den Userkommentaren im PHP-Handbuch zu fsockopen().

      Ein ratloser tobeit

      Informiere dich stets nicht nur darüber, wie eine Funktion im Gutfall arbeitet, sondern beachte auch den Fehlerfall und reagiere darauf angemessen. Alle diese Informationen bekommst du im PHP-Handbuch.

      Desweiteren ist es für die Fehlersuche immer von Vorteil, sich die Inhalte von Variablen und Rückgabewerte der verwendeten Funktionen und Ausdrücke anzusehen. echo ist für einfache Fälle angemessen, var_dump() liefert hingegen exaktere Informationen.

      echo "$verabschiedung $name";

      1. Okay ... Entwarnung!!

        Es lag tatsächlich wie vermutet am Proxy, ich muss fsockopen auf den Proxy-Server anwenden, dann funktioniert es!!

        Vielen Dank nochmal an alle die sich viel Mühe gegeben haben mir zu helfen, Ihr seid die Besten :)

        Grüße

    2. Moin!

      Eigentlich möcht ich hier ungern als Themenpusher geahntet werden, jedoch hab ich mich noch an eine andere Lösung gewagt und dabei kamen mir eventuelle Fehlerquellen in den Sinn ...

      Lokal getestet, funktioniert der Zugriff einwandfrei, jedoch auf den eigentlichen Webservice angewendet, gibts natürlich wieder Problemchen mit folgenden Meldungen ...

      "Warning: fwrite(): supplied argument is not a valid stream resource in C:\Program Files\xampp\htdocs\web.php on line 16

      Offensichtlich ist fsockopen() gescheitert. Die Doku sagt:

      "Return Values

      fsockopen() returns a file pointer which may be used together with the other file functions (such as fgets(), fgetss(), fwrite(), fclose(), and feof()). If the call fails, it will return FALSE"

      Der Rest sind Folgefehler.

      Da du den Erfolg von fsockopen() nicht prüfst, rennt dein Programm also hilflos in die Katastrophe. Dabei kannst du nicht nur den Erfolg ermitteln, sondern durch weitere Parameter auch die Fehlerursache ermitteln. Siehe http://www.php.net/fsockopen...

      Für mich liegt entsprechend die Vermutung nahe, dass überhaupt keine Connection zu dem Server aufgebaut werden kann, ich bin derzeit dabei zu klären ob ich einen anderen Port und/oder Proxy verwenden muss, wobei mich interessiert, wie gebe ich dabei einen Proxy an oder kümmert sich darum der Browser??

      Diese Vermutung könntest du ja mal durch Fehlerbehandlung bestätigen oder verwerfen.

      Was die Verwendung eines bestimmten Ports angeht: Das hängt ausschließlich vom Service ab, den du abrufen willst. Wenn der HTTP auf dem Standardport spricht, ist 80 die richtige Wahl. Zumindest bei fsockopen(). Hingegen gehört der Port IMHO NICHT in den HTTP-Host-Header.

      Ob du einen Proxy verwenden mußt, um von deinem Server ins Internet zu kommen, kann ich dir ebensowenig sagen, das mußt du selbst wissen. Frag deinen Netzwerkadministrator, der weiß das.

      Aber wenn ja, dann mußt du die Proxynutzung entsprechend programmieren. Dein Browser kann sich darum gar nicht kümmern, weil der mit dem Service-Server ja gar nicht kommuniziert.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."