Hi Folks,
ich suche eine möglichst ressourcenschonende Möglichkeit, folgende Aufgabe zu lösen:
In einem PHP-Script möchte ich für die Inhalte eines Verzeichnisbaumes Rechte hinterlegen, ob die einzelnen Dateien dem User angezeigt werden dürfen oder nicht.
Dabei soll die Rechtevergabe natürlich nicht für jede einzelnen Datei erfolgen müssen, sondern es sollen auch Muster möglich sein - nur recht simple, also bspw. * und ?, wie man sie als Wildcards überlicher Dateisystemimplementierungen kennt.
Also soll mit "*.htm" ein Recht für alle Dateien mit der Endung .htm gesetzt werden können, analog soll "hallo*" alle Dateien erwischen, deren Name mit "hallo" beginnt. Und für die Ordner sollen die Wildcards ebenfalls gelten, also "/ordner1/ordner?/xyz.*" soll innerhalb von "ordner1" und darunter in allen Ordnern, deren Name aus "ordner" plus einem beliebigen Zeichen bestehen, alle Dateien mit dem Namen "xyz" und beliebiger Endung matchen - Prinzip sollte klar sein.
Zum Überprüfen, ob ein Pfad-Dateiname-String auf ein Muster passt, käme ggf. fnmatch() in Frage, bzw. das simple Umschreiben solcher Muster in reguläre Ausdrücke.
Jetzt stehe ich aber vor der Frage, wie ich bei so einem System konkurrierende Regeln vernünftig priorisiert bekomme.
Eine "voll qualifizierte" Regel, bspw. für "/ordner1/ordnerA/Datei.xyz", soll natürlich "stärker" sein, als eine dazu konkurrierende "/ordner1/ordner?/*.xyz", die ggf. zum Erlauben/Verbieten eine andere Aussage macht.
Aber was ist, wenn ich jetzt Testen möchte, ob "ordner1/ordnerA/blah.txt" angezeigt werden darf - und zwei Regeln
"/ordner1/ordner?/blah.txt" - erlaubt
"/ordner1/o?dnerA/blah.txt" - verboten
existieren, die beide zutreffen, aber zu unterschiedlichen Aussagen kommen?
Die Regeln müssten also irgendwie sortiert werden - nur nach welchem Kriterium?
Zuerst sollten natürlich die erwähnten voll qualifizierten Regeln drankommen, und danach die "weicheren", die Wildcards enthalten. Sobald ich dann eine passende Regel gefunden habe, soll die Suche abgebrochen werden.
Ich bin mir noch nicht sicher, wie ich die Regeln ablegen soll - ein Array, bestehend aus Strings, die jeweils eine Regel enthalten?
Oder vielleicht doch lieber ein mehrdimensionales Array, in dem ich dann für jeden "Ordner"-Bestandteil einer Regel eine Ebene nutze?
Also so in der Art:
Array
(
['ordner1'] => Array
(
['ordner?'] => Array
(
['voller.name'] => 1
['xyz.*'] => 1
['*.php'] => 0
)
)
)
Da würde ich dann, wenn ich "/ordner1/ordnerA/blah.php" untersuchen möchte, dieses am Verzeichnistrennzeichen / aufsplitten, und dann zunächst schauen, ob das Array auf erster Ebene einen/mehrere passende Einträge für ""ordner1" enthält. Anschließend würde unterhalb dieser Zweige weiter gesucht, was auf "ordnerA" passt, etc.
Problem dabei: Wie lege ich darin sinnvoll eine Regel für Dateien namens "*.txt" ab, die für _alle_ Verzeichnistiefen gültigkeit haben soll?
Array
(
['*'] => Array
(
['*.txt'] => 1
)
)
Und wie würde ich so etwas sinnvoll parsen, wenn nicht nur "/ordner1/xyz.txt", sondern auch "/ordner1/ordnerA/blah.txt" von dieser Regel erfasst werden soll? Am '*' eine Schleife drehen, und auf dieser Arrayebene für das nächste Unterverzeichnis erneut prüfen?
Dann müsste ich bei einer Regel
Array
(
['ordner*'] => Array
(
['*.txt'] => 1
)
)
aber eigentlich auch hier eine Schleife einlegen, weil die auf "/ordner1/blah.txt" genauso passen könnte wie auf "/ordner1/ordnerA/blubb.txt".
Hm, nein, ich glaube da verrenne ich mich mit dieser Array-Ebenen-Geschichte in unpraktikable Gefilde - oder ...?
Da wäre ein eindimensionales Array, in dem ich Regelmuster á la
"/ordner1/*/*.txt"
"*.txt"
"*A/*.txt"
ablege, vermutlich doch geeigneter.
Aber die Priorisierungsfrage bleibt bestehen.
Ich könnte zunächst mal Regeln, die nur aus nicht-Wildcardzeichen bestehen, nach oben sortieren.
Regeln mit Wildcards werden dann danach priorisiert, an welcher Stelle das Wildcardzeichen auftaucht ...
Aber auch das erscheint mir noch zu unspezifisch, um eine Sortierung des Regelwerks hinzubekommen, die möglichst eindeutig ausfällt, und wenig bis keine Zweifelsfälle hinterlässt.
Klar, wenn ich mir vorher die Reihenfolge der Regeln überlegen würde, wäre das ganze Problem kaum existent.
Aber die Regeln sollen nachher durch einen Benutzer administriert werden - d.h., ich würde nur Regelmuster als Texteingabe bekommen, und möchte diese in mein Regelwerk einbauen.
Oder kann ich es dem Admin-Nutzer zumuten, eine Priorisierung seiner Regeln selber vorzunehmen? Bspw. Regeleingabe über eine Textarea, eine Regel pro Zeile, weiter oben = höhere Priorität. Wer zuerst kommt, mahlt zuerst ...
Wer sich über soetwas auch schon mal den Kopf zerbrochen hat, möge sich ermutigt fühlen, mich mit seinen Gedankengängen zu diesem Thema zu erheitern.
Gruß,
wahsaga
--
/voodoo.css:
#GeorgeWBush { position:absolute; bottom:-6ft; }