如何从 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);
$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);