shawon191 shawon191 - 5 months ago 7
PHP Question

match items inside curly braces and map them to a given string

I am trying to make a routing system in php which uses regex. What I need is to match the route specified in route collection and check if the url matches with it, and if it does, return the parameters in the route by matching with the url.

For example

$route="user/{username}/id/{id}/age/{age}/profile";
$url="user/joe/id/99/age/33/profile";


First thing is to check if the $url matches the $route pattern, return false if it doesn't.

Then I need to return an array containing

[
'username'=>'joe',
'id'=>'99',
'age'=>'33',
]


I'm not good at this at all, I had a clumsy go at it.

Here's my current code

<?php

$r="user/username/{name}/id/{id}/age/{age}/profile";

$u="user/username/joe/id/99/age/33/profile";

route::match($r, $u);
class route{



public static function match($route, $url)
{
if(strpos($route, '{')===FALSE)
{
if(strcmp($route, $url)==0)
{
return TRUE;
}
return FALSE;
}
$vars=[];
$umatches=[];

preg_match_all('/\{(.*?)\}/', $route, $matches);

preg_match('/(.*?)\{/', $route, $amatches);

preg_match_all('/\}(.*?)\{/', $route, $bmatches);

$a=preg_split(end($bmatches[1]), $route);

$b=preg_split('/\}(.*?)/', $a[1]);

array_push($umatches, $amatches[1]);

foreach ($bmatches[1] as $key => $value)
{
array_push($umatches, $value);
}

array_push($umatches, $b[1]);

$pattern="/".str_replace('/', '\/', $amatches[1])."/";

$split=preg_split($pattern, $url);

$i=0;

foreach ($umatches as $key => $value) {
$value=str_replace('/', '\/', $value);
$value='/'.$value.'/';
$r=preg_split($value, $url);
$url=$r[1];
if($i>0)array_push($vars, $r[0]);
$i++;
}
print_r($vars);

if(sizeof($matches[1])!=sizeof($vars)) return FALSE;

$params=[];

for ($i=0; $i < sizeof($matches[1]); $i++) {
$params[$matches[1][$i]]=$vars[$i];
}

print_r($params);
return $params;
}
}


Here I ran the code http://ideone.com/blljFM

sln sln
Answer

Not a php guru here. So below is just a quick 2-step solution using
pseudo-code.

global $TemplateArray;
global $UrlArray;

function GetRoutParams ( $strUrlTemplate, $strUrl )
{
    $TemplateArray = [];
    $UrlArray = [];

    // Step 1. Create the regex from the template

    $strUrlRegex = preg_replace_callback('~\{([^{}]+)\}~',
                 function( $matches ){
                      $repl = '([^/]+)';
                      // push $matches[1] into a $TemplateArray
                      return $repl;
                 },
                 $strUrlTemplate);

    // Step 2. Create the hash from the regex

    if ( preg_match($strUrlRegex, $strUrl, $matches) )
    {
         // Peel off the matches
         // (Or, make a hash)
         for ( int $i = 0; $i < $matches.count; $i++ )
         {
             push $UrlArray, $TemplateArray[$i];
             push $UrlArray, $matches[$i];
         }
         // (Or, make a hash)
         // $UrlHash[ $TemplateArray[$i] ] =  $matches[$i];
    }
    else
    {
         return false;
    }
    return true;
}