Mod_Rewrite + Dynamische Variablen

djcritical

Grünschnabel
Hallo zusammen,

ich probiere nun schon seit Stunden hin und her und komme auf keinen Nenner.

Zu der Aufgabe:

Der User legt eine "Domain" für einen Inhalt fest.
Bsp: User speichert "about" -> Der Inhalt wird in DB unter z.B. ID 2 gespeichert.

Danach folgt Eintrag in die .htaccess

RewriteRule about$ cid.php?id=2

Zu dem Problem:

Das funktioniert ja super, nur möchte ich jetzt zu dem Inhalt beliebig viele Variablen übergeben können, aber immernoch die Seite unter http://www.seite.de/about (http://www.seite.de/cid.php?id=2) erreichen können.

Mein Gedankensgang:

RewriteRule about(/?)[^(.*)/]*$ cid.php?id=2&$1 [N]

Das funktioniert für die Aufrufe:

http://www.seite.de/about
http://www.seite.de/about/
http://www.seite.de/about/foo

und ab hier ist Schluss. :(

Es folgt also keine weiter Auflösung der URL wie z.B.:

http://www.seite.de/about/foo/bar/lorem/ipsum

zu
http://www.seite.de/cid.php?id=2&foo=bar&lorem=ipsum

Wobei Bedingung ist das alle Variablen und deren Inhalt dynamisch sind.. Also Variable foo kann auch morgen Baum sein. Wichtig ist nur, das "about" fest zur id=2 übergeben wird.

Gibt es dafür eine RegEx Lösung? Ich habe das Gefühl das bei erneutem Durchlauf die statische Variable id=2 überschrieben wird. Oder auch nicht. Ich komme wirklich nicht weiter.

Ich danke euch vielmals für konstruktive Hilfe!

Beste Grüße
Dave
 
Ich weiß zwar nicht, wie man das mit RegEx in der .htaccess löst, und ich weiß auch nicht, ob es überhaupt möglich ist, aber ich würde dir vorschlagen, dass du das Problem direkt in PHP löst:
PHP:
<?php
$get = explode('/', $_GET['vars']);

foreach($get as $var) {
  if(isset($key)) {
    $vars[$key] = $var;
    unset($key);
  }
  else {
    $key = $var;
  }
}

// Hier sind jetzt deine Variablen gespeichert
$vars;
?>
 
Hallo "einfach nur crack"

Danke für die super schnelle Antwort!
Ich weis was du damit sagen willst und ich habe es auch gerade noch einmal versucht so umzustriken, aber es funktioniert so nicht. Es muss leider ein ModRewrite angelegt werden.

Denn sonst wäre ja der Inhalt aus der Datenbank (cid.php?id=2) nicht über /about aufrufbar.

Vieleicht nocheinmal etwas genauer:

Es handelt sich um ein CMS.

- Der User legt eine neue "Seite" an (z.B. About) -> er hat im System nun den FCK Editor zur verfügung um diese Unterseite der Website zu gestalten.

- Diese Speichert er nun ab und hat die Möglichkeit eine Suchmaschinenfreundliche URL mit Anzugeben (z.B.: /about)

- Der User speichert jetzt und es wird der Inhalt aus dem FCK Editor in die DB geschrieben mit einer Autoincrement ID.

- Nach dem Speichern wird in die .htaccess Datei des CMS der Eintrag RewriteRule about$ cid.php?id=2 geschrieben. (Also der gewünschte Aufrufname + die last inster ID aus mysql)

- Die cid.php Datei macht nicht anderes als die Daten aus der DB nun im WebsiteLayout darzustellen.

- Also ist http://www.seite.de/about nun über die .htaccess http://www.seite.de/cid.php=2 (Und dieses muss fest sein und keines Falls dynamisch!)

Jetzt möchte ich allerdings, das wenn man zu http://www.seite.de/about -> noch X Variablen hinzufügt (ob nun 60 mal foo/bar/foo/bar/foo/bar oder der gleichen) diese mit an die cid.php?id=2 übergeben werden.

Es ist irgendwie schwerz zu beschreiben ich weis :(

Dennoch danke für jeden Hilfe!

LG Dave
 
Ich weiß genau was du meinst, aber deine Idee die .htaccess-Datei über ein Skript zu verändern, finde ich sehr gewagt. Diese Datei ist zur Konfiguration deines Servers gedacht und sollte nur von einer Person verändert werden. Nimm lieber meinen Weg und beseitige somit eine Sicherheitsrisiko. Mein Skript kannst du auch so abändern, dass der erste ausgelesene Wert in der URL auf den Eintrag in der Datenbank hinweist und danach erst mein Skript abläuft:
PHP:
<?php 
$get = explode('/', $_GET['vars']);

// Hier ist jetzt der Verweis auf die Seite drin
$page = $get[0];
unset($get[0]);

foreach($get as $var) { 
  if(isset($key)) { 
    $vars[$key] = $var; 
    unset($key); 
  } 
  else { 
    $key = $var; 
  } 
} 

// Hier sind jetzt deine Variablen gespeichert 
$vars; 
?>

EDIT: Was mir gerade noch eingefallen ist: die Seitennamen speicherst du in deiner Datenbank dann in einer Spalte, welche die Eigenschaft UNIQUE hat und keine Schrägstriche enthalten darf. IDs sind auch noch möglich, aber nur bedingt nötig, da der Seitenname schon als ID verwendet werden kann.
 
Zuletzt bearbeitet:
Hi!

RewriteRule about$ cid.php?id=2

...

RewriteRule about(/?)[^(.*)/]*$ cid.php?id=2&$1 [N]

Das funktioniert für die Aufrufe:

http://www.seite.de/about
http://www.seite.de/about/
http://www.seite.de/about/foo

und ab hier ist Schluss. :(

Wenn Du es noch nicht aufgegeben hast, versuch's mal mit...
Code:
RewriteRule about(/?\?(.*))?$ cid.php?id=2&$2 [N]
RewriteRule about/foo(/?\?(.*))?$ cid.php?id=3&$2 [N]
RewriteRule about/foo/bar(/?\?(.*))?$ cid.php?id=4&$2 [N]
RewriteRule better(/?\?(.*))?$ cid.php?id=5&$2 [N]
RewriteRule better/done(/?\?(.*))?$ cid.php?id=6&$2 [N]
RewriteRule better/done/in(/?\?(.*))?$ cid.php?id=7&$2 [N]
RewriteRule better/done/in/c(/?\?(.*))?$ cid.php?id=8&$2 [N]
Wenn ich Dein Anliegen nicht komplett falsch verstanden habe sollte das funktionieren.

[EDIT]
Ok, ich hab' Dich falsch verstanden.
Es ist dennoch möglich mit ModRewrite, allderings nicht mit einer einzigen Regel.
Das wird ein ganz netter Satz - sowas macht keinen Spaß.
Das willst Du bestimmt nicht. Oder doch? :)

Gruß
Enum
 
Zuletzt bearbeitet:
Probier mal folgende Regeln:
Code:
RewriteRule ^([^/]+)/([^/]+)/([^/]+)(.*) /$1$4?$2=$3 [QSA,N]
RewriteRule ^([^/]+)/([^/]*)$ /$1?$2 [QSA]

RewriteRule ^about$ cid.php?id=2 [QSA,L]
Du solltest dich allerdings für nur eine Schreibweise entscheiden, also mit oder ohne abschließenden Schrägstrich.
 
Schonmal Danke für die Antworten!
Bin gerade noch auf Arbeit, probiere es aber sofort wenn ich zuhause bin.

Meld mich dann mit dem Resultat! :)
 
So, entschuldigt, ist ein Tag später geworden :D

Also ich habe alle eure Lösungswege versucht, modifiziert und bin jeglichen Möglichkeiten wie es "enden" könnte gefolgt.

Ich sage mal so, das Problem ist gelöst, jedoch nicht zu 100%.

Nun mein Resultat...

Als erstes habe ich den Weg berücksichtigt, die .htaccess File nicht mehr zu Ändern um das Sicherheitsrisiko auszuschließen. Also suchte ich nach einer variablen Regex die angwendet werden kann, wenn fest geschriebene nicht zutreffen.

Erster Schritt:
Die cid.php umgeschrieben die nun später eine Variable $_GET['_CONT'] empfangen wird. Mit dieser Variable wird nun in der DB geschaut ob diese von dem User angelegt wurde. Das Script kann dann wie vorher mit den Daten weiter arbeiten oder wenn die VAR nicht gefunden wurde einfach eine 404 ausschmeißt.

Soweit so gut...

Schritt zwei:

Warum ich die Lösung
PHP:
<?php 
$get = explode('/', $_GET['vars']);

// Hier ist jetzt der Verweis auf die Seite drin
$page = $get[0];
unset($get[0]);

foreach($get as $var) { 
  if(isset($key)) { 
    $vars[$key] = $var; 
    unset($key); 
  } 
  else { 
    $key = $var; 
  } 
} 

// Hier sind jetzt deine Variablen gespeichert 
$vars; 
?>

nicht anwenden kann, ist folgende:

Der User kann ja auch z.B. als URL:

about/foo/bar oder
about/foo/bar/heute/gestern/mittwoch angeben unter der sein angelegter Inhalt erreichbar sein soll...

Ich könnte somit nicht mehr unterscheiden was Scriptverweis und was Variable ist. Denn er würde ja in der DB nur nach "about" ($get[0]) suchen.

Schritt drei: ^^


Zitat von Gumbo:
PHP:
RewriteRule ^([^/]+)/([^/]+)/([^/]+)(.*) /$1$4?$2=$3 [QSA,N]
RewriteRule ^([^/]+)/([^/]*)$ /$1?$2 [QSA]

RewriteRule ^about$ cid.php?id=2 [QSA,L]

Hat leider nicht funktioniert. Den Basepfad /about kann ich aufrufen, jedoch beliebig viele Variablen im gleichen Format anhängen war nicht möglich.

Was ich jetzt habe...

PHP:
ErrorDocument 404 /404.php
Options +FollowSymLinks
RewriteEngine on
## SYS Rewrite ##
RewriteRule tags/(.*)$ tags.php?query=$1 [L]
...
...
...
RewriteRule search$ search.php [L]

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)([/?])*$ cid.php?_CNT=$1 [QSA,L]

Das ermöglicht mir, das ich die .htaccess nicht mehr ändern muss.
Jedoch ist die Form nicht schön...

ich kann jetzt quasi die Seite

/about oder

/about/foo (So wie es in der DB abgelegt ist)

aufrufen und kann mir auch beliebig viele Variablen für das Dokument mit übergeben... z.B.:

/about/?foo=bar&page=2 oder
/about/foo/?lorem=ipsum&dollor=sit&page=1&foo=bar

also völlig egal wieviele Variablen man mit übergibt.

Soviel zu: Das Problem ist, aber nicht zu 100% gelöst...

Jetzt wäre natürlich noch toll, wenn mein Vorhaben vollendet werden könnte...

Gleiche Prinzip nur das ich statt:

?lorem=ipsum&dollor=sit&page=1&foo=bar

einfach mit:

lorem/ipsum/dollor/sit/page/1/foo/bar

weitermachen kann, aber immernoch zwischen dem aufgerufenen Namen und den dynamischen Variablen unterscheiden kann. Über eine Trennung nach Slashes ist es somit meiner Meinung nach irgendwie nicht möglich das der Eigenname des Scriptes ja schon Slashes enthalten kann...

Aber wie dann? :(

Hi!

[EDIT]
Es ist dennoch möglich mit ModRewrite, allderings nicht mit einer einzigen Regel.
Das wird ein ganz netter Satz - sowas macht keinen Spaß.
Das willst Du bestimmt nicht. Oder doch? :)

Gruß
Enum

Doch ich möchte :)


Beste Grüße
Dave
 
Zuletzt bearbeitet:

Na dann sollst Du Deinen Willen bekommen... :p
Code:
RewriteEngine On
# Dateiendungen liefern wir zwar aus, nehmen sie aber nicht zurück:
RewriteRule ^(.+)(\.html?\b)(.*)$ $1$3
# Rekursion, mit Vorsicht zu genießen:
RewriteRule ^/([^/]+)/([^/]+)/?(.*)? /$3?$1=$2 [QSA,N,NE]
# Im Fall einer geraden Anzahl parameter:
RewriteRule ^/$ /index.php [L]
# Wenn irgendein PHP-Skript direkt angesteuert wird:
RewriteRule ^/.*\.php$ $0 [L]
# Falls wir eine ungerade Zahl von Verzeichnissen bekommen haben:
RewriteRule ^/([^/]+)/?$ /index.php?__not_parsed=$1 [QSA,L]
# Falls etwas nicht berücksichtigt wurde:
RewriteRule ^.*$ /index.php?__not_considered=$0 [QSA,L]
Anstelle umständlicher Erklärungsversuche hier einfach mal ein Link zum Testen.

Den Kram zu optimieren überlasse ich gern den Profis - Gumbo z.B. hätte bestimmt noch so einiges zu verbessern -
ich wollte nur beweisen dass es möglich ist.

Gruß
Enum
 
Zuletzt bearbeitet:
Zurück