PHP URL Routing funktioniert nur teilweise (möglicherweise kompliziert)

Anh Nhan

Grünschnabel
Hallo allerseits,
meine URL-Routing-Methode für mein MVC Software (angelehnt an das Symfony Framework falls es jemand kennt) hier soll zwei Parameter erhalten, eine URL sowie ein Muster (Pattern, von $route->url), auf das es getestet werden soll. Zusätzlich, falls der Test überhaupt so weit kommt, soll noch diverse angegebene Parameter (das Array $route->params->params... SimpleXML, wisst ihr?) angehängt werden und evt. überschreiben. Falls der Test erfolgreich war, gibt es ein Array mit allen herausgefischten Variablen (die Kennzeichen im Muster dafür sind zum Beispiel :module oder :action) zurückgeben.
Muster sind zum Beispiel /:module oder /:module/:action, die URLs sollen wie /update oder /update/action ausschauen

Funktioniert mit einigen URLs und Testmuster auch ganz prima, z.B. URL /update auf das Muster /:module, doch sobald ich eine URL nehme wie /update/show, die auf das Muster /:module/:action zutreffen soll, funktioniert es überhaupt nicht mehr, für die Variable :action kommt 'sho' raus, obwohl 'show' rauskommen sollte. Bei der URL /update/show/2 sowie dem Muster /:module/:action/:id ist es ähnlich... Ok, es zeigt irgendwie ein komisches Verhalten... Wenn ich die URL /update/show/hey auf das Muster /:module/:action/:id teste, kommt auch mal :id ganz raus, aber :action bleibt trotzdem zu kurz....
Ich vermute, dass da etwas mit den Offsets von den ganzen strpos() und substr() funktionen zu tun hat, aber welches genau, weiß ich nicht, weswegen ich hier frage.
Ich hoffe, ihr könnt den Code überblicken...
PHP:
	function checkURL($url, $route) {
		$pattern = ((string)$route->url == '/') ? '/' : (string)$route->url.'/';
		$url = (preg_match('/\/$/i', $url)) ? $url : $url.'/';

		$curpos_pattern = 0;
		$curpos_url = 0;

		$endpos_pattern = strlen($pattern);
		$endpos_url = strlen($url);
		$ret = array();

		// Is the pattern using variables?
		// If yes, parse it, else just check if the URL and the pattern are the same
		if(strpos($pattern, ':', $curpos_pattern) !== false) {
			while($curpos_url<=$endpos_url) {
				// If there're still variables to be checked, do that
				if($curpos_pattern < strlen($pattern) && strpos($pattern, ':', $curpos_pattern) !== false) {
					$n_pattern = strpos($pattern, ':', $curpos_pattern);
					$n_url = ($curpos_url>0) ? $curpos_url : strpos($pattern, '/', $curpos_pattern)+1;

					$t1 = substr($pattern, $curpos_pattern, $n_pattern - $curpos_pattern);
					$t2 = substr($url, $curpos_url, $n_url - $curpos_url);
					if($t1 != $t2) {
						return false;
					}

					$n2_url = strpos($url, '/', $n_url);
					$n2_pattern = strpos($pattern, '/', $n_pattern);

					$var_name = substr($pattern, $n_pattern+1, $n2_pattern - $n_pattern - 1);
					$var_value = substr($url, $n_url, $n2_url - $n_pattern);
						
					$curpos_url = $n2_url + 1;
					$curpos_pattern = $n2_pattern + 1;

					$ret[$var_name] = $var_value;
				} else {
					// If no more variables, just check if the rest's right
					if(substr($url, $curpos_url, $endpos_url) != substr($pattern, $curpos_pattern, $endpos_pattern)) {
						return false;
					} else {
						break;
					}
				}
			}
		} else {
			// No variables, so just check for that
			if($url != $pattern) {
				return false;
			}
		}

		// Now check for some given params in the routes scheme file
		if($route->params) {
			foreach($route->params as $par_name => $par_value) {
				foreach($par_value as $param_name => $param_value) {
					$ret[$param_name] = $param_value;
				}
			}
		}

		return $ret;
	}
 
Zuletzt bearbeitet:
Kurze Frage: Warum machst du es so kompliziert, wenn ein explode() auch funktioniert und es damit sehr wahrscheinlich leichter zu implementieren ist?
 
Zurück