Dies realisiere ich mit festen ebenen. Wird dies auf 2 gestellt (meiner Meinung nach ein Standard), werden die ersten Ordner aus der Angabe als fixe Schlüssel verwendet. Alle weiteren sind Variablen, die per Get()-Map angesprochen werden sollen. Ich wollte mal fragen, ob da jemand noch Ideen zur Optimierung hat. An der Performance soll es nicht hapern. Wenn ich ElapsedMilliseconds glauben darf, läuft der folgende Code unter einer Millisekunde durch. Es geht eher um die Lösung selbst. Da würde ich weitere Denkanstöße begrüßen.
PS: Das ist der Probecode. Ich habe es etwas kommentiert. Es sieht aber so wirr aus, da dieser Code eher in Richting Machbarkeitsstudie geht. Der Code, der im Framework landet ist definitiv sauberer
Code: Alles auswählen
TimeA.i = ElapsedMilliseconds()
; Simuliert FastCGI URL und die eingerichtete Route
Route.s = "news/view/year/name.html"
GivenUrl.s = "news/view/2016/team_hat_verloren.html"
; Platzhalter-Prozeduradresse
GivenProcedurePointer.i = 1234567890
; Mögliche Einstellungen
Layers.i = 2 + 1
Handle.s = "html"
; Struktur für die Routen
Structure ParsedRoutes
Variables.s
Proc.i
EndStructure
Define.s Key,Vars,Sub,GetKey
; Route-Map
NewMap Routes.ParsedRoutes()
; ===== Beim entwickeln der Webanwendung =====
; Parsen der einzustellenden Route
CountParams.i = CountString(Route,"/") + 1
For C = 1 To CountParams
Sub = StringField(Route,C,"/")
If C < Layers
Key + Sub
Else
Key + "__" + C + "__"
If C < CountParams
Vars + Sub + "|"
Else
Vars + RemoveString(Sub,"."+Handle)
EndIf
EndIf
If C < CountParams
Key + "/"
Else
Key + "." + Handle
EndIf
Next C
; Route festlegen
Routes(Key)\Proc = GivenProcedurePointer
Routes(Key)\Variables = Vars
Key = ""
; ===== Nach Request =====
; Parsen der URL und finden der Route
NewList TempGet.s()
NewMap Get.s()
CountParams.i = CountString(GivenUrl,"/") + 1
For C = 1 To CountParams
Sub = StringField(GivenUrl,C,"/")
If C < Layers
Key + Sub
Else
Key + "__" + C + "__"
If C < CountParams
AddElement(TempGet())
TempGet() = Sub
Else
AddElement(TempGet())
TempGet() = RemoveString(Sub,"."+Handle)
EndIf
EndIf
If C < CountParams
Key + "/"
Else
Key + "." + Handle
EndIf
Next C
If FindMapElement(Routes(),Key)
; Holen der Variablen und erstellen von Get()
Vars = Routes()\Variables
C.i = 1
If ListSize(TempGet()) = (CountString(Vars,"|") + 1)
ForEach TempGet()
Get(StringField(Vars,C,"|")) = TempGet()
C + 1
Next
Else
Debug #False
End
EndIf
Else
Debug #False
End
EndIf
; Demo-Ausgabe
Debug "Eingerichtete Route: " + Route + Chr(10)
Debug "Übergebe URL: " + GivenUrl
Debug "Geparste Route: " + Key + Chr(10)
Debug "Hinterlegte Prozedur: " + Str(Routes()\Proc)
Debug "Hinterlegte Variablen: " + Routes()\Variables + Chr(10)
Debug "Get-Map für Prozedur:"
ForEach Get()
Debug MapKey(Get()) + ": " + Get()
Next
Debug Chr(10) + Str(ElapsedMilliseconds() - TimeA)
Code: Alles auswählen
Eingerichtete Route: news/view/year/name.html
Übergebe URL: news/view/2016/team_hat_verloren.html
Geparste Route: news/view/__3__/__4__.html
Hinterlegte Prozedur: 1234567890
Hinterlegte Variablen: year|name
Get-Map für Prozedur:
year: 2016
name: team_hat_verloren
0
Ansonsten komtm es so rein