PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Post und Get unter PHP


Bedman
2002-02-16, 22:54:02
Hi Leute,

ich hab ein kleines Problem. Ich möchte an ein Skript (Perl) meine Daten schicken. Leider versteht dieses Skript nur Post und nicht Get. Diese Daten müssen aber an 2 Skripts geschickt werden. Wie kann ich zum Beispiel mit einer Aktion (Submit-Button) 2 verschiedene Skripte ausführen, oder wie schaffe ich es einen GET-String an die POST-Variable des Scripts zu schicken?

Bedman

barracuda
2002-02-17, 00:22:16
IMHO geht beides nicht. Kannst Du nicht versuchen, aus den beiden Skripten eins zu machen?

Captain America
2002-02-17, 02:15:59
Sicher geht das.

Schick die Daten ganz normal an das PHP-Skript. Innerhalb des PHP-Skriptes simulierst du dann einen Browser, der per Post die Daten an das Perl-Skript schickt.



// Hier Daten prüfen, ggf fehlermeldung ausgeben

// Formatier die Daten genau so wie im Get-String, oder nimm den Get-String selbst
$data = "var1=" . urlencode($var1) . "&var2=" . urlencode($var2);

$fp = fsockopen("www.bla.com", 80);
fputs($fp, "POST /skript.pl HTTP/1.0\r\n");
fputs($fp, "Content-Length: " . strlen($data) . "\r\n");
fputs($fp, "\r\n");
fputs($fp, $data);

$result = "";

while(!feof($fp))
{
$result .= fread($fp, 1024);
}

fclose($fp);



Hab ich nicht live getestet, aber so geht das auf jeden Fall.

Bedman
2002-02-17, 12:37:42
He danke, ich checks mal aus. Aber da ich noch ein Rookie in PHP bin, wäre es cool wen du mir noch ein paar Erläuterungen zu dem Skript geben könntest.

Thx Bedman

Captain America
2002-02-17, 19:56:14
Oh ja. Ich erkläre es dir sehr Ausführlich =) Dieser Text wird evtl für php-labor.at verwendung finden, mal schauen.

Um das Skript wirklich verstehen zu können, muss man wissen wie HTTP-Requests funktionieren. Und das bringt uns zu einer Frage, die sich jeder junge Mann in seinem Leben gestellt haben sollte:

Was passiert eigentlich, wenn ich in meinem Browser eine URL eintippe und Enter drücke?

Ganz einfach, der Browser schickt einen HTTP-Request (Request = Anfrage) ab. Dieser Request besteht aus stinknormalem Text, ist also von Menschen ohne weiteres lesbar, und hat ein ebenfalls sehr simples Format:


HTTP-Methode Pfad HTTP-Version[CR][LF]


HTTP-Methode ist GET, POST, etc.

Pfad ist das Dokument das Angefordert wird, z.b. /abc/def.html

HTTP-Version ist entweder HTTP/1.0, oder HTTP/1.1.

[CR][LF] ist der Zeilenumbruch unter Windows (Carriage-Return / Linefeed, geschrieben als "\r\n" in PHP).

Schauen wir uns ein mal einen simplen GET-Aufruf an, der das Dokument /index.html anfordert:


GET /index.html HTTP/1.1


Zusätzlich zu dieser Request-Line kann der Browser auch noch weitere Daten mitsenden, die sogenannten Request-Header. Diese können bestimmte Informationen beinhalten wie z.B. die Browser-Version, oder welche Sprache der Browser gerne haben möchte falls Dokumente mehrsprachig vorliegen. Request-Header haben folgendes Format:


Header-Name: Wert[CR][LF]


Man kann sich den Header-Namen nicht einfach so aussuchen, welche Header-Namen es gibt ist in der HTTP-Spezifikation festgehalten. Das alles zu erklären würde jetzt aber den Rahmen sprengen.

Hier ein Beispiel, bei dem aus dem HTTP-Request ersichtlich wird, mit welchem Browser das Dokument aufgerufen wird. Der Header wird einfach in einer neuen Zeile unter die Request-Line geklatscht.


GET /index.html HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)


OK, so weit so gut. Ich möchte noch einmal an einem realen Beispiel zeigen, was bei einem HTTP-GET passiert.

0.) Hein Spack gibt in seinen Browser "http://www.forum-3dcenter.org/vbulletin/" ein
1.) Der Browser öffnet eine Verbindung zu www.forum-3dcenter.org
2.) Über diese Verbindung schickt der Browser folgenden Text:


GET /vbulletin/ HTTP/1.1
Host: www.forum-3dcenter.org
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)


3.) Der Webserver auf www.forum-3dcenter.org hat diesen Request gelesen, und schickt das HTML-Dokument - wieder als Klartext - zurück an den Browser.


Einfach, nich? =)

So, ich rocke jetzt erst mal zum Kiosk und hole mir nen Eistee! Ich bin gleich zurück, und erkläre in Teil 2 wie man einen Post aufbauen muss. Bis gleich!

Bedman
2002-02-17, 22:46:33
ok das klingt schon mal alles sehr interessant! Aber was ist ein Browser ;-)
Erklär es einfach einen Informatiker der sich seit neusten mit PHP beschäftigt. Ich hab durch www.selfphp3.com schon mal rausgefunden was das skript so anstellt. Erklär mir nur die letzte while Schleife und was wichtig am ersten Teil des Skripts ist (wo man drauf achten muß)
he du hast was gut bei mir!

Bedman

Captain America
2002-02-19, 22:36:22
Und weiter gehts. Wie gesagt, der Text wird woanders noch verwurstet, deshalb so Kilometerlang. :D Trotzdem halte ich Wissen über HTTP für essentiell, es ist enorm Hilfreich wenn man mit PHP arbeitet. Im 3. Teil erklär ich dann was das Skript macht.

Eine Sache muss ich vorher noch nachreichen: wer noch nicht total abgestumpft von dauerhaftem Zocken ist, wird bemerkt haben, dass der letzte Request einen Header "Host" hat. Dieser Header muss immer angegeben werden. Der Wert des Headers ist die Domain, zu der die Verbindung aufgebaut wurde.

Der kürzeste Request ist somit:


GET / HTTP/1.1
Host: www.domain.tld


OK, und nun zu POST. GET hatte Bisher eine Request-Line und mindestens einen Request-Header. Bei POST kommt noch der Request-Body hinzu. Er kommt nach dem letzten Header, ist aber zusätzlich durch eine Leerzeile - wie in HTTP üblich [CR][LF] - getrennt.


POST / HTTP/1.1[CR][LF]
Host: www.domain.tld[CR][LF]
[CR][LF]
Hallo, ich bin ein Request-Body! Mein Format kann jede Form haben.


Der Request-Body selbst hat am Ende kein Extra-[CR][LF].

Das Beispiel oben ist für die Praxis unnütz, denn der Request-Body hat kein Sinnvolles Format. Was man in der Regel braucht, ist ein Request-Body der nach application/x-www-form-urlencoded kodiert ist. Hinter diesem schwer zu merkenden Namen steckt ein einfacher Mechanismus Daten zu formatieren.

Dieses HTML-Formular soll zeigen, wie die Daten kodiert werden:


<FROM action="http://www.test.bla/test.php" method="POST" enctype="application/x-www-form-urlencoded">

var1: <INPUT type="text" name="var1"><BR>
var2: <INPUT type="text" name="var2"><BR>
<INPUT type="submit" value="Abschicken">

</FORM>


Dieser Codeschnipsel stellt ein HTML-Formular mit 2 Textfeldern dar, sie haben die Namen var1 und var2. Wenn man nun in das erste Feld "PHP", und in das zweite "rocks" schreibt und auf "Abschicken" klickt, dann wird der Browser so einen Request abschicken:


POST /test.php HTTP/1.1
Host: www.test.bla
Content-Type: application/x-www-form-urlencoded

var1=PHP&var2=rocks


Variablennamen und Werte werden durch ein '=' getrennt, und einzelne Wertepaare durch '&':


var1=wert1&var2=wert2&varn=wertn



OK, und jetzt gehts ans PHP-Skript.

Captain America
2002-02-19, 23:01:35
/* Dies sind die Daten, die du an das Perl-Skript schickst. Sie
werden nach application/x-www-form-urlencoded bearbeitet. Das ist
also der Request-Body.

Die Funktion urlencode() ist nötig, um Zeichen wie und '&' zu
ersetzen. Ansonsten wüsste ja niemand ob das '&' aus der Variablen
kommt, oder ein Trennzeichen ist. */

$data = "var1=" . urlencode($var1) . "&var2=" . urlencode($var2);



/*

fsockopen() öffnet eine Verbindung zu dem Server, auf dem das Script
liegt. Halt dir diese Tatsache noch mal vor Augen: du öffnest eine
Verbindung zum SERVER, nicht zum SKRIPT.

Die Verbindung wird in $fp gespeichert.

*/

$fp = fsockopen("www.bla.com", 80);


/* Nun schreibst du in $fp die Request-Line, abgeschlossen durch
\r\n. Die Funktion fputs() (file put string) ist zum schreiben in
eine geöffnete Verbindung. */

fputs($fp, "POST /skript.pl HTTP/1.1\r\n");

/* Nach der Request-Line kommen die 2 nötigen Header: Host und
Content-Type. */

fputs($fp, "Host: www.bla.com\r\n");
fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");

/* Es ist ein guter Stil, den Header Content-Length anzugeben. Sein
wert ist die Länge des Request-Body's in Bytes. */

fputs($fp, "Content-Length: " . strlen($data) . "\r\n");

/* Eine Leer-Zeile trennt Request-Header vom Request-Body */

fputs($fp, "\r\n");

/* Und nun wird der Request-Body geschrieben */

fputs($fp, $data);


/* Nachdem der Request komplett gesendet wurde, ist es Zeit die Seite
die der Webserver auf letzteren hin erzeugt zu lesen.

In der Variablen $result wird die Seite gespeichert. */

$result = "";

/* Solange die Verbindung $fp nicht am Dateiende angelangt ist
(feof; file end of file; gibt true zurück wenn man noch weiter mit
fread() lesen kann, und false wenn das Dateiende erreicht ist), soll
mit fread() gelesen werden, und das Ergbenis an die Variable $result angehangen
werden. */

while(!feof($fp))
{
$result = $result . fread($fp, 1024);
// Kürzer: $result .= fread($fp, 1024);
//
// $a = $a . $b;
// entspricht
// $a .= $b;
}

/* Sobald feof() true zurückgibt, die Verbindung schliessen */

fclose($fp);





Wenn var1=PHP und var2=rocks, dann hast du folgendes an www.bla.com geschrieben:


POST /skript.pl HTTP/1.1
Host: www.bla.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 19

var1=PHP&var2=rocks


OK, ich hoffe dir wird jetzt klar was abgeht. Mit diesem Codeschnipsel hast du sozusagen ein Formular aus PHP abgeschickt.

Formular
&darr;
PHP
&darr;
Perl

Beide Skripte haben nun die Daten. Noch Fragen?

Unregistered
2002-02-19, 23:39:22
He danke, da habsch mal wieder was gelernt. Nun muß ich morgen nur noch Numerik schreiben und dann gehts gleich ans ausprobieren.

Vielen Dank nochmal für die prompte Antwort!!!

Ciao Bedman