我正在为我的一个项目开发路由器,我需要执行以下操作:
例如,假设我们有这个设置路径数组:
$routes = [
'blog/posts' => 'Path/To/Module/Blog@posts',
'blog/view/{params} => 'Path/To/Module/Blog@view',
'api/blog/create/{params}' => 'Path/To/Module/API/Blog@create'
];
然后,如果我们通过此网址传递:http://localhost/blog/posts
,它会调度blog/posts
路线 - 这很好。
现在,当涉及到需要参数的路由时,我所需要的只是一种实现传递参数的能力的方法(即http://localhost/blog/posts/param1/param2/param3
以及能够在创建前添加api
的能力http://localhost/api/blog/create/
以API调用为目标,但我很难过。
提前谢谢。
答案 0 :(得分:7)
这是基本的东西,当前路由可以有一个模式,如果应用程序路径以该模式开始,那么它就是匹配。其余的路径变成了参数。
<?php
class Route
{
public $name;
public $pattern;
public $class;
public $method;
public $params;
}
class Router
{
public $routes;
public function __construct(array $routes)
{
$this->routes = $routes;
}
public function resolve($app_path)
{
$matched = false;
foreach($this->routes as $route) {
if(strpos($app_path, $route->pattern) === 0) {
$matched = true;
break;
}
}
if(! $matched) throw new Exception('Could not match route.');
$param_str = str_replace($route->pattern, '', $app_path);
$params = explode('/', trim($param_str, '/'));
$params = array_filter($params);
$match = clone($route);
$match->params = $params;
return $match;
}
}
class Controller
{
public function action()
{
var_dump(func_get_args());
}
}
$route = new Route;
$route->name = 'blog-posts';
$route->pattern = '/blog/posts/';
$route->class = 'Controller';
$route->method = 'action';
$router = new Router(array($route));
$match = $router->resolve('/blog/posts/foo/bar');
// Dispatch
if($match) {
call_user_func_array(array(new $match->class, $match->method), $match->params);
}
输出:
array (size=2)
0 => string 'foo' (length=3)
1 => string 'bar' (length=3)
答案 1 :(得分:0)
好的,所以我看了你的建议,我已经解决了这个问题:
这是一个基本版本 - 只是一个显示功能的概念版本,我不建议在生产环境中使用它。
$routes = [
'blog/view' => 'Example@index',
'api/forum/create' => 'other.php'
];
$url = explode('/', $_GET['url']);
if (isset($url[0]))
{
if ($url[0] == 'api')
{
$params = array_slice($url, 3);
$url = array_slice($url, 0, 3);
}
else
{
$params = array_slice($url, 2);
$url = array_slice($url, 0, 2);
}
}
$url = implode('/', $url);
if (array_key_exists($url, $routes))
{
$path = explode('/', $routes[$url]);
unset($path[count($path)]);
$segments = end($path);
$segments = explode('@', $segments);
$controller = $segments[0];
$method = $segments[1];
require_once APP_ROOT . '/app/' . $controller . '.php';
$controller = new $controller;
call_user_func_array([$controller, $method], $params);
}
有魅力。我将立即将其实施到我的申请中。
谢谢大家的帮助:)