如何从 url 中提取值并使用 preg_match 匹配它们

how to extract values from url and match them using preg_match

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

我有一个路由数组 -

$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 
]; 

如何将 $pathInfo 与其对应的路由相匹配。

这就是我尝试的方式 -

    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;
                }
            }
        }
    }

唯一的区别在这里我将路由定义为

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

并将值与 (.*) 字段匹配。

您可以将您的路由路径转换为适当的正则表达式,检查 $pathInfo 每个,然后 return 第一个匹配的(如果有的话):

/**
 * @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;
}

用法:

findRoute($routes, $pathInfo);

演示:https://3v4l.org/DoimK