borisbaer: URI als Datenbank-Identifier für Überschriften usw. verwenden

Hallo zusammen,

bei meiner Website gibt es dynamische Pfade für Spiele, z.B.

…/games/demons-souls

Im Router-Attribut steht dann der Pfad so:

#[ Route( path: 'games/{page}', method: 'GET' ) ]

Ich möchte anhand dessen z.B. die Überschrift der entsprechenden Seite herleiten. Ich habe als Identifier aber nur diesen Part der URI, in meinem Beispiel ist das demons-souls.

In meiner Datenbank habe ich eine Tabelle games, die folgende Spalten enthält: gameID, title, franchise, origin, year, platform.

Der obige URI-Part (gemeint ist demons-souls) wird übrigens aus der Spalte title generiert, sprich aus Demon’s Souls wird durch eine entsprechende Funktion (slugify) demons-souls.

Folgende Möglichkeiten sehe ich:

Möglichkeit 1: Ich erstelle eine neue Spalte (z.B. mit dem Namen slug) und trage dort manuell demons-souls ein. Dann vergleiche die URI mit dem slug und bekomme meinen Titel und was ich sonst noch so haben will aus der Tabelle. Nachteil: Ich muss alles manuell machen.

Möglichkeit 2: Ich füge keine neue Spalte hinzu, sondern lese die Tabelle als Array aus, verändere in diesem Array die Spalte title so, dass die vollen Titel zu slugs werden. Anschließend vergleiche ich das neue Array mit dem slug in der URI und weiß so, in welcher Reihe geguckt werden muss. Nachteil: Ich parse das recht große Array (aktuell mehr als 1000 Einträge) zweimal. Zudem muss ich mir irgendwas überlegen, wenn es ein Spiel mit dem jeweiligen Namen mehr als einmal gibt. Bei Demon’s Souls gibt es nämlich das Original von 2009 und das Remake von 2020 – beide heißen aber Demon’s Souls. Der automatisch generierte slug müsste dies beachten und beim zweiten Eintrag die Jahreszahl hinzufügen, etwa demons-souls-2020. Alles in allem scheint das eher sehr kompliziert, nur um den Titel herauszufinden.

Möglichkeit 3: In der URI füge ich die unique ID (gameID) ein, z.B. …/games/25/demons-souls, verstecke sie jedoch über irgendeine Rewrite-Regel. Ich weiß jedoch nicht, ob PHP auch auf versteckte URI-Teile zugreifen kann. Ist eigentlich so ähnlich wie Möglichkeit 1, nur dass ich hier nach der unique ID schaue.

Wie wird so etwas normalerweise gehandhabt? Ich wäre sehr dankbar für jede Hilfe.

Grüße
Boris

  1. Ich erstelle eine neue Spalte (z.B. mit dem Namen slug) und trage dort manuell demons-souls ein.

    Du erstellst eine neue Spalte slug und schaust mal ob sich Deine Funktion slugify als Funktion Deines Datenbankservers umschreiben und registrieren lässt.

    Dann machst Du vermittels dieser eigenen Funktion ein Update und zu guter Letzt sorgst Du dafür, dass die neu gefüllte Spalte slug indexiert wird.

    Deine „Möglichkeit 3“ ist unmöglich. Du kannst nicht Teile der URI verstecken.

    1. Hallo Raketenwilli,

      Du erstellst eine neue Spalte slug und schaust mal ob sich Deine Funktion slugify als Funktion Deines Datenbankservers umschreiben und registrieren lässt.

      also würdest du in jedem Fall eine weitere Spalte in der Tabelle empfehlen? Mit SQL-Funktionen kenne ich mich leider überhaupt nicht aus. Ich bin noch nicht über das Stadium „Ich benutze phpMyAdmin von XAMPP“ hinaus. Mehr als Datenbank-Tabellen habe ich bisher noch nicht erstellt. Wenn ich dich recht verstehe, dann würde diese Funktion bei jedem neuen Eintrag ausgeführt werden und aus dem Titel einen slug generieren?

      Dann machst Du vermittels dieser eigenen Funktion ein Update und zu guter Letzt sorgst Du dafür, dass die neu gefüllte Spalte slug indexiert wird.

      In der Theorie verstehe ich, was du meinst, in der Praxis habe ich leider keine Ahnung, wie man das umsetzt. Ich schätze, ich muss mich noch deutlich mehr über mySQL-Datenbanken lernen.

      Deine „Möglichkeit 3“ ist unmöglich. Du kannst nicht Teile der URI verstecken.

      Ach so, sondern nur umschreiben. Habe verstanden.

      Danke für den Input!

      Grüße
      Boris

  2. Du machst es wie es heise einst gemacht hat:

    /games/demons-souls-0815
    /games/demons-souls-0816
    

    Per rewrite in /games/ Umschreiben zu:

    …
    .*-([0-9]+)$ index.php?item=$1
    
    /games/show.php?item=0815
    /games/show.php?item=0816
    

    Die Zahlen sind dann die ID der Zeile in der Datenbank.

    1. Hello,

      bevor Ihr Euch hier in die Plattitüden des "so macht man das" verliert:

      Beim Design gibt es mehrere Dinge zu beachten:

      • kann die Abbildung bijektiv (streng bidrektional) ausgeführt werden?
      • wie erwünscht oder sinnvoll sind "sprechende" URis?
      • wie groß darf die PATHLENGTH des URi werden?
      • wie breit darf die Spalte in der DB-Tabelle werden?
      • wird für die Spalte der DB-Tablle CaseSensivity benutzt?
      • welche Kodierungsunterschiede (Kontext) sind zu beachten?
      • was soll im "not found"-Fall geschehen?
      • ...

      Zusätzlich:

      • Eingriff in die Zugriffsrechte
      • personalisierte Darstellung

      Glück Auf
      Tom vom Berg

      --
      Es gibt soviel Sonne, nutzen wir sie.
      www.Solar-Harz.de
      S☼nnige Grüße aus dem Oberharz
      1. Dieser Beitrag wurde gelöscht: Beitrag ist Hohn und Spott auf das gesamte Forum und Wiki
      2. Da mein Beitrag mit dem Kommentar „Beitrag ist Hohn und Spott auf das gesamte Forum und Wiki“ gelöscht wurde: Widerspruch. Es war womöglich höhnisch gegenüber Tom. Nicht gegenüber dem Forum und Wiki.

        1. Erwünscht ist hier nichts davon. Und das hat einen Sinn.

        2. Hallo Mitleser 2.0,

          als Selfhtml-Vereinsmitglied und Forenmoderator stimme ich Raketenwilli 100% bei. Wenn Du nerven willst, tu das woanders.

          Rolf

          --
          sumpsi - posui - obstruxi
      3. Hallo Tom,

        • kann die Abbildung bijektiv (streng bidrektional) ausgeführt werden?

        Was meinst du damit? Ich bin weder Mathe- noch Informatiker.

        • wie erwünscht oder sinnvoll sind "sprechende" URis?

        Sehr erwünscht.

        • wie groß darf die PATHLENGTH des URi werden?

        So lang, wie der Titel des Spiels ist. Sollte ich ein Maximum festlegen?

        • wie breit darf die Spalte in der DB-Tabelle werden?

        Siehe oben.

        • wird für die Spalte der DB-Tablle CaseSensivity benutzt?

        Darüber habe ich bisher noch nicht nachgedacht. Inwiefern ist das relevant?

        • welche Kodierungsunterschiede (Kontext) sind zu beachten?

        Leider keine Ahnung.

        • was soll im "not found"-Fall geschehen?

        Bereits umgesetzt. Es wird eine 404-Seite angezeigt (verbose oder concise, je nach User-Rolle).

        Zusätzlich:

        • Eingriff in die Zugriffsrechte
        • personalisierte Darstellung

        Was meinst du damit?

        Danke für die Hinweise!

        Grüße
        Boris

        1. Hello,

          • kann die Abbildung bijektiv (streng bidrektional) ausgeführt werden?

          Was meinst du damit? Ich bin weder Mathe- noch Informatiker.

          Du möchtest vermutlich nach außen nur die lesbaren Links erzeugen, egal wie die innerhalb der Anwendung verwaltet/abgebildet werden.
          Wenn Du also einen Link in einer Seite erzeugst, soll da nicht
          example.com/index.php?page=305999 stehen, sondern
          example.com/rennen_um_die_wette/start/paul-gegen-paula/12

          • wie erwünscht oder sinnvoll sind "sprechende" URis?

          Sehr erwünscht.

          Dachte ich mir

          • wie groß darf die PATHLENGTH des URi werden?

          So lang, wie der Titel des Spiels ist. Sollte ich ein Maximum festlegen?

          Die erlaubte Länge von URis ist nicht unbegrenzt, insbesondere dann, wenn sie intern auf das Dateisystem abgebildet werden soll.
          Wenn man die Datenbank als "Übersetzer" dazwischen schaltet, kann man das schon erheblich vergrößern, muss aber dann eben bei der Spaltenbreite der betroffenen Datenbankfelder Rücksicht darauf nehmen.

          • wie breit darf die Spalte in der DB-Tabelle werden?

          Siehe oben.

          • wird für die Spalte der DB-Tablle CaseSensivity benutzt?

          Darüber habe ich bisher noch nicht nachgedacht. Inwiefern ist das relevant?

          Wenn eine bijektive Abbildung erwünscht wird und eine Koppelung an das Dateisystem stattfinden soll, muss man berücksichtigen, ob dieses zwischen Klein- und Großschreibung unterscheidet. Und auch bei URis gilt, dass alles im Pfad hinter dem Domainnamen case-sensitiv ist.

          • welche Kodierungsunterschiede (Kontext) sind zu beachten?

          In einer URi sind nicht alle Zeichen erlaubt. In einer Datenbank auch nicht ohne weitere Vorsichtsmaßnahmen. Da muss man dann die Kontextwechsel beachten.

          • was soll im "not found"-Fall geschehen?

          Bereits umgesetzt. Es wird eine 404-Seite angezeigt (verbose oder concise, je nach User-Rolle).

          Na, das ist doch schon ein Anfang. ;-)

          Glück Auf
          Tom vom Berg

          --
          Es gibt soviel Sonne, nutzen wir sie.
          www.Solar-Harz.de
          S☼nnige Grüße aus dem Oberharz
          1. Hallo Tom,

            Die erlaubte Länge von URis ist nicht unbegrenzt, insbesondere dann, wenn sie intern auf das Dateisystem abgebildet werden soll.

            in der Theorie ist die Länge von URIs tatsächlich unbegrenzt; die HTTP-Spezifikation enthält keine Obergrenze.

            Die tatsächliche Implementierung der gängigen HTTP-Server setzt aber dennoch Grenzen. Ich hatte vor einiger Zeit mal ein paar Jahre lang einen Apachen auf meinem Home-Server, der auch von außerhalb erreichbar war. Dort fand ich im Log immer mal wieder Einträge mit Statuscode 414 "Request URI too long". Ich habe dann mal im Quellcode vom Apachen gewühlt und festgestellt, dass der ein Limit von 8192 Zeichen hat (nach Decodierung von Percent-Encoding).

            In einer URi sind nicht alle Zeichen erlaubt. In einer Datenbank auch nicht ohne weitere Vorsichtsmaßnahmen. Da muss man dann die Kontextwechsel beachten.

            Ja. Wenn man das korrekt tut, kann man aber alle Zeichen verwenden.

            Einen schönen Tag noch
             Martin

            --
            Kaffee ist nur schädlich, wenn Ihnen ein ganzer Sack aus dem 5. Stock auf den Kopf fällt.
            1. Hello Martin,

              Die erlaubte Länge von URis ist nicht unbegrenzt, insbesondere dann, wenn sie intern auf das Dateisystem abgebildet werden soll.

              in der Theorie ist die Länge von URIs tatsächlich unbegrenzt; die HTTP-Spezifikation enthält keine Obergrenze.

              Die tatsächliche Implementierung der gängigen HTTP-Server setzt aber dennoch Grenzen. Ich hatte vor einiger Zeit mal ein paar Jahre lang einen Apachen auf meinem Home-Server, der auch von außerhalb erreichbar war. Dort fand ich im Log immer mal wieder Einträge mit Statuscode 414 "Request URI too long". Ich habe dann mal im Quellcode vom Apachen gewühlt und festgestellt, dass der ein Limit von 8192 Zeichen hat (nach Decodierung von Percent-Encoding).

              Bytes!

              In einer URi sind nicht alle Zeichen erlaubt. In einer Datenbank auch nicht ohne weitere Vorsichtsmaßnahmen. Da muss man dann die Kontextwechsel beachten.

              Ja. Wenn man das korrekt tut, kann man aber alle Zeichen verwenden.

              Genau. Man muss nur alle Speicherbereiche (z. B. Spalten in der DB) groß genug machen. Aber auch hier gilt: Spaltenbreite wird in Bytes gerechnet.

              Zeichenanzahl <> nominale Spaltenbreite.

              Und die Pathlength im Dateisystem ist auch extrem begrenzt und abhängig vom Dateisystem (Z. B. WIN NTFS vs. EXT4 oder Btree bei Linux)

              Und auch hier sind unterschiedliche Zeichen "verboten". Bei Windows soviele, dass ich jedes Mal das Kotzen kriege, wenn ich in Linux gespeicherte *.eml-Dateien (eMails) nach Windows kopieren will.

              Glück Auf
              Tom vom Berg

              --
              Es gibt soviel Sonne, nutzen wir sie.
              www.Solar-Harz.de
              S☼nnige Grüße aus dem Oberharz
    2. Du machst es wie es heise einst gemacht hat:

      /games/demons-souls-0815
      /games/demons-souls-0816
      

      Per rewrite in /games/ Umschreiben zu:

      …
      .*-([0-9]+)$ index.php?item=$1
      
      /games/show.php?item=0815
      /games/show.php?item=0816
      

      Die Zahlen sind dann die ID der Zeile in der Datenbank.

      Ich würde halt gerne darauf verzichten, dass die ID in der URL sichtbar ist.