POST-Request, xml als Rückgabe
tobeit
- php
0 Horst0 Sven Rautenberg0 Horst0 Alexander (HH)0 Horst
0 tobeit1 dedlfix
0 tobeit
1 Sven Rautenberg
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
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
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
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
*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
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
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 ...
- 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
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 ...
- 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
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
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
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
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
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
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
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
Moin Moin!
Schonmal JSON/JSONRPC probiert? Wesentlich weniger Widerstand ...
Alexander
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
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
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";
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
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