Skip to content
Advertisement

how to extract values from url and match them using preg_match

$pathInfo = 'store/view/14342/galaxy-s10-lite-sm-g770-8gb';

I have a route array as –

$route = [
   'store/{id}/{pid}' => ['home/store', ['id', 'exuo', 'pid']], 
   'store/{id}' => ['home/store', ['id']],
   'store/view/{id}/{name}' => ['home/store', ['id','name']], // pathInfo should match this route 
]; 

How do I match the the $pathInfo with its corresponding route.

this is how i tried to do it –

    public function process_route() {
        if (is_array($this->routes()) && count($this->routes()) > 0) {
            //print_r([$this->rawPathInfo, $this->request, $this->route]) . "<br>";
            foreach ($this->routes() as $pattern => $rules) {
                $match = str_replace('/', '/', $pattern);

                if (preg_match("/$match/", $this->pathInfo)) {
                    if (count(explode('/', $this->pathInfo)) == count(explode('/', $pattern))) {
                        $this->set_params($rules);

                        return $rules[0];
                    }
                }
            }
        }

        return FALSE;
    }

    protected function set_params($rules) {
        if (count($rules) >= 2) {
            if (is_array($rules[1]) && count($rules) >= 2) {
                $pathInfoArray = explode("/", $this->pathInfo);
                foreach ($rules[1] as $key) {
                    $index1 = array_search($key, $pathInfoArray);
                    $value = (isset($pathInfoArray[$index1 + 1])) ? $pathInfoArray[$index1 + 1] : self::$NOT_FOUND;
                    if ($value !== self::$NOT_FOUND)
                        $_GET[$key] = $value;
                }
            }
        }
    }

the only diff is here I defined the routes as

 $routes =[
   'store/id/.*/exuo/.*/pid/.*' => ['home/store', ['id', 'exuo', 'pid']], 
];

and was matching the values with the (.*) fields.

Advertisement

Answer

You could transform your route paths into appropriate regular expressions, check $pathInfo against each of them, then return the first one which matches (if any):

/**
 * @param string[] $routes
 */
function findRoute(array $routes, string $pathInfo): ?string
{
  foreach (array_keys($routes) as $routePath) {
    $pattern = '~^' . preg_replace('/{.*?}/', '[^/]+', $routePath) . '$~';
    if (preg_match($pattern, $pathInfo)) {
      return $routePath;
    }
  }
  return null;
}

Usage:

findRoute($routes, $pathInfo);

Demo: https://3v4l.org/DoimK

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement