在PHP中路由干净的URL

时间:2013-11-01 04:20:25

标签: php regex url-routing

我想知道是否有人可以使用我的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();
    }

}

1 个答案:

答案 0 :(得分: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();
 }

}