php.exe POST und GET Daten übergeben
int21h
- php
Hi,
Mit der php.exe kann man ja eine PHP-Datei parsen lassen und das Ergebnis auf stdout ausgeben lassen (php -f file.php).
Bei einer normalen Datei klappt das auch wunderbar, nur Frage ich mich, wie ich nun einen QUERY_STRING oder die POST-Daten mitparsen lassen kann? (Sprich: Das Programm arbeitet z.B mit $_GET["var"] oder $_POST["var"]
Ich wäre für jede Hilfe sehr dankbar!
Hi!
Mit der php.exe kann man ja eine PHP-Datei parsen lassen und das Ergebnis auf stdout ausgeben lassen (php -f file.php).
Ja. Aber das ist für den reinen Einsatz in der Kommandozeile gedacht, nicht als eigenständiger Webserver oder sowas.
Bei einer normalen Datei klappt das auch wunderbar, nur Frage ich mich, wie ich nun einen QUERY_STRING oder die POST-Daten mitparsen lassen kann? (Sprich: Das Programm arbeitet z.B mit $_GET["var"] oder $_POST["var"]
Die Frage ist eher, wie kommt der Query-String vom Client zum PHP-Script? Wie willst Du denn Dein Script aufrufen? Mit dem Browser geht das nur über eie Webserver, und da bekommst Du von diesem auch die $_POST und $_GET Arrays zur Verfügng gestellt, nicht so beim Einsatz der CLI-Version von PHP.
Siehe auch:
http://de3.php.net/manual/de/features.commandline.php
Wenn Du ein PHP-Script über die Shell aufrufst, kannst Du diesem Argumente übergeben, siehe:
http://www.dclp-faq.de/q/q-php-shell.html
Wenn ein Script GET und POST Variablen verwendet ist es sicherlich einmal für eine Webserver-Umgebung und nicht für eine Shell-Umgebung geschrieben worden.
Grüße
Andreas
Die Frage ist eher, wie kommt der Query-String vom Client zum PHP-Script? Wie willst Du denn Dein Script aufrufen? Mit dem Browser geht das nur über eie Webserver, und da bekommst Du von diesem auch die $_POST und $_GET Arrays zur Verfügng gestellt, nicht so beim Einsatz der CLI-Version von PHP.
Das genau is ja das Problem. Ich schreibe mir gerade einen eigenen Webserver. Und wenn eine *.php Datei angefordert wird. dann wollte ich "einfach" die angeforderte Datei an den PHP-Parser (php.exe) übergeben, dass Ergebnis von stdoud des Parser abfangen und mittels
HTTP zurücksenden. Nur weiss ich nicht, wie ich das mit GET und POST machen soll. Der QUERY_STRING wird ja nur in der Umgebungsvariable
abgelegt und die POST-Daten stehen dem Script als STDIN zur Verfügung. Nur weiß ich eben nicht, wie ich dass alles mittels php.exe parsen kann.
Hallo!
Das genau is ja das Problem. Ich schreibe mir gerade einen eigenen Webserver.
Ah, so ist das! Das rückt die Frage natürlich in ein ganz anderes Licht ;-)
Und wenn eine *.php Datei angefordert wird. dann wollte ich "einfach" die angeforderte Datei an den PHP-Parser (php.exe) übergeben, dass Ergebnis von stdoud des Parser abfangen und mittels
HTTP zurücksenden. Nur weiss ich nicht, wie ich das mit GET und POST machen soll. Der QUERY_STRING wird ja nur in der Umgebungsvariable
abgelegt und die POST-Daten stehen dem Script als STDIN zur Verfügung. Nur weiß ich eben nicht, wie ich dass alles mittels php.exe parsen kann.
Da bin ich ehrlich gesagt etwas überfragt, da ich mich hiermit noch nicht beschäftigt habe. Was Du auf alle Fälle brauchst ist eien Schnittstelle zu PHP, da es für Deinen Server vermutlich noch kein PHP-Modul gibt, musst Du PHP über CGI ansprechen. Hierzu musst Du halt die CGI-Spezifikation lesen und entsprechend implementieren, denke ich.
Versuchs mal hier:
http://hoohoo.ncsa.uiuc.edu/cgi/
Wenn ich http://hoohoo.ncsa.uiuc.edu/cgi/interface.html richtig deute funktioniert das ganze z.B. bei einem POST Request ganz grob so:
0. Ein Client sendet eine Anfrage an ein PHP-Script per POST
1. Du setzt die Umgebungsvariablen entsprechend der CGI-Spezifikation
2. Du schickst den Query-String an stdin von php.exe mit dem Dateinamen als Argument
3. Du liest die Ausgabe von PHP
4. Du erzeugst die fehlenden Header
5. Du schickst alles zusammen an den Client zurück
Mit welcher Programmiersprache schreibst Du den Web-Server?
Mit ist nicht ganz so klar wie PHP die GET-Parameter bekommt, ich vermute mal dass PHP versucht die aus den entsprechenden Umgebungsvariablen nach CGI-Spezifikation selbst auszulesen und in den Array zu schreiben, naja, wie gesagt, "ich vermute" ;-)
Außerdem bin ich nicht so sicher wo die Umgebungsvariablen gesetzt werden.
Grüße
Andreas
Mit welcher Programmiersprache schreibst Du den Web-Server?
Den Webserver schreibe ich komplett in Java (1.4.2). Die Standardfunktionen funktionieren bereits, nur dass parsen von php files klappt nicht. Mittlerweile denke ich, dass das einlesen des QUERY_STRINGs oder der POST Daten in einem Script beim parsen mit php.exe überhaupt nicht geht. :(
Trotzdem vielen Dank für deine Hilfe!
Hi!
Den Webserver schreibe ich komplett in Java (1.4.2).
Ah.
Die Standardfunktionen funktionieren bereits, nur dass parsen von php files klappt nicht. Mittlerweile denke ich, dass das einlesen des QUERY_STRINGs oder der POST Daten in einem Script beim parsen mit php.exe überhaupt nicht geht. :(
Doch, Apache & Co. machen das ja auch irgendwie, und man gibt bei der CGI-Version ja nur den Pfad zur binary-File an, der werden dann die Daten übergeben, auf welche Weise auch immer, vermutlich über eine bidirektionale pipe. CGI ist ja standardisiert, das heißt das PHP im Prinzip mit jedem Webserver laufen müsste, der CGI unterstützt, und eben das musst Du mit Deinem Webserver hinbekommen.
Ich weiß jetzt allerdings nicht wie gut das mit Java geht. Die Übergabe von GET-Parametern passiert soweit ich das jetzt weiß wirklich über die Umgebungsvariablen, die man z.B. in PHP mit setenv() setzt, in Java kenne ich keine solche Funktion. Jedenfalls müsste PHP dann theoretisch diese Umegebunsvariable(QUEREY_STRING) automatisch analysieren und entsprechend den $_GET Array mit den Werten füllen. Vermutlich braucht PHP aber mehr als einen Wert um überhaupt was zu machen, ich würde schon alle Umgebungsvariablen setzen so wie
hier: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
und hier: http://de3.php.net/manual/de/install.commandline.php#install.commandline.using-variables
beschrieben.
Ich denke dass es Sache des Servers ist den genauen Pfad des angeforderten Scriptes zusammenzusetzen(document-root + URL-Pfad), und soweit ich das weiß wird eben dieser absolute Pfad zum Script als Argument an den Interpreteraufruf angehängt, und nicht als Umgebungsvariable übermittelt.
Aber vielleicht solltest Du mal einen Blick in den Quelltext eines möglichst einfachen Webservers werfen, z.B. http://hoohoo.ncsa.uiuc.edu/docs/setup/Compilation.html#get_source bei mir bekomme ich das irgendwie gerade nicht entpackt, aber das sind nur 300 KB, da sollte man den Teil bzgl. CGI doch finden und dann siehst Du wie es geht, wenn auch vemtulich in einer anderen Sprache.
Grüße
Andreas
Ich bin schon ein gutes Stück weiter, und weiß jetzt, dass ich die POST Daten mit einer Pipe in das Script bringen kann (echo POSTDATEN | php file.php) und für die GET Daten setze ich eine Umgebungsvariable. Im Script kann ich auch bereits auf die Daten mittels $_ENV['QUERY_STRING'] und $fp = fopen("C://stdin", "r") zugreifen. Nur funktionieren die Arrays $_GET[] und $_POST immer noch nicht. Meine einzige Frage is nun, wie fülle ich diese Arrays?
Hi!
Ich bin schon ein gutes Stück weiter, und weiß jetzt, dass ich die POST Daten mit einer Pipe in das Script bringen kann (echo POSTDATEN | php file.php)
Das würde ich nicht machen, die POST-Daten können schonmal etwas größer sein und dann kannst Du so probleme bekommen (ist mir mal passiert). ich würde eine bidirektionale pipe öffnen, so dass Du direkt auf STDIN schreiben kannst, und STDOUT auslesen.
und für die GET Daten setze ich eine Umgebungsvariable. Im Script kann ich auch bereits auf die Daten mittels $_ENV['QUERY_STRING'] und $fp = fopen("C://stdin", "r") zugreifen. Nur funktionieren die Arrays $_GET[] und $_POST immer noch nicht. Meine einzige Frage is nun, wie fülle ich diese Arrays?
AFAIK erstellt PHP diese Arrays mit Hilfe der gesetzten Umgebungsvariablen. Ich würde mir mal den PHP-Source ansehen, das hae ich gerade mal gemacht.
Z.B. findest Du da solche Dinge in der Datei cgi_main.c im Verzeichnis cgi in Zeile 983:
/* Make sure we detect we are a cgi - a bit redundancy here,
but the default case is that we have to check only the first one. */
if (getenv("SERVER_SOFTWARE")
|| getenv("SERVER_NAME")
|| getenv("GATEWAY_INTERFACE")
|| getenv("REQUEST_METHOD")) {
cgi = 1;
}
Das heißt obige Variablen müssen (korrekt) gesetzt sein, da PHP sonst nicht versucht wie in der CGI-spec. auf die Umgebungsvariablen zuzugreifen. Was Du machst ist PHP ohne jegliches Konzept anzusprechen, klar bekommst Du dann mit tricks Variablen aus den Umgebungsvariablen und STDIN, aber darum geht es nicht. Du brauchst eien definierte3 Schnittstelle wo für Dich nur CGI in Frage kommt. Hierzu musst Du a) Wissen wie die Schnittstelle funktioniert(also Welche Variablen wie gesetzt werden, was wie übergeben/angesprochen wird...). Der Einfachheit halbe kannst Du Dir auch im PHP-Source ansehen was genau gefprdert wird. Oben das ist nur ein Beispiel. Es gibt sicher noch weitere Hürden, am sichersten wäre es daher eine korrekte CGI-Schnittstelle zu implementieren. Das ist glaube ich gar nicht so schwer. Also so ganz komm eich mit dem Code nicht klar, auf alle Fälle werden GET-Variablen automatisch aus dem QUERY_STRING extrahiert, naja, aber ich habe nicht wirklich herausbekommen können unter welchen Voraussetzungen das passiert.
Also ich habe mir mal die genaus CGI-Spezifikation angesehen, die ist gar nicht so lang und recht einfach zu verstehen. Ich habe das in wengen Minuten überflogen udn kann sagen da steht alles drin was Du wisen musst.
Da steht z.B.:
Servers MUST provide the following metavariables to scripts. See the individual descriptions for exceptions and semantics.
CONTENT_LENGTH
CONTENT_TYPE
GATEWAY_INTERFACE
PATH_INFO
QUERY_STRING
REMOTE_ADDR
REQUEST_METHOD
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
Mit genauen Angaben wie diese Variabnlen auszusehen haben und wie sie übergeben werden sollten. Diese Variablen solltest Du recht einfach setzen können und schon sollte es gehen!
da steht z.B. auch dass ein Script welches CGI verwendet(also auch die PHP-Implamentation) vor jeder Antwort den Inhalt von REQUEST_METHOD prüfen soll, und das hast Du schonmal nicht gesetzt.
PHP im Speziallen prüpft mindestens(!) SERVER_SOFTWARE, SERVER_NAME, GATEWAY_INTERFACE und REQUEST_METHOD bevor es überhaupt irgendwas in Richtung CGI tut. Kann sein dass später noch mehr geprüft ist, was sogar sehr wahrscheinlich ist. Also, setze obige Umgebungsvariablen korrekt und es sollte funktionieren.
lies: http://cgi-spec.golux.com/draft-coar-cgi-v11-03-clean.html
und implementiere das danach! Und lies es komplett bis Du alles verstanden hast, das wird nicht lange dauern.
Immerhin hast Du dann eine richtige CGI-Schnittstelle mit der Du dann auch PERL usw. ansprechen kannst! Und ohne wirst Du PHP nicht anständig zum laufen bekommen, denn die Alternative ist eine eigene SAPI zu schreiben, was sicherlich erheblich aufwändiger ist!
Viele Grüße
Andreas
PS: Kannst Du mir verraten wie Du in Java Umgebungsvariablen setzt? Ist das identisch für Windows und Unix? Und sag Bescheid ob es funktioniert :-)
Hi!
Z.B. findest Du da solche Dinge in der Datei cgi_main.c im Verzeichnis cgi in Zeile 983:
/* Make sure we detect we are a cgi - a bit redundancy here,
but the default case is that we have to check only the first one. */
if (getenv("SERVER_SOFTWARE")
|| getenv("SERVER_NAME")
|| getenv("GATEWAY_INTERFACE")
|| getenv("REQUEST_METHOD")) {
cgi = 1;
}
In Zeile 569 dieser Datei(Pfad im Source: sapi/cgi/cgi_main.c) steht übrigens auch noch ein interessanter Kommentar:
/* {{{ init_request_info
initializes request_info structure
specificly in this section we handle proper translations
for:
PATH_INFO
derived from the portion of the URI path following
the script name but preceding any query data
may be empty
PATH_TRANSLATED
derived by taking any path-info component of the
request URI and performing any virtual-to-physical
translation appropriate to map it onto the server's
document repository structure
empty if PATH_INFO is empty
The env var PATH_TRANSLATED **IS DIFFERENT** than the
request_info.path_translated variable, the latter should
match SCRIPT_FILENAME instead.
SCRIPT_NAME
set to a URL path that could identify the CGI script
rather than the interpreter. PHP_SELF is set to this.
REQUEST_URI
uri section following the domain:port part of a URI
SCRIPT_FILENAME
The virtual-to-physical translation of SCRIPT_NAME (as per
PATH_TRANSLATED)
These settings are documented at
http://cgi-spec.golux.com/
Based on the following URL request:
http://localhost/info.php/test?a=b
should produce, which btw is the same as if
we were running under mod_cgi on apache (ie. not
using ScriptAlias directives):
PATH_INFO=/test
PATH_TRANSLATED=/docroot/test
SCRIPT_NAME=/info.php
REQUEST_URI=/info.php/test?a=b
SCRIPT_FILENAME=/docroot/info.php
QUERY_STRING=a=b
but what we get is (cgi/mod_fastcgi under apache):
PATH_INFO=/info.php/test
PATH_TRANSLATED=/docroot/info.php/test
SCRIPT_NAME=/php/php-cgi (from the Action setting I suppose)
REQUEST_URI=/info.php/test?a=b
SCRIPT_FILENAME=/path/to/php/bin/php-cgi (Action setting translated)
QUERY_STRING=a=b
Comments in the code below refer to using the above URL in a request
*/
Grüße
Andreas
Hallo,
nur mal eben den Titel etwas korrigiert, denn das Thema ist IMHO interessanter als der ursprüngliche Titel vermuten läßt ;-)
Wenn ich irgendwo Mist erzählt habe bitte ich den Wissenden mich zu korrigieren :)
Grüße
Andreas