Andreas Korthaus: Zugriff auf Umgebungs-Variablen nach URL-Rewrite

Hallo!

Sitze da immer noch an meinem "modularen Programmieren"(bin aufgrund von Urlaub noch nicht wirklich weiter, dafür gut erholt ;-)).
Jedendfalls habeich jetz teinfach mal angefangen, udn habe direkt das erste Problem was ich vorhergesehen hatte was Ihr aber nicht als Problem angesehen habt:

Ich habe jetzt eine index.php, auf die alle Requests weitergeleitet werden, per .htaccess:

RewriteRule ^(.*)$            /index.php?request=$1 [L]

Das funktioniert auch prima, nur bekomme ich so nichtmal übermittelte GET-Parameter, ein (.*) müßte doch alles rausfischen, oder?

Und wenn das schon nicht geht, wie soll das dann mit POST-Daten und Upload-Files funktionieren? Ich lasse mir in index.php print_r($_REQUEST) ausgeben, und da steht aber nur "Array ( [request] => /irgendeinquatsch.php )", was ja absolut logisch ist, das Script index.php hat natürlich ganz neue Umgebungsvariablen, das kan man sehr schlecht mit den Umgebungsvariablen des ursprüngichen Requests mischen. Außerdem erstellt PHP die Umgebungsvariablen, aber wenn Apache umleitet hat PHP noch gar keinen Handschlag getan, das erste was PHP bekommt ist "/index.php?request=irgendeinquatsch.php" und erstellt hierfür die Umgebungsvariablen. Da ich aber alles über das eine Script laufen lassen wollte, wie kann ich dort zum einen an die GET-Parameter kommen(was vermutlich nicht ganz so schwer ist), zum anderen an die POST Parameter, unter anderem Upload-Files?
Wie funktioniert das ganze? Kann man das überhaupt mit einer Rewrite-Rule lösen? Oder kann ich den kompletten Ansatz mit einem zentralen Script vergessen?

Viele Grüße
Andreas

  1. Hallo Andreas,

    Das funktioniert auch prima, nur bekomme ich so nichtmal übermittelte GET-Parameter, ein (.*) müßte doch alles rausfischen, oder?

    Du auch? Hmmm. Dann bin  ich wengistens nicht allein. Ich habe es so gelöst, dass GET-Paramter immer in der Form

    http://irgendwas/param1/param2/param3/...

    übergeben werden, was anderes blieb mir nicht übrig. Aber das war ja gerade der Sinn. Bsp:

    http://irgendwas/admin/user/edit/christian

    oder per POST an

    http://irgendwas/admin/user/edit

    und dann als Hidden-Field alle weiteren Infos. Das ist viel schöner als irgendwas mit ?, oder nicht?

    Interessieren würde mich das ganze natürlich trotzdem.

    Noch etwas: In $_SERVER['REQUEST_URI'] steht der Originalrequest - da kannst Du natürlich alles nach dem ? parsen, wenn Du willst. PHP bietet da glaube ich sogar eine Funktion an... Ich hab' das aber nicht gemacht.

    Und wenn das schon nicht geht, wie soll das dann mit POST-Daten und Upload-Files funktionieren?

    Mit $_POST hatte ich in so einer Konstellation noch nie Probleme, die kamen immer an ($_REQUEST verwende ich aus einer Laune heraus nie ;)) und $_FILE habe ich nicht probiert, sollte aber funktionieren, da $_POST funktioniert.

    Grüße,

    Christian

    --
    Ich wünsche allen ein frohes neues Jahr 2003!
    Ich bitte darum, dass ein Themenbereich (BARRIEREFREIHEIT) eingerichtet wird.
    Hmm, was könnte ich sonst noch in die Signatur schreiben?
    1. Hallo Christian!

      Du auch? Hmmm. Dann bin  ich wengistens nicht allein. Ich habe es so gelöst, dass GET-Paramter immer in der Form

      Kommando zurück - mit POST funktioniert das ganze (wider Erwarten ;-)), also halb so wild.

      http://irgendwas/param1/param2/param3/...

      übergeben werden, was anderes blieb mir nicht übrig. Aber das war ja gerade der Sinn. Bsp:

      http://irgendwas/admin/user/edit/christian

      Hm. Das ist zwar sehr schön, aber irgendwie ist mir das so unsicher, keine Ahnung, nur so vom Gefühl ist das eine potentielle Fehlerquelle, aber wie gesagt, habe kein echten Argumente dagegen. Dazu gehört auf alle Fälle mehr Disziplin.

      oder per POST an
      http://irgendwas/admin/user/edit

      und dann als Hidden-Field alle weiteren Infos. Das ist viel schöner als irgendwas mit ?, oder nicht?

      Hidden Files sind mit das häßlichste was es gibt finde ich, denn meist(nicht immer!) sind sie Resultat schlechter Programmierung, die Erfahrung habe zumindest ich bisher gemacht. Außerdem kann man oft nicht auf GET verzichten.

      Noch etwas: In $_SERVER['REQUEST_URI'] steht der Originalrequest - da kannst Du natürlich alles nach dem ? parsen, wenn Du willst. PHP bietet da glaube ich sogar eine Funktion an... Ich hab' das aber nicht gemacht.

      Ja da gibt es was, was mich an der Funktion stört, die funktioniert genau so wie "register_globals=on", alle Variablen werden direkt hergestellt. Das gefällt mir nicht. Für geht hätte isch schon gerne eine Lösung für die .htaccess. Das muß doch irgendwie möglich sein, oder?

      Und wenn das schon nicht geht, wie soll das dann mit POST-Daten und Upload-Files funktionieren?

      Mit $_POST hatte ich in so einer Konstellation noch nie Probleme, die kamen immer an ($_REQUEST verwende ich aus einer Laune heraus nie ;)) und $_FILE habe ich nicht probiert, sollte aber funktionieren, da $_POST funktioniert.

      ;-) Das hatte ich zum Glück auch bemerkt
      *Erleichterung....*

      Grüße
      Andreas
      Andereas

      1. Hallo

        Dazu gehört auf alle Fälle mehr Disziplin.

        Was soll daran so schlimm sein? ;-)

        Hidden Files sind mit das häßlichste was es gibt finde ich, denn meist(nicht immer!) sind sie Resultat schlechter Programmierung, die Erfahrung habe zumindest ich bisher gemacht.

        Nicht notwendigerweise. Du musst per Hidden-Field die User-ID übergeben, wenn Du einen Benutzer in der Benutzerverwaltung bearbeitest - Du _könntest_ sie zwar per GET »verschicken« - aber das ist auch nicht schöner - nur anders.

        Ja da gibt es was, was mich an der Funktion stört, die funktioniert genau so wie "register_globals=on", alle Variablen werden direkt hergestellt. Das gefällt mir nicht. Für geht hätte isch schon gerne eine Lösung für die .htaccess. Das muß doch irgendwie möglich sein, oder?

        Du musst doch einfach das Zeichen "?" finden, dann einen Substring machen, diesen nach dem &-Zeichen trennen, dann jeden einzelnen Eintrag nach dem =-Zeichen trennen und sowohl Name als auch Wert durch urldecode jagen - dann kannst Du damit anstellen, was Du willst.

        Grüße,

        Christian

        --
        Ich wünsche allen ein frohes neues Jahr 2003!
        Ich bitte darum, dass ein Themenbereich (BARRIEREFREIHEIT) eingerichtet wird.
        Hmm, was könnte ich sonst noch in die Signatur schreiben?
        1. Hallo!

          Dazu gehört auf alle Fälle mehr Disziplin.

          Was soll daran so schlimm sein? ;-)

          ich habe die ganze Zeit das Gefühl das ich früher oder später damit Probleme bekomme ;->

          Nicht notwendigerweise. Du musst per Hidden-Field die User-ID übergeben, wenn Du einen Benutzer in der Benutzerverwaltung bearbeitest - Du _könntest_ sie zwar per GET »verschicken« - aber das ist auch nicht schöner - nur anders.

          ich verwende HTTP-Auth Header für den eindeutigen-Usernamen und speicher die UserID in einer Session, sehr elegante Variante, was? ;-)
          Wobei ich hier auch ein ungutes Gefühl im Magen habe ;-)

          Du musst doch einfach das Zeichen "?" finden, dann einen Substring machen, diesen nach dem &-Zeichen trennen, dann jeden einzelnen Eintrag nach dem =-Zeichen trennen und sowohl Name als auch Wert durch urldecode jagen - dann kannst Du damit anstellen, was Du willst.

          Ich weiß auch nicht. Eigentlich kein Problem. Ich benutze ja nichts großartiges. Das ganze schreib ich in $myGET[] oder sowas und habe es so schön in einem eigenen Array, muß in eine Funktion packen, OK, das sollte gehen. Danke Dir!
          Ich würde das jetzt so am Anfang von index.php schreiben:

          if($_SERVER["REQUEST_METHOD"]=="GET") {
              $request_array = explode("?",$_SERVER["REQUEST_URI"]);
              parse_str ( $request_array[1] , $myREQUEST);
          }
          else {
              $myREQUEST = $_POST;
          }

          print_r($myREQUEST);

          Also _ohne_ extra Funktion/Klasse/Modul, da das sowieso _immer_ auszuführen ist, denn in index.php bekomme ich nur die URL als eigenen GET-Parameter(durch meine rewrite-rule), alle weiteren Parameter würde ich dann in besagten Array schreiben, so dass ich dann nacher so drauf zugreifen kann. Oder ist das nicht optimal? Was mich jetzt noch ein wenig daran stört, aus $_SERVER["REQUEST_URI"] hole ich mir ja jetzt die Parameter, nur ist das denn auch richtig so? Gehörten die Parasmeter überhaupt zur URI? Ich denke schon, oder?
          Mit parse_str() mache ich mir so keine Sorgen da ich die genau wie $_POST.. erzeuge. Aber das hat vieleicht doch einen kleinen aber feinen Haken:
          $_POST ist superglobal, $myREQUEST nicht. Ich will ja später auch in Klassen darauf zugreifen, dei Frage ist ob ich mir hier eien Möglichkeit überlege, wie ich diesen Array der entsprechenden Klasse übergebe, oder ob ich aus dem Array $myRequest nicht einfach den superglobalen Array $_REQUEST mache, mit http://php3.de/manual/de/function.putenv.php. Aber das soll ja nicht so toll sein, es ist ja eh das Ziel die Umgebungsvariablen mit irgendeiner Schnittestelle  zu übergeben als sie aus den einzelnen Klassen/Modulen selbst zu holen. Nur wie mache ich das praktisch?

          Ich habe eine Klasse die einen Wert aus einem REQUEST-Parameter braucht. Wie sollte so eine standardisierte Schnittstelle aussehen?
          Ich würde vielleicht in meinem Basismodul eine Methode hinzufügen "getRequest", die dann den kompletten Array zurückgibt, oder sollte ich lieber jeden Wert einzelnd abfragen, indem ich getRequest("var") alles einzelnd übergebe?

          Oder wie sieht sonst so eine Schnittstelle aus?

          Und noch eine Frage zu Eurer Erfahrung:
          Ist es gut oder schlecht das ich GET und POST-Requests beide in dieselbe Variable schreibe? Für mich macht es im Script doch keienn Unterschied ob der HTTP-REQUEST jetzt ein GET oder ein POST war, darum wil ich mich in den einzelnden Scripten gar nicht kümmern, da soll es nur drum gehen - ich brauche eine Angabe vom Browser, und wie die jetzt genau kommt ist Sache des Templates, oder?

          Wie ist das aus Eurer Erfahrung? Wann hat es Sinn GET und POST auch im Script zu trennen?

          Viele Grüße
          Andreas

      2. Hi,

        Kommando zurück - mit POST funktioniert das ganze (wider Erwarten ;-))

        warum? STDIN wird nun wirklich erst ganz zum Schluss ausgelesen :-)

        http://irgendwas/param1/param2/param3/...

        Es dürfte übrigens problematisch sein, einen Browser dazu zu bewegen, GET-Formulare so abzuschicken...

        Hm. Das ist zwar sehr schön, aber irgendwie ist mir das so unsicher, keine Ahnung, nur so vom Gefühl ist das eine potentielle Fehlerquelle,

        Die URL enthält eine Semantik, darum vermutlich.

        Hidden Files sind mit das häßlichste was es gibt finde ich, denn meist(nicht immer!) sind sie Resultat schlechter Programmierung, die Erfahrung habe zumindest ich bisher gemacht.

        Das finde ich eigentlich nicht. Wie sonst willst Du beispielsweise per Formular eine Session-ID übergeben? Sie der Formular-Action als Parameter anzuhängen, _das_ ist schlechte Programmierung - ganz besonders, wenn es mit der Methode POST übermittelt wird. Und wie gut man Cookies für unverzichtbare Daten verwenden kann, sollte klar sein.

        Außerdem kann man oft nicht auf GET verzichten.

        Jupp.

        Ja da gibt es was, was mich an der Funktion stört, die funktioniert genau so wie "register_globals=on", alle Variablen werden direkt hergestellt. Das gefällt mir nicht.

        Vernünftig. Mal so ganz nebenbei: Hast Du PHP eigentlich als Server-Modul oder als CGI-Variante installiert? Bei ersterem kann ich mir durchaus vorstellen, dass mod_php bereits vor mod_rewrite die Parameter auswertet. Ich weiß, das kollidiert ein wenig mit meiner Äußerung ganz oben ;-)

        Cheatah

        --
        X-Will-Answer-Email: No
        1. Hallo!

          Kommando zurück - mit POST funktioniert das ganze (wider Erwarten ;-))

          warum? STDIN wird nun wirklich erst ganz zum Schluss ausgelesen :-)

          von wem? Apache oder PHP? Apache bekommt einen Request, schickt er POST dann an STDIN von PHP? Denn eigentlich dürfte ja erst nach dem Rewrite ein Aufruf kommen an PHP, und deshalb sind die POST-Daten auch da.

          http://irgendwas/param1/param2/param3/...
          Es dürfte übrigens problematisch sein, einen Browser dazu zu bewegen, GET-Formulare so abzuschicken..

          warum sollte man das wollen? Wir haben andere Probleme ;-)

          Die URL enthält eine Semantik, darum vermutlich.

          Das sollt emir eigentlich egal sein, da ich sowieso alles zerpflücke, aber das ist noch nicht alles so klar, da meine Struktur doch etwas sehr komplex ist, zumindest zum anfangen ;-)

          Das finde ich eigentlich nicht. Wie sonst willst Du beispielsweise per Formular eine Session-ID übergeben? Sie der Formular-Action als Parameter anzuhängen, _das_ ist schlechte Programmierung - ganz besonders, wenn es mit der Methode POST übermittelt wird. Und wie gut man Cookies für unverzichtbare Daten verwenden kann, sollte klar sein.

          Daher verwende ich hierfür HTTP-AUTH mit SessionID=REMOTE_USER, ist aber ein Sonderfall, ich weiß, aber klappt prima!

          Vernünftig. Mal so ganz nebenbei: Hast Du PHP eigentlich als Server-Modul oder als CGI-Variante installiert? Bei ersterem kann ich mir durchaus vorstellen, dass mod_php bereits vor mod_rewrite die Parameter auswertet. Ich weiß, das kollidiert ein wenig mit meiner Äußerung ganz oben ;-)

          Ich verwende zur Zeit CGI, endgültig kommt es aber auf einen Server zum mod_php, das kann ich aber erst nächste Woche testen. Meinst Du das gobt Probleme? Apache kann doch keinen Request weiterleitet wenn noch nicht sicher feststeht an wen genau der Request geht, das hätte ja nicht überschaubare Folgen!

          Viele Grüße
          Andreas

          1. Hi Andreas,

            Kommando zurück - mit POST funktioniert das ganze (wider Erwarten ;-))
            warum? STDIN wird nun wirklich erst ganz zum Schluss ausgelesen :-)
            von wem? Apache oder PHP? Apache bekommt einen Request, schickt er POST dann an STDIN von PHP? Denn eigentlich dürfte ja erst nach dem Rewrite ein Aufruf kommen an PHP

            erst nach dem Rewrite kann ja feststehen, ob der resultierende URL überhaupt noch eine Datei ist, die vom PHP-Interpreter behandelt werden soll. Wenn Deine Datei also tatsächlich vom PHP-Interpreter verarbeitet wird, dann sind bereits sämtliche URL-Manipulationen abgeschlossen - beispielsweise auch Directory Browsing und Language Negotiation.

            Viele Grüße
                  Michael

            --
            T'Pol: I apologize if I acted inappropriately.
            V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
      3. Hi

        Hidden Files sind mit das häßlichste was es gibt finde ich, denn meist(nicht immer!) sind sie Resultat schlechter Programmierung, die Erfahrung habe zumindest ich bisher gemacht. Außerdem kann man oft nicht auf GET verzichten.

        Wo muss man denn auf GET verzichten? In POST-Formularen? Neeee...

        <form action="form.php?get=get&nochnget=nochnget" method="POST">
        <input>...
        </form>

        auf der ergebnisseite lässt du dir mal print_r($_REQUEST); ausgeben. Und siehe da, POST _und_ GET steht zur Verfügung, zumindest in PHP. Bevor jetzt die HTTP-Puristen kommen und sagen, dass das nicht erlaubt wäre: Das stimmt prinzipiell natürlich, dass nur _eine_ Methode erlaubt ist, aber wenn dann in den Logs steht POST http://localhost/posttest.php?get=get... HTTP1.1 dann heißt das für mich, dass ich das so machen kann.

        Fabian

        1. Hi Fabian!

          Hidden Files sind mit das häßlichste was es gibt finde ich, denn meist(nicht immer!) sind sie Resultat schlechter Programmierung, die Erfahrung habe zumindest ich bisher gemacht. Außerdem kann man oft nicht auf GET verzichten.
          Wo muss man denn auf GET verzichten? In POST-Formularen? Neeee...

          <form action="form.php?get=get&nochnget=nochnget" method="POST">
          <input>...
          </form>

          Bevor ich ungültiges HTTP verwende verwende ich doch lieber hidden-fields ;-)
          Im Ernst, warum sollte man das wollen? Wenn ich GET möchte stelle ich das Forumlar auf GET, sonst halt POST. Außerdem habe ich gesagt das man nicht auf GET verzichten kann, also das genaue Gegenteil von dem, was Du darus interpretiert hast, oder? Auf GET kann nur Verzichten wenn man nur Forumlare verwendet, wenn man normale Links möchte braucht man hierfür Javascripte die das Formular abschicken... sehr unschön.
          Das Problem war ja GET-Parameter nach einem URL-Rewrite zu extrahieren, was anscheinend nur indirekt geht.

          Das stimmt prinzipiell natürlich, dass nur _eine_ Methode erlaubt ist, aber wenn dann in den Logs steht POST http://localhost/posttest.php?get=get... HTTP1.1 dann heißt das für mich, dass ich das so machen kann.

          In den selfforum-Logs steht auch das Ferraris im Web surfen können...
          Auch ActiveX funktioniert bei den meisten Browsern(der User-Anzahl nach), verwendst Du das dann auch?
          Und vor allem hat das 0 Nutzen, oder?

          Grüße
          Andreas

          1. Hi

            Hidden Files sind mit das häßlichste was es gibt finde ich, denn meist(nicht immer!) sind sie Resultat schlechter Programmierung, die Erfahrung habe zumindest ich bisher gemacht. Außerdem kann man oft nicht auf GET verzichten.
            Wo muss man denn auf GET verzichten? In POST-Formularen? Neeee...

            <form action="form.php?get=get&nochnget=nochnget" method="POST">
            <input>...
            </form>
            Bevor ich ungültiges HTTP verwende verwende ich doch lieber hidden-fields ;-)

            Ach was. Eben sagtest du noch, du magst sie nicht ;-)
            Was ich damit erreichen wolltem war genau diese Antwort: Es gibt _immer_ etwas noch schlechteres ;-)

            Im Ernst, warum sollte man das wollen? Wenn ich GET möchte stelle ich das Forumlar auf GET, sonst halt POST. Außerdem habe ich gesagt das man nicht auf GET verzichten kann, also das genaue Gegenteil von dem, was Du darus interpretiert hast, oder? Auf GET kann nur Verzichten wenn man nur Forumlare verwendet, wenn man normale Links möchte braucht man hierfür Javascripte die das Formular abschicken... sehr unschön.

            Exakt.

            Das Problem war ja GET-Parameter nach einem URL-Rewrite zu extrahieren, was anscheinend nur indirekt geht.

            Das stimmt prinzipiell natürlich, dass nur _eine_ Methode erlaubt ist, aber wenn dann in den Logs steht POST http://localhost/posttest.php?get=get... HTTP1.1 dann heißt das für mich, dass ich das so machen kann.
            In den selfforum-Logs steht auch das Ferraris im Web surfen können...

            Die heißen auch nur so. Ich kann $_GET auch $_FERRARI nennen ;-)

            Auch ActiveX funktioniert bei den meisten Browsern(der User-Anzahl nach), verwendst Du das dann auch?
            Und vor allem hat das 0 Nutzen, oder?

            Mhh, theoretisch ja.

            Fabian

        2. Hallo Fabian,

          Bevor jetzt die HTTP-Puristen kommen und sagen, dass das nicht erlaubt wäre: Das stimmt prinzipiell natürlich,

          Hä? Natürlich ist das erlaubt. Was denkst Du? Das einzige, was nicht 100%ig HTTP-Konform ist, ist dass PHP die Variablen in $_GET unterbringt - die Namensgebung wäre in dem Fall unglücklich. Denn eine HTTP-URL kann _immer_, egal welche Methode, auch aus einem Search-String bestehen. Ob dieser jetzt vom Scriptschreiber bentutzt werden sollte, um Parameter bei POST zu übergeben, ist die zweite Sache.

          Grüße,

          Christian

          --
          Ich wünsche allen ein frohes neues Jahr 2003!
          Ich bitte darum, dass ein Themenbereich (BARRIEREFREIHEIT) eingerichtet wird.
          Hmm, was könnte ich sonst noch in die Signatur schreiben?
          1. Hi

            Bevor jetzt die HTTP-Puristen kommen und sagen, dass das nicht erlaubt wäre: Das stimmt prinzipiell natürlich,

            Hä? Natürlich ist das erlaubt. Was denkst Du? Das einzige, was nicht 100%ig HTTP-Konform ist, ist dass PHP die Variablen in $_GET unterbringt - die Namensgebung wäre in dem Fall unglücklich. Denn eine HTTP-URL kann _immer_, egal welche Methode, auch aus einem Search-String bestehen. Ob dieser jetzt vom Scriptschreiber bentutzt werden sollte, um Parameter bei POST zu übergeben, ist die zweite Sache.

            Oder so ;-)
            Das fragwürdige war für mich lediglich $_GET, denn auch wenn das ganze "funktioniert" ist das wohl kaum GET, sondern eher $_SERVER['QUERY_STRING'].

            Fabian

            1. Hallo Fabian,

              Das fragwürdige war für mich lediglich $_GET, denn auch wenn das ganze "funktioniert" ist das wohl kaum GET, sondern eher $_SERVER['QUERY_STRING'].

              Hab' ich das denn nicht gesagt?

              Das einzige, was nicht 100%ig HTTP-Konform ist, ist dass PHP die Variablen in $_GET unterbringt - die Namensgebung wäre in dem Fall unglücklich.

              Grüße,

              Christian

              --
              Ich wünsche allen ein frohes neues Jahr 2003!
              Ich bitte darum, dass ein Themenbereich (BARRIEREFREIHEIT) eingerichtet wird.
              Hmm, was könnte ich sonst noch in die Signatur schreiben?
              1. Hi

                Das fragwürdige war für mich lediglich $_GET, denn auch wenn das ganze "funktioniert" ist das wohl kaum GET, sondern eher $_SERVER['QUERY_STRING'].

                Hab' ich das denn nicht gesagt?

                Hihi, doch hast du. Das wär mal interessant, immer mal wieder "Ich hab's doch gesagt"-Postings zu machen, da würde man bei Leuten die garnix raffen (sic!) glatt das Forum vollposten können ;-)

                Fabian