Siegfried: Versuch der Vereinfachung in PHP schlug fehl

Hallo,

ich schon wieder!

Ich wollte folgendes korrektes Code-Stück vereinfachen

<?php
echo "<a href=" . $_SERVER['REQUEST_URI'] . "datenschutz.php>Datenschutzhinweise</a><br>";
echo '<span style="margin-left: 2rem; margin-right: 2rem;">|</span>';
echo "<a href=" . $_SERVER['REQUEST_URI'] . "impressum.php>Impressum</a><br>";
?>

durch

<a href=" . <?php echo $_SERVER['REQUEST_URI']?> . "datenschutz.php>Datenschutzhinweise</a>
<span style="margin-left: 2rem; margin-right: 2rem;">|</span>
<a href=" . <?php echo $_SERVER['REQUEST_URI']?> . "impressum.php>Impressum</a>

Im ersten Beispiel ergibt sich als erster Link: https://www......de/-test/de/datenschutz.php

Im 2. Beispiel ergibt sich als erster Link: https://www......de/-test/de/.%20/-test/de/%20.

Was habe ich hier wieder falsch gemacht?

  1. @@Siegfried

    Was habe ich hier wieder falsch gemacht?

    Nu mach mal keinen Punkt!

    Nicht da, wo keiner hingehört: im HTML. Denn du willst ja keine Punkte ausgeben . Und Leerzeichen auch nicht. Und die Anführungszeichen an den richtigen Stellen schließen:

    <a href="<?php echo $_SERVER['REQUEST_URI']?>datenschutz.php">Datenschutzhinweise</a>
    <span style="margin-left: 2rem; margin-right: 2rem;">|</span>
    <a href="<?php echo $_SERVER['REQUEST_URI']?>impressum.php">Impressum</a>
    

    Statt <?php echo kannst du auch kurz <?= schreiben.

    Und die Stile des Trenners gehören ins Stylesheet, nich inline ins HTML.

    Jolan tru

    --
    Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)
    1. Moin Gunnar,

      <a href="<?php echo $_SERVER['REQUEST_URI']?>datenschutz.php">Datenschutzhinweise</a>
      <span style="margin-left: 2rem; margin-right: 2rem;">|</span>
      <a href="<?php echo $_SERVER['REQUEST_URI']?>impressum.php">Impressum</a>
      

      fehlt da nicht noch der Kontextwechsel? Moderne Browser hindern mich zwar URIs wie https://example.org/request-uri/<strong>Hallo</strong> in die Adresszeile einzugeben, weil sie die spitzen Klammern maskieren, aber in Links oder mit curl kann das immer noch durchgehen.

      Viele Grüße
      Robert

      1. @@Robert B.

        fehlt da nicht noch der Kontextwechsel?

        Huch, ja.

        <a href="<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>datenschutz.php">Datenschutzhinweise</a>
        <span style="margin-left: 2rem; margin-right: 2rem;">|</span>
        <a href="<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>impressum.php">Impressum</a>
        
        
        Jolan tru
        
        {:@art-x-romulan}
        
        -- 
        Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)
        
  2. Lieber Siegfried,

    Ich wollte folgendes korrektes Code-Stück vereinfachen

    soso, korrekt also? Mal schauen...

    echo "<a href=" . $_SERVER['REQUEST_URI'] . "datenschutz.php>Datenschutzhinweise</a><br>";
    

    Wenn ich Dein Script unter dieser URL aufrufe...

    https://www.example.com/script.php?var1=Wert%201&var2=Wert%202#anker
    

    ... dann ist alles nach dem .com Bestandteil von $_SERVER['REQUEST_URI']. Der von Dir so zusammengesetzte Link sähe dann so aus:

    <a href="/script.php?var1=Wert%201&var2=Wert%202#ankerdatenschutz.php">Datenschutzhinweise</a><br>
    

    Was habe ich hier wieder falsch gemacht?

    Ganz einfach: Du hast versucht schneller an ein Ziel zu gelangen, indem Du Dir das Erlernen der Grundlagen ersparst.

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix,

      bitte vergiss bei aller Polemik nicht, dass der Hash-Teil der URL beim Browser bleibt.

      Fachlich richtig ist hier: REQUEST_URI ist ein ungünstiger Baustein, um datenschutz.php anzusprechen.

      Wenn ich https://example.com/foo/ aufrufe, dann funktioniert Siegfrieds Code wie gewünscht.

      Das ist jedoch längst nicht immer der Fall. Dass die URL nur aus dem Verzeichnisnamen besteht, ist eher die Ausnahme. Man kann mit REQUEST_URI arbeiten, muss diese aber erstmal mit parse_url() zerlegen und den path herausholen, um den von Dir gezeigten Vermüllungsvektor zu beseitigen.

      Darauf gehe ich jetzt aber nicht weiter ein, denn da wäre eine Frage, die Du und Gunnar nicht betrachtet habt: Ist dies ein Problem, das man überhaupt haben muss? Wenn datenschutz.php im gleichen Ordner steht wie das Script, aus dem heraus zum Datenschutz oder Impressum verlinkt werden soll, genügt <a href="./datenschutz.php">Datenschmutz</a>, PHP Akrobatik ist komplett unnötig.

      Siegfried, ich finde es toll, dass Du dazu übergehen möchtest, HTML Code aus PHP nicht mehr mit echo auszugeben, sondern dafür in den HTML-Mode zurückzuschalten! Bitte gewöhne Dir auch noch an, Attributwerte in Anführungszeichen zu setzen.

      Dies hier funktioniert zwar:

      <a href=./datenschutz.php>Datenschutz</a>
      

      aber es kann schnell passieren, dass ein Sonderzeichen in ein Attribut hinein gerät (es gibt ja viele davon, in denen ein Space durchaus normal ist) und damit den HTML-Parser abschießt.

      <span class="divider dark">|</span>
      

      würde beispielsweise ohne Anführungszeichen nicht funktionieren. Da Programmierer nur begrenzten Hirnschmalz haben, sollte man sich den Kopf nicht mit der Frage belasten, ob man für dieses konkrete Attribut nun Anführungszeichen braucht oder nicht, sondern einfach immer welche machen. Diese zwei Bytes machen den Kohl nicht merklich fetter.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Lieber Rolf,

        bitte vergiss bei aller Polemik nicht, dass der Hash-Teil der URL beim Browser bleibt.

        in letzter Zeit hatte ich irgend etwas getestet, das mir ermöglicht hatte, den Hash-Teil auf dem Server zu verarbeiten. Hmm. REQUEST_URI war es wohl nicht.

        Fachlich richtig ist hier: REQUEST_URI ist ein ungünstiger Baustein, um datenschutz.php anzusprechen.

        Wenn ich https://example.com/foo/ aufrufe, dann funktioniert Siegfrieds Code wie gewünscht.

        Warum nicht
        https://example.com/script.php/datenschutz
        anstatt
        https://example.com/datenschutz.php?

        Wenn man ein zentrales PHP-Script verwendet, welches immer aufgerufen wird und welches sich anhand des REQUEST_URI dann sucht, welche Unterseite gemeint ist, kann man sich vieles leichter machen.

        Für „schönere“ URLs kann man dann auch noch ein URL-Rewriting verwenden, welches https://example.com/datenschutz intern zu https://example.com/script.php/datenschutz umschreibt und das zentrale PHP-Script entsprechend arbeiten lässt.

        <span class="divider dark">|</span>
        

        Das ist ein Fall für CSS. Das Pipe-Symbol sollte nicht im HTML stehen, sondern als visueller Trenner per CSS dargestellt werden. Was macht man, wenn die damit zu trennenden Dinge untereinander stehen, weil schmale Viewports sie nicht nebeneinander zeigen? Da sind sie so visuell nicht mehr sinnvoll.

        Liebe Grüße

        Felix Riesterer

        1. Hallo Felix,

          https://example.com/datenschutz.php
          https://example.com/index.php/datenschutz
          https://example.com/datenschutz
          URL-Rewriting
          (so) kann man sich vieles leichter machen.

          Ja. Du und ich können das. Aber ganz ehrlich: ich traue Siegfried einen Action Router (noch) nicht zu. Da steckt nämlich einiges an Hirnschmalz drin, beziehungsweise man braucht geeignete Tools. Insbesondere für das reverse rewriting, das dafür eigentlich nötig ist. Wenn ich nämlich aufrufseitig von URLs wie index.php?action=blog&article=Hirnschmalz ausgehe, dann möchte ich das eigentlich auch konsistent in meinem Code haben und nicht beim Ausgeben von URLs daran denken müssen, dass da ein Rewriter in der Kette sitzt, der das beim Seitenabruf als /blog/Hirnschmalz sehen möchte. Ein GUTER Rewriter erkennnt das selbst und schreibt die URLs beim Ausgeben entsprechend um. Inbesondere muss der reverse rewriter auch wissen, dass er bei einer solchen Manipulation auch so was wie "href=styles.css" in "href="../styles.css" umschreiben muss.

          Sowas gibt's, z.B. in ASP.NET MVC, und auch im Rewrite-Plugin für den IIS. Über die Fähigkeiten von mod_rewrite geht das weit hinaus, aber sicherlich gibt's auch für Apache oder PHP solche Tools. Und es ist nichts für Gelegenheitsanwender. Wenn ich nur 3-4 Seiten habe, ist ein Script pro Seite deutlich einfacher.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Lieber Rolf,

            Ja. Du und ich können das.

            es wäre eine nächste Ausbaustufe, wenn /script.php/name erledigt ist.

            Wenn ich nämlich aufrufseitig von URLs wie index.php?action=blog&article=Hirnschmalz ausgehe,

            Warum solltest Du das? Ich tue das nicht. In meiner Lesart wäre das /blog/Hirnschmalz als Request. Und der Rewriter setzt noch ein /script.php davor. Fertig.

            Liebe Grüße

            Felix Riesterer

        2. Hallo,

          in letzter Zeit hatte ich irgend etwas getestet, das mir ermöglicht hatte, den Hash-Teil auf dem Server zu verarbeiten. Hmm. REQUEST_URI war es wohl nicht.

          das würde mich interessieren. Meines Wissens behält der Browser den Fragment Identifier für sich und sendet ihn nicht an den Server. Wenn du wiederfindest, was du da gemacht hast, zeig uns das doch bitte mal.

          Ich könnte mir auch vorstellen, dass du irgendwas verwechselst.

          Warum nicht
          https://example.com/script.php/datenschutz
          anstatt
          https://example.com/datenschutz.php?

          Berechtigte Frage. Das ist zweifellos eleganter.

          Wenn man ein zentrales PHP-Script verwendet, welches immer aufgerufen wird und welches sich anhand des REQUEST_URI dann sucht, welche Unterseite gemeint ist, kann man sich vieles leichter machen.

          Dann geht's noch einfacher: Wenn man direkt PATH_INFO auswertet, ist das ganze "lästige" Gedöns wie Hostname, Local Path und Scriptname schon weg und man kriegt die Garnelen essfertig auf den Teller.

          Für „schönere“ URLs kann man dann auch noch ein URL-Rewriting verwenden, welches https://example.com/datenschutz intern zu https://example.com/script.php/datenschutz umschreibt und das zentrale PHP-Script entsprechend arbeiten lässt.

          Auch dann kann man PATH_INFO noch anwenden.

          Einen schönen Tag noch
           Martin

          --
          Manchmal kann man gar nicht so viel fühlen, wie man denkt.
          Und manchmal fühlt man so viel, dass man gar nicht denken kann.
          1. Hallo,

            in letzter Zeit hatte ich irgend etwas getestet, das mir ermöglicht hatte, den Hash-Teil auf dem Server zu verarbeiten. Hmm. REQUEST_URI war es wohl nicht.

            das würde mich interessieren. Meines Wissens behält der Browser den Fragment Identifier für sich und sendet ihn nicht an den Server. Wenn du wiederfindest, was du da gemacht hast, zeig uns das doch bitte mal.

            Ich könnte mir auch vorstellen, dass du irgendwas verwechselst.

            Yep. Der Fragment Identifier landet nicht nativ beim Server. Man kann ihn nur auslesen und nachgelagert über einen eigenen Request dem Server dann mitteilen.