0

我想知道是否有人可以使用我的 php 脚本给我,我正在尝试制作像这样的干净 URL,而不使用任何正则表达式。

Controller/Method/arg1/arg2/arg3

到目前为止,我让它工作得很好,但我无法让它与 URL 中的参数一起工作。如果有人可以让这个脚本与 URL 中的参数一起工作,那将对我有很大帮助。我当前的路由器只能映射控制器和方法,并且 args 必须在 ? 但我想让它在 / 之后像我发布的干净 URL 示例一样工作。谢谢你。

$router = new Router();
$router->add('/', 'HomeController::IndexAction');
$router->add('/edit', 'HomeController::EditAction');

$response = $router->dispatch(new Request);

print_r($response);

class Router
{
    private $routes = array();

    public function add($path, $controller)
    {
        $this->routes[$path] = $controller;
    }

    public function match($uri)
    {   
        if(array_key_exists($uri, $this->routes)) {
            return $this->routes[$uri];
        }
    }

    public function dispatch(Request $request)
    {
        $route = $this->match($request->getUri());
        if($route) {
            list($controllerName, $method) = explode('::', $route, 2);
            $controller = new $controllerName;

            if(method_exists($controller,$method)) {      
                return $controller->{$method}($request);
            }
        }
        return "Error route not found!";
    }

}

class Request
{
    private $uri;
    private $args = array();

    public function __construct() 
    {
        $scriptName = $_SERVER['SCRIPT_NAME'];
        $uri = $_SERVER['REQUEST_URI'];
        $args = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
        if (strpos($uri, $scriptName) !== false) {
            $path = $scriptName;
        }
        else {
            $path = str_replace('\\', '', dirname($scriptName));
        }
        $uri = substr_replace($uri, '', 0, strlen($path));
        $uri = str_replace('?' . $args, '', $uri);
        $uri = '/' . ltrim($uri, '/');

        $this->uri = $uri;
        $this->args = $args;
    }

    public function getUri()
    {
        return $this->uri;
    }

    public function getArgs()
    {
        return $this->args;
    }
}

class HomeController
{
    public function IndexAction(Request $request)
    {
        return "home controller";
    }

    public function EditAction(Request $request)
    {
        return $request->getArgs();
    }

}
4

1 回答 1

0

受 Kohana 的启发<...>,这里是关于如何做你想做的事情的基本示例。

您可能需要修改 add() 方法以允许参数(例如控制器应该只匹配字母,arg1 只匹配数字等)。

另外,找到路由后,必须检查控制器和方法是否存在

<?php
$router = new Router();
$router->add('/<controller>/<method>/<arg1>/<arg2>/<arg3>', 'HomeController::IndexAction');
$router->add('/edit', 'HomeController::EditAction');

$response = $router->dispatch(new Request);

print_r($response);

class Router
{
 private $routes = array();
 private $rex_routes = array();

 private $current_route = null;

 public function param($name)
 {
   if (isset($this->current_route[$name]))
    $this->current_route[$name];
 }

 public function add($path, $controller)
 {
  $this->routes[$path] = $controller;
  if (preg_match_all('#<(.*)>#U', $path, $matches))
  {
   $params = $matches[1];
   $rex_route = preg_replace('#<(.*)>#U', '(.*)', $path);
   $this->rex_routes['#'.$rex_route.'#'] = $params;
  }
  $this->routes[$path] = $controller;
 }

 public function match($uri)
 {
  if(array_key_exists($uri, $this->routes)) {
   return $this->routes[$uri];
  }
  else
   foreach($this->rex_routes as $route => $params)
   {
    if (preg_match($route, $uri, $matches))
    {
     array_shift($matches);
     $this->current_route = array_combine($params, $matches);
     return true;
    }
   }
   throw new Exception "$uri does not match<br/>";
 }

 public function dispatch(Request $request)
 {
  $route = $this->match($request->getUri());
  if($route) {
   list($controllerName, $method) = explode('::', $route, 2);
   $controller = new $controllerName;

   if(method_exists($controller,$method)) {      
    return $controller->{$method}($request);
   }
  }
  return "Error route not found!";
 }

}

class Request
{
 private $uri;
 private $args = array();

 public function __construct() 
 {
  $scriptName = $_SERVER['SCRIPT_NAME'];
  $uri = $_SERVER['REQUEST_URI'];
  $args = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
  if (strpos($uri, $scriptName) !== false) {
   $path = $scriptName;
  }
  else {
   $path = str_replace('\\', '', dirname($scriptName));
  }
  $uri = substr_replace($uri, '', 0, strlen($path));
  $uri = str_replace('?' . $args, '', $uri);
  $uri = '/' . ltrim($uri, '/');

  $this->uri = $uri;
  $this->args = $args;
 }

 public function getUri()
 {
  return $this->uri;
 }

 public function getArgs()
 {
  return $this->args;
 }
}

class HomeController
{
 public function IndexAction(Request $request)
 {
  return "home controller";
 }

 public function EditAction(Request $request)
 {
  return $request->getArgs();
 }

}
于 2013-11-01T11:26:05.637 回答